diff --git a/Cargo.toml b/Cargo.toml index 014f7701b..0133e25b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,6 @@ serde_derive = "1.0" [build-dependencies] skeptic = "0.13" -serde_derive = "1.0" version_check = "0.1" [profile.release] diff --git a/src/context.rs b/src/context.rs index c9f770147..f792370f5 100644 --- a/src/context.rs +++ b/src/context.rs @@ -25,7 +25,7 @@ pub(crate) trait IoContext: 'static { #[derive(Debug)] pub(crate) enum Frame { - Message(HttpResponse), + Message(Box), Payload(Option), Drain(Rc>), } @@ -141,7 +141,7 @@ impl HttpContext where A: Actor { Body::StreamingContext | Body::UpgradeContext => self.streaming = true, _ => (), } - self.stream.push_back(Frame::Message(resp)) + self.stream.push_back(Frame::Message(Box::new(resp))) } /// Write payload diff --git a/src/encoding.rs b/src/encoding.rs index be44990b7..e4af95929 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -125,9 +125,9 @@ impl PayloadWriter for PayloadType { } enum Decoder { - Deflate(DeflateDecoder>), - Gzip(Option>), - Br(BrotliDecoder>), + Deflate(Box>>), + Gzip(Box>>), + Br(Box>>), Identity, } @@ -158,10 +158,10 @@ impl EncodedPayload { pub fn new(inner: PayloadSender, enc: ContentEncoding) -> EncodedPayload { let dec = match enc { ContentEncoding::Br => Decoder::Br( - BrotliDecoder::new(BytesMut::with_capacity(8192).writer())), + Box::new(BrotliDecoder::new(BytesMut::with_capacity(8192).writer()))), ContentEncoding::Deflate => Decoder::Deflate( - DeflateDecoder::new(BytesMut::with_capacity(8192).writer())), - ContentEncoding::Gzip => Decoder::Gzip(None), + Box::new(DeflateDecoder::new(BytesMut::with_capacity(8192).writer()))), + ContentEncoding::Gzip => Decoder::Gzip(Box::new(None)), _ => Decoder::Identity, }; EncodedPayload { @@ -204,13 +204,13 @@ impl PayloadWriter for EncodedPayload { } loop { let len = self.dst.get_ref().len(); - let len_buf = decoder.as_mut().unwrap().get_mut().buf.len(); + let len_buf = decoder.as_mut().as_mut().unwrap().get_mut().buf.len(); if len < len_buf * 2 { self.dst.get_mut().reserve(len_buf * 2 - len); unsafe{self.dst.get_mut().set_len(len_buf * 2)}; } - match decoder.as_mut().unwrap().read(&mut self.dst.get_mut()) { + match decoder.as_mut().as_mut().unwrap().read(&mut self.dst.get_mut()) { Ok(n) => { if n == 0 { self.inner.feed_eof(); @@ -271,13 +271,13 @@ impl PayloadWriter for EncodedPayload { if decoder.is_none() { let mut buf = BytesMut::new(); buf.extend(data); - *decoder = Some(GzDecoder::new(Wrapper{buf: buf}).unwrap()); + *(decoder.as_mut()) = Some(GzDecoder::new(Wrapper{buf: buf}).unwrap()); } else { - decoder.as_mut().unwrap().get_mut().buf.extend(data); + decoder.as_mut().as_mut().unwrap().get_mut().buf.extend(data); } loop { - let len_buf = decoder.as_mut().unwrap().get_mut().buf.len(); + let len_buf = decoder.as_mut().as_mut().unwrap().get_mut().buf.len(); if len_buf == 0 { return } @@ -287,7 +287,7 @@ impl PayloadWriter for EncodedPayload { self.dst.get_mut().reserve(len_buf * 2 - len); unsafe{self.dst.get_mut().set_len(len_buf * 2)}; } - match decoder.as_mut().unwrap().read(&mut self.dst.get_mut()) { + match decoder.as_mut().as_mut().unwrap().read(&mut self.dst.get_mut()) { Ok(n) => { if n == 0 { return diff --git a/src/h1writer.rs b/src/h1writer.rs index 58b6da58c..ec3c6c314 100644 --- a/src/h1writer.rs +++ b/src/h1writer.rs @@ -1,8 +1,7 @@ use std::io; -use std::fmt::Write; use futures::{Async, Poll}; use tokio_io::AsyncWrite; -use http::{Version, StatusCode}; +use http::Version; use http::header::{HeaderValue, CONNECTION, CONTENT_TYPE, DATE}; use date; @@ -151,11 +150,17 @@ impl Writer for H1Writer { buffer.reserve(100 + msg.headers().len() * AVERAGE_HEADER_SIZE); } - if version == Version::HTTP_11 && msg.status() == StatusCode::OK { - buffer.extend(b"HTTP/1.1 200 OK\r\n"); - } else { - let _ = write!(buffer, "{:?} {}\r\n", version, msg.status()); + match version { + Version::HTTP_11 => buffer.extend(b"HTTP/1.1 "), + Version::HTTP_2 => buffer.extend(b"HTTP/2.0 "), + Version::HTTP_10 => buffer.extend(b"HTTP/1.0 "), + Version::HTTP_09 => buffer.extend(b"HTTP/0.9 "), } + buffer.extend(msg.status().as_u16().to_string().as_bytes()); + buffer.extend(b" "); + buffer.extend(msg.reason().as_bytes()); + buffer.extend(b"\r\n"); + for (key, value) in msg.headers() { let t: &[u8] = key.as_ref(); buffer.extend(t); diff --git a/src/handler.rs b/src/handler.rs index 5c9ba94a8..f059e81c0 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -50,7 +50,7 @@ impl Handler for F pub struct Reply(ReplyItem); pub(crate) enum ReplyItem { - Message(HttpResponse), + Message(Box), Actor(Box), Future(Box>), } @@ -76,7 +76,7 @@ impl Reply { /// Send response #[inline] pub fn response>(response: R) -> Reply { - Reply(ReplyItem::Message(response.into())) + Reply(ReplyItem::Message(Box::new(response.into()))) } #[inline] @@ -107,14 +107,14 @@ impl FromRequest for HttpResponse { type Error = Error; fn from_request(self, _: HttpRequest) -> Result { - Ok(Reply(ReplyItem::Message(self))) + Ok(Reply(ReplyItem::Message(Box::new(self)))) } } impl From for Reply { fn from(resp: HttpResponse) -> Reply { - Reply(ReplyItem::Message(resp)) + Reply(ReplyItem::Message(Box::new(resp))) } } @@ -138,7 +138,7 @@ impl> From> for Reply { fn from(res: Result) -> Self { match res { Ok(val) => val, - Err(err) => Reply(ReplyItem::Message(err.into().into())), + Err(err) => Reply(ReplyItem::Message(Box::new(err.into().into()))), } } } diff --git a/src/httpcodes.rs b/src/httpcodes.rs index e2af3ec50..f00a2a5f5 100644 --- a/src/httpcodes.rs +++ b/src/httpcodes.rs @@ -166,7 +166,7 @@ mod tests { #[test] fn test_with_reason() { let resp = HTTPOk.response(); - assert_eq!(resp.reason(), ""); + assert_eq!(resp.reason(), "OK"); let resp = HTTPBadRequest.with_reason("test"); assert_eq!(resp.status(), StatusCode::BAD_REQUEST); diff --git a/src/httpresponse.rs b/src/httpresponse.rs index ba4cb7b23..3ff4089c7 100644 --- a/src/httpresponse.rs +++ b/src/httpresponse.rs @@ -119,7 +119,7 @@ impl HttpResponse { if let Some(reason) = self.reason { reason } else { - "" + self.status.canonical_reason().unwrap_or("") } } diff --git a/src/middlewares/defaultheaders.rs b/src/middlewares/defaultheaders.rs index a0b772e90..3335847e0 100644 --- a/src/middlewares/defaultheaders.rs +++ b/src/middlewares/defaultheaders.rs @@ -37,7 +37,7 @@ impl DefaultHeaders { impl Middleware for DefaultHeaders { - fn response(&self, _: &mut HttpRequest, mut resp: HttpResponse) -> Response { + fn response(&self, _: &mut HttpRequest, mut resp: Box) -> Response { for (key, value) in self.0.iter() { if !resp.headers().contains_key(key) { resp.headers_mut().insert(key, value.clone()); @@ -97,14 +97,14 @@ mod tests { let mut req = HttpRequest::default(); let resp = HttpResponse::Ok().finish().unwrap(); - let resp = match mw.response(&mut req, resp) { + let resp = match mw.response(&mut req, Box::new(resp)) { Response::Done(resp) => resp, _ => panic!(), }; assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); let resp = HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish().unwrap(); - let resp = match mw.response(&mut req, resp) { + let resp = match mw.response(&mut req, Box::new(resp)) { Response::Done(resp) => resp, _ => panic!(), }; diff --git a/src/middlewares/mod.rs b/src/middlewares/mod.rs index b9798c97b..d5d88fc78 100644 --- a/src/middlewares/mod.rs +++ b/src/middlewares/mod.rs @@ -21,7 +21,7 @@ pub enum Started { Err(Error), /// New http response got generated. If middleware generates response /// handler execution halts. - Response(HttpResponse), + Response(Box), /// Execution completed, runs future to completion. Future(Box, Error=Error>>), } @@ -31,7 +31,7 @@ pub enum Response { /// Moddleware error Err(Error), /// New http response got generated - Done(HttpResponse), + Done(Box), /// Result is a future that resolves to a new http response Future(Box>), } @@ -56,7 +56,7 @@ pub trait Middleware { /// Method is called when handler returns response, /// but before sending http message to peer. - fn response(&self, req: &mut HttpRequest, resp: HttpResponse) -> Response { + fn response(&self, req: &mut HttpRequest, resp: Box) -> Response { Response::Done(resp) } diff --git a/src/middlewares/session.rs b/src/middlewares/session.rs index a807b0c03..d38fb0682 100644 --- a/src/middlewares/session.rs +++ b/src/middlewares/session.rs @@ -107,7 +107,7 @@ impl> Middleware for SessionStorage { Started::Future(Box::new(fut)) } - fn response(&self, req: &mut HttpRequest, resp: HttpResponse) -> Response { + fn response(&self, req: &mut HttpRequest, resp: Box) -> Response { if let Some(s_box) = req.extensions().remove::>() { s_box.0.write(resp) } else { @@ -129,7 +129,7 @@ pub trait SessionImpl: 'static { fn clear(&mut self); /// Write session to storage backend. - fn write(&self, resp: HttpResponse) -> Response; + fn write(&self, resp: Box) -> Response; } /// Session's storage backend trait definition. @@ -155,7 +155,7 @@ impl SessionImpl for DummySessionImpl { fn set(&mut self, key: &str, value: String) {} fn remove(&mut self, key: &str) {} fn clear(&mut self) {} - fn write(&self, resp: HttpResponse) -> Response { + fn write(&self, resp: Box) -> Response { Response::Done(resp) } } @@ -205,7 +205,7 @@ impl SessionImpl for CookieSession { self.state.clear() } - fn write(&self, mut resp: HttpResponse) -> Response { + fn write(&self, mut resp: Box) -> Response { if self.changed { let _ = self.inner.set_cookie(&mut resp, &self.state); } diff --git a/src/param.rs b/src/param.rs index 63c37f13b..b948ac187 100644 --- a/src/param.rs +++ b/src/param.rs @@ -20,7 +20,7 @@ pub trait FromParam: Sized { /// /// If resource path contains variable patterns, `Params` stores this variables. #[derive(Debug)] -pub struct Params<'a>(SmallVec<[(&'a str, &'a str); 4]>); +pub struct Params<'a>(SmallVec<[(&'a str, &'a str); 3]>); impl<'a> Default for Params<'a> { fn default() -> Params<'a> { diff --git a/src/pipeline.rs b/src/pipeline.rs index cea38fa9e..9c7aa60d4 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -141,7 +141,8 @@ impl Pipeline { impl Pipeline<()> { pub fn error>(err: R) -> Box { Box::new(Pipeline( - PipelineInfo::new(HttpRequest::default()), ProcessResponse::init(err.into()))) + PipelineInfo::new( + HttpRequest::default()), ProcessResponse::init(Box::new(err.into())))) } } @@ -346,15 +347,15 @@ impl StartMiddlewares { fut: Some(fut)}), Ok(Async::Ready(resp)) => { if let Some(resp) = resp { - return RunMiddlewares::init(info, resp); + return RunMiddlewares::init(info, Box::new(resp)); } info.count += 1; } Err(err) => - return ProcessResponse::init(err.into()), + return ProcessResponse::init(Box::new(err.into())), }, Started::Err(err) => - return ProcessResponse::init(err.into()), + return ProcessResponse::init(Box::new(err.into())), } } } @@ -369,7 +370,7 @@ impl StartMiddlewares { Ok(Async::Ready(resp)) => { info.count += 1; if let Some(resp) = resp { - return Ok(RunMiddlewares::init(info, resp)); + return Ok(RunMiddlewares::init(info, Box::new(resp))); } if info.count == len { let reply = (unsafe{&*self.hnd})(info.req.clone()); @@ -387,13 +388,13 @@ impl StartMiddlewares { continue 'outer }, Started::Err(err) => - return Ok(ProcessResponse::init(err.into())) + return Ok(ProcessResponse::init(Box::new(err.into()))) } } } } Err(err) => - return Ok(ProcessResponse::init(err.into())) + return Ok(ProcessResponse::init(Box::new(err.into()))) } } } @@ -441,14 +442,14 @@ impl WaitingResponse { Ok(Async::Ready(None)) => { error!("Unexpected eof"); let err: Error = UnexpectedTaskFrame.into(); - return Ok(ProcessResponse::init(err.into())) + return Ok(ProcessResponse::init(Box::new(err.into()))) }, Ok(Async::NotReady) => { self.stream = PipelineResponse::Context(context); return Err(PipelineState::Handler(self)) }, Err(err) => - return Ok(ProcessResponse::init(err.into())) + return Ok(ProcessResponse::init(Box::new(err.into()))) } } }, @@ -459,9 +460,9 @@ impl WaitingResponse { Err(PipelineState::Handler(self)) } Ok(Async::Ready(response)) => - Ok(RunMiddlewares::init(info, response)), + Ok(RunMiddlewares::init(info, Box::new(response))), Err(err) => - Ok(ProcessResponse::init(err.into())), + Ok(ProcessResponse::init(Box::new(err.into()))), } } PipelineResponse::None => { @@ -481,7 +482,7 @@ struct RunMiddlewares { impl RunMiddlewares { - fn init(info: &mut PipelineInfo, mut resp: HttpResponse) -> PipelineState + fn init(info: &mut PipelineInfo, mut resp: Box) -> PipelineState { if info.count == 0 { return ProcessResponse::init(resp); @@ -493,7 +494,7 @@ impl RunMiddlewares { resp = match info.mws[curr].response(info.req_mut(), resp) { Response::Err(err) => { info.count = curr + 1; - return ProcessResponse::init(err.into()) + return ProcessResponse::init(Box::new(err.into())) } Response::Done(r) => { curr += 1; @@ -521,10 +522,10 @@ impl RunMiddlewares { return Ok(PipelineState::RunMiddlewares(self)), Ok(Async::Ready(resp)) => { self.curr += 1; - resp + Box::new(resp) } Err(err) => - return Ok(ProcessResponse::init(err.into())), + return Ok(ProcessResponse::init(Box::new(err.into()))), }; loop { @@ -533,7 +534,7 @@ impl RunMiddlewares { } else { match info.mws[self.curr].response(info.req_mut(), resp) { Response::Err(err) => - return Ok(ProcessResponse::init(err.into())), + return Ok(ProcessResponse::init(Box::new(err.into()))), Response::Done(r) => { self.curr += 1; resp = r @@ -550,7 +551,7 @@ impl RunMiddlewares { } struct ProcessResponse { - resp: HttpResponse, + resp: Box, iostate: IOState, running: RunningState, drain: DrainVec, @@ -596,6 +597,7 @@ impl IOState { } struct DrainVec(Vec>>); + impl Drop for DrainVec { fn drop(&mut self) { for drain in &mut self.0 { @@ -606,7 +608,7 @@ impl Drop for DrainVec { impl ProcessResponse { - fn init(resp: HttpResponse) -> PipelineState + fn init(resp: Box) -> PipelineState { PipelineState::Response( ProcessResponse{ resp: resp, @@ -786,14 +788,14 @@ impl ProcessResponse { /// Middlewares start executor struct FinishingMiddlewares { - resp: HttpResponse, + resp: Box, fut: Option>>, _s: PhantomData, } impl FinishingMiddlewares { - fn init(info: &mut PipelineInfo, resp: HttpResponse) -> PipelineState { + fn init(info: &mut PipelineInfo, resp: Box) -> PipelineState { if info.count == 0 { Completed::init(info) } else { diff --git a/src/server.rs b/src/server.rs index 5d03d4f9f..3e81e5422 100644 --- a/src/server.rs +++ b/src/server.rs @@ -267,6 +267,7 @@ impl HttpServer }; let msg = IoStream{ io: socket.into_tcp_stream(), peer: Some(addr), http2: false}; + println!("next: {}", next); wrks[next].unbounded_send(msg).expect("worker thread died"); next = (next + 1) % wrks.len(); } diff --git a/tests/test_server.rs b/tests/test_server.rs index b3b58b3b7..65a0a38e1 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -59,7 +59,7 @@ impl middlewares::Middleware for MiddlewareTest { middlewares::Started::Done } - fn response(&self, _: &mut HttpRequest, resp: HttpResponse) -> middlewares::Response { + fn response(&self, _: &mut HttpRequest, resp: Box) -> middlewares::Response { self.response.store(self.response.load(Ordering::Relaxed) + 1, Ordering::Relaxed); middlewares::Response::Done(resp) } @@ -85,9 +85,9 @@ fn test_middlewares() { HttpServer::new( move || vec![Application::new() - .middleware(MiddlewareTest{start: act_num1.clone(), - response: act_num2.clone(), - finish: act_num3.clone()}) + .middleware(MiddlewareTest{start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3)}) .resource("/", |r| r.method(Method::GET).h(httpcodes::HTTPOk))]) .serve::<_, ()>("127.0.0.1:58904").unwrap(); sys.run();