From c652625bebabd9e0d0b5b680383c8b7a04e1eacd Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Fri, 1 May 2020 16:11:13 +0100 Subject: [PATCH] vmm: api: Add a default implementation for simple PUT requests Extend the EndpointHandler trait to include automatic support for handling PUT requests. This will allow the removal of lots of duplicated code in the following commit from the API handling code. Signed-off-by: Rob Bradford --- vmm/src/api/http.rs | 41 ++++++++++++++++++++++++++++++++++-- vmm/src/api/http_endpoint.rs | 9 +------- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/vmm/src/api/http.rs b/vmm/src/api/http.rs index c2836d256..1bb005a9c 100644 --- a/vmm/src/api/http.rs +++ b/vmm/src/api/http.rs @@ -10,7 +10,7 @@ use crate::api::http_endpoint::{ use crate::api::{ApiError, ApiRequest, VmAction}; use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::{Error, Result}; -use micro_http::{HttpServer, MediaType, Request, Response, StatusCode, Version}; +use micro_http::{Body, HttpServer, MediaType, Method, Request, Response, StatusCode, Version}; use seccomp::{SeccompFilter, SeccompLevel}; use serde_json::Error as SerdeError; use std::collections::HashMap; @@ -25,6 +25,9 @@ pub enum HttpError { /// API request receive error SerdeJsonDeserialize(SerdeError), + /// Attempt to access unsupported HTTP method + BadRequest, + /// Could not create a VM VmCreate(ApiError), @@ -86,8 +89,21 @@ pub enum HttpError { VmAddVsock(ApiError), } +impl From for HttpError { + fn from(e: serde_json::Error) -> Self { + HttpError::SerdeJsonDeserialize(e) + } +} + const HTTP_ROOT: &str = "/api/v1"; +pub fn error_response(error: HttpError, status: StatusCode) -> Response { + let mut response = Response::new(Version::Http11, status); + response.set_body(Body::new(format!("{:?}", error))); + + response +} + /// An HTTP endpoint handler interface pub trait EndpointHandler: Sync + Send { /// Handles an HTTP request. @@ -100,7 +116,28 @@ pub trait EndpointHandler: Sync + Send { req: &Request, api_notifier: EventFd, api_sender: Sender, - ) -> Response; + ) -> Response { + match req.method() { + Method::Put => match self.put_handler(api_notifier, api_sender, &req.body) { + Ok(_) => Response::new(Version::Http11, StatusCode::NoContent), + Err(e @ HttpError::BadRequest) => error_response(e, StatusCode::BadRequest), + Err(e @ HttpError::SerdeJsonDeserialize(_)) => { + error_response(e, StatusCode::BadRequest) + } + Err(e) => error_response(e, StatusCode::InternalServerError), + }, + _ => Response::new(Version::Http11, StatusCode::BadRequest), + } + } + + fn put_handler( + &self, + _api_notifier: EventFd, + _api_sender: Sender, + _body: &Option, + ) -> std::result::Result<(), HttpError> { + Err(HttpError::BadRequest) + } } /// An HTTP routes structure. diff --git a/vmm/src/api/http_endpoint.rs b/vmm/src/api/http_endpoint.rs index 2fdf7b0d2..687a17605 100644 --- a/vmm/src/api/http_endpoint.rs +++ b/vmm/src/api/http_endpoint.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // -use crate::api::http::{EndpointHandler, HttpError}; +use crate::api::http::{error_response, EndpointHandler, HttpError}; use crate::api::{ vm_add_device, vm_add_disk, vm_add_fs, vm_add_net, vm_add_pmem, vm_add_vsock, vm_boot, vm_create, vm_delete, vm_info, vm_pause, vm_reboot, vm_remove_device, vm_resize, vm_restore, @@ -16,13 +16,6 @@ use std::sync::mpsc::Sender; use std::sync::{Arc, Mutex}; use vmm_sys_util::eventfd::EventFd; -fn error_response(error: HttpError, status: StatusCode) -> Response { - let mut response = Response::new(Version::Http11, status); - response.set_body(Body::new(format!("{:?}", error))); - - response -} - // /api/v1/vm.create handler pub struct VmCreate {}