Simplify the HttpRoute trait

Previously the HttpRoute has logic to clone the handler parameter,
which is an implementation detail of the API server. So simplify
the HttpRoute interfaces by removing the argument cloning logic.

Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
This commit is contained in:
Liu Jiang
2020-03-23 21:27:04 +08:00
committed by Adrian Catangiu
parent ac3bb940ab
commit 8ca0839b58
2 changed files with 9 additions and 36 deletions

View File

@@ -121,5 +121,5 @@ pub use self::common::{Body, Method, Version};
pub use self::connection::{ConnectionError, HttpConnection};
pub use self::request::{Request, RequestError};
pub use self::response::{Response, StatusCode};
pub use self::router::{EndpointHandler, HttpRoutes, RouteError, TryClone};
pub use self::router::{EndpointHandler, HttpRoutes, RouteError};
pub use self::server::{HttpServer, ServerError, ServerRequest, ServerResponse};

View File

@@ -3,29 +3,20 @@
//
// SPDX-License-Identifier: Apache-2.0
use std::collections::HashMap;
use std::collections::hash_map::HashMap;
use crate::{MediaType, Request, Response, StatusCode, Version};
pub use crate::common::RouteError;
/// Trait to clone the argument for EndpointHandler::handle_request.
pub trait TryClone
where
Self: std::marker::Sized,
{
/// Clone an object from a reference.
fn try_clone(&self) -> Option<Self>;
}
/// An HTTP endpoint handler interface
pub trait EndpointHandler<T>: Sync + Send {
/// Handles an HTTP request.
fn handle_request(&self, req: &Request, arg: T) -> Response;
fn handle_request(&self, req: &Request, arg: &T) -> Response;
}
/// An HTTP routes structure.
pub struct HttpRoutes<T: TryClone> {
pub struct HttpRoutes<T> {
server_id: String,
prefix: String,
media_type: MediaType,
@@ -33,7 +24,7 @@ pub struct HttpRoutes<T: TryClone> {
routes: HashMap<String, Box<dyn EndpointHandler<T> + Sync + Send>>,
}
impl<T: Send + TryClone> HttpRoutes<T> {
impl<T: Send> HttpRoutes<T> {
/// Create a http request router.
pub fn new(server_id: String, prefix: String) -> Self {
HttpRoutes {
@@ -60,13 +51,10 @@ impl<T: Send + TryClone> HttpRoutes<T> {
}
/// Handle an incoming http request and generate corresponding response.
pub fn handle_http_request(&self, request: &Request, argument: &T) -> Response {
pub fn handle_http_request(&self, request: &Request, argument: T) -> Response {
let path = request.uri().get_abs_path().to_string();
let mut response = match self.routes.get(&path) {
Some(route) => match argument.try_clone() {
Some(arg) => route.handle_request(&request, arg),
None => Response::new(Version::Http11, StatusCode::InternalServerError),
},
Some(route) => route.handle_request(&request, &argument),
None => Response::new(Version::Http11, StatusCode::NotFound),
};
@@ -82,19 +70,10 @@ mod tests {
struct HandlerArg(bool);
impl TryClone for HandlerArg {
fn try_clone(&self) -> Option<Self> {
match self.0 {
true => Some(HandlerArg(true)),
false => None,
}
}
}
struct MockHandler {}
impl EndpointHandler<HandlerArg> for MockHandler {
fn handle_request(&self, _req: &Request, _arg: HandlerArg) -> Response {
fn handle_request(&self, _req: &Request, _arg: &HandlerArg) -> Response {
Response::new(Version::Http11, StatusCode::OK)
}
}
@@ -130,13 +109,7 @@ mod tests {
let request =
Request::try_from(b"GET http://localhost/api/v1/func2 HTTP/1.1\r\n\r\n").unwrap();
let arg = HandlerArg(true);
let reply = router.handle_http_request(&request, &arg);
let reply = router.handle_http_request(&request, arg);
assert_eq!(reply.status(), StatusCode::NotFound);
let request =
Request::try_from(b"GET http://localhost/api/v1/func1 HTTP/1.1\r\n\r\n").unwrap();
let arg = HandlerArg(false);
let reply = router.handle_http_request(&request, &arg);
assert_eq!(reply.status(), StatusCode::InternalServerError);
}
}