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 <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-05-01 16:11:13 +01:00
parent a3e8bea03c
commit c652625beb
2 changed files with 40 additions and 10 deletions

View File

@ -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<serde_json::Error> 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<ApiRequest>,
) -> 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<ApiRequest>,
_body: &Option<Body>,
) -> std::result::Result<(), HttpError> {
Err(HttpError::BadRequest)
}
}
/// An HTTP routes structure.

View File

@ -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 {}