diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index f68d0503c..84e4eda0b 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -144,6 +144,7 @@ pin_project! { flags: Flags, peer_addr: Option, conn_data: Option>, + config: ServiceConfig, error: Option, #[pin] @@ -252,6 +253,7 @@ where flags, peer_addr, conn_data: conn_data.0.map(Rc::new), + config: config.clone(), error: None, state: State::None, @@ -346,14 +348,17 @@ where message: Response<()>, body: &impl MessageBody, ) -> Result { - let size = body.size(); let this = self.project(); + + let size = body.size(); + this.codec .encode(Message::Item((message, size)), this.write_buf) .map_err(|err| { if let Some(mut payload) = this.payload.take() { payload.set_error(PayloadError::Incomplete(None)); } + DispatchError::Io(err) })?; @@ -373,6 +378,7 @@ where _ => State::SendPayload { body }, }; self.project().state.set(state); + Ok(()) } @@ -773,7 +779,7 @@ where } if updated && this.timer.is_some() { - if let Some(expire) = this.codec.config().keep_alive_deadline() { + if let Some(expire) = this.config.keep_alive_deadline() { *this.ka_deadline = expire; } } @@ -789,7 +795,7 @@ where None => { // conditionally go into shutdown timeout if this.flags.contains(Flags::SHUTDOWN) { - if let Some(deadline) = this.codec.config().client_disconnect_deadline() { + if let Some(deadline) = this.config.client_disconnect_deadline() { // write client disconnect time out and poll again to // go into Some(timer) branch this.timer.set(Some(sleep_until(deadline))); @@ -815,8 +821,7 @@ where this.flags.insert(Flags::SHUTDOWN); // start shutdown timeout - if let Some(deadline) = - this.codec.config().client_disconnect_deadline() + if let Some(deadline) = this.config.client_disconnect_deadline() { timer.as_mut().reset(deadline); let _ = timer.poll(cx); @@ -840,8 +845,7 @@ where this = self.project(); this.flags.insert(Flags::STARTED | Flags::SHUTDOWN); } - } else if let Some(deadline) = this.codec.config().keep_alive_deadline() - { + } else if let Some(deadline) = this.config.keep_alive_deadline() { // still have unfinished task. try to reset and register keep-alive timer.as_mut().reset(deadline); let _ = timer.poll(cx); @@ -1015,11 +1019,13 @@ where }; loop { - // poll_response and populate write buffer. - // drain indicate if write buffer should be emptied before next run. + // poll response to populate write buffer + // drain indicates whether write buffer should be emptied before next run let drain = match inner.as_mut().poll_response(cx)? { PollResponse::DrainWriteBuf => true, + PollResponse::DoNothing => false, + // upgrade request and goes Upgrade variant of DispatcherState. PollResponse::Upgrade(req) => { let upgrade = inner.upgrade(req); diff --git a/actix-http/src/header/map.rs b/actix-http/src/header/map.rs index 33fb262c4..8f6d1cead 100644 --- a/actix-http/src/header/map.rs +++ b/actix-http/src/header/map.rs @@ -630,7 +630,7 @@ impl Removed { /// Returns true if iterator contains no elements, without consuming it. /// /// If called immediately after [`HeaderMap::insert`] or [`HeaderMap::remove`], it will indicate - /// wether any items were actually replaced or removed, respectively. + /// whether any items were actually replaced or removed, respectively. pub fn is_empty(&self) -> bool { match self.inner { // size hint lower bound of smallvec is the correct length diff --git a/actix-http/src/responses/head.rs b/actix-http/src/responses/head.rs index 870073ab3..f21957349 100644 --- a/actix-http/src/responses/head.rs +++ b/actix-http/src/responses/head.rs @@ -42,7 +42,7 @@ impl ResponseHead { &mut self.headers } - /// Sets the flag that controls wether to send headers formatted as Camel-Case. + /// Sets the flag that controls whether to send headers formatted as Camel-Case. /// /// Only applicable to HTTP/1.x responses; HTTP/2 header names are always lowercase. #[inline] diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index c74978f35..305cb30b5 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -2,7 +2,7 @@ use std::{ convert::Infallible, io::{Read, Write}, net, thread, - time::Duration, + time::{Duration, Instant}, }; use actix_http::{ @@ -201,11 +201,14 @@ async fn test_slow_request() { let mut srv = test_server(|| { HttpService::build() .client_timeout(100) + .keep_alive(2) .finish(|_| ok::<_, Infallible>(Response::ok())) .tcp() }) .await; + let start = Instant::now(); + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n"); let mut data = String::new(); @@ -216,6 +219,17 @@ async fn test_slow_request() { data ); + let end = Instant::now(); + let diff = end - start; + + if diff < Duration::from_secs(1) { + // test success + } else if diff < Duration::from_secs(3) { + panic!("request seems to have wrongly timed-out according to keep-alive"); + } else { + panic!("request took way too long to time out"); + } + srv.stop().await; }