From 7fb4f5642a2f06820f79fee3f82d41a087aa1e1d Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 3 Jul 2019 11:54:35 +0200 Subject: [PATCH] src/server/rest.rs: log peer address, use hyper MakeService --- src/server/rest.rs | 52 +++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/server/rest.rs b/src/server/rest.rs index 59237920..273feba3 100644 --- a/src/server/rest.rs +++ b/src/server/rest.rs @@ -23,7 +23,7 @@ use tokio::fs::File; //use hyper::body::Payload; use hyper::http::request::Parts; use hyper::{Body, Request, Response, StatusCode}; -use hyper::service::{Service, NewService}; +use hyper::service::{Service, MakeService}; use hyper::rt::{Future, Stream}; use hyper::header; @@ -40,24 +40,46 @@ impl RestServer { } } -impl NewService for RestServer +impl MakeService<&tokio_openssl::SslStream> for RestServer { type ReqBody = Body; type ResBody = Body; - type Error = hyper::Error; - type InitError = hyper::Error; + type Error = Error; + type MakeError = Error; type Service = ApiService; - type Future = Box + Send>; - fn new_service(&self) -> Self::Future { - Box::new(future::ok(ApiService { api_config: self.api_config.clone() })) + type Future = Box + Send>; + fn make_service(&mut self, ctx: &tokio_openssl::SslStream) -> Self::Future { + let peer = ctx.get_ref().get_ref().peer_addr().unwrap(); + Box::new(future::ok(ApiService { peer, api_config: self.api_config.clone() })) } } +impl MakeService<&tokio::net::TcpStream> for RestServer +{ + type ReqBody = Body; + type ResBody = Body; + type Error = Error; + type MakeError = Error; + type Service = ApiService; + type Future = Box + Send>; + fn make_service(&mut self, ctx: &tokio::net::TcpStream) -> Self::Future { + let peer = ctx.peer_addr().unwrap(); + Box::new(future::ok(ApiService { peer, api_config: self.api_config.clone() })) + } +} + + pub struct ApiService { + pub peer: std::net::SocketAddr, pub api_config: Arc, } -fn log_response(method: hyper::Method, path: &str, resp: &Response) { +fn log_response( + peer: &std::net::SocketAddr, + method: hyper::Method, + path: &str, + resp: &Response, +) { if resp.extensions().get::().is_some() { return; }; @@ -65,43 +87,43 @@ fn log_response(method: hyper::Method, path: &str, resp: &Response) { if !(status.is_success() || status.is_informational()) { let reason = status.canonical_reason().unwrap_or("unknown reason"); - let client = "unknown"; // fixme: howto get peer_addr ? let mut message = "request failed"; if let Some(data) = resp.extensions().get::() { message = &data.0; } - log::error!("{} {}: {} {}: [client {}] {}", method.as_str(), path, status.as_str(), reason, client, message); + log::error!("{} {}: {} {}: [client {}] {}", method.as_str(), path, status.as_str(), reason, peer, message); } } impl Service for ApiService { type ReqBody = Body; type ResBody = Body; - type Error = hyper::Error; + type Error = Error; type Future = Box, Error = Self::Error> + Send>; fn call(&mut self, req: Request) -> Self::Future { let path = req.uri().path().to_owned(); let method = req.method().clone(); + let peer = self.peer.clone(); Box::new(handle_request(self.api_config.clone(), req).then(move |result| { match result { Ok(res) => { - log_response(method, &path, &res); - Ok::<_, hyper::Error>(res) + log_response(&peer, method, &path, &res); + Ok::<_, Self::Error>(res) } Err(err) => { if let Some(apierr) = err.downcast_ref::() { let mut resp = Response::new(Body::from(apierr.message.clone())); *resp.status_mut() = apierr.code; - log_response(method, &path, &resp); + log_response(&peer, method, &path, &resp); Ok(resp) } else { let mut resp = Response::new(Body::from(err.to_string())); *resp.status_mut() = StatusCode::BAD_REQUEST; - log_response(method, &path, &resp); + log_response(&peer, method, &path, &resp); Ok(resp) } }