From 0dc96658f24f3e61842e1b5461a8492ef1c90649 Mon Sep 17 00:00:00 2001 From: Douman Date: Fri, 21 Sep 2018 07:24:10 +0300 Subject: [PATCH] Send response to inform client of error (#515) --- CHANGES.md | 6 ++++++ src/payload.rs | 4 +++- src/server/h1.rs | 24 +++++++++++++++++------- tests/test_server.rs | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3a28a82ea..36b6dc765 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Changes +## [0.7.9] - 2018-09-x + +### Fixed + +* HTTP1 decoding errors are reported to the client. #512 + ## [0.7.8] - 2018-09-17 ### Added diff --git a/src/payload.rs b/src/payload.rs index 1d9281f51..382c0b0f5 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,6 +1,8 @@ //! Payload stream use bytes::{Bytes, BytesMut}; -use futures::task::{current as current_task, Task}; +use futures::task::Task; +#[cfg(not(test))] +use futures::task::current as current_task; use futures::{Async, Poll, Stream}; use std::cell::RefCell; use std::cmp; diff --git a/src/server/h1.rs b/src/server/h1.rs index d6e13e227..b715dfb6a 100644 --- a/src/server/h1.rs +++ b/src/server/h1.rs @@ -373,6 +373,16 @@ where Ok(Async::NotReady) } + fn push_response_entry(&mut self, status: StatusCode) { + self.tasks.push_back(Entry { + pipe: EntryPipe::Error(ServerError::err( + Version::HTTP_11, + status, + )), + flags: EntryFlags::empty(), + }); + } + pub fn parse(&mut self) { 'outer: loop { match self.decoder.decode(&mut self.buf, &self.settings) { @@ -439,13 +449,7 @@ where } // handler is not found - self.tasks.push_back(Entry { - pipe: EntryPipe::Error(ServerError::err( - Version::HTTP_11, - StatusCode::NOT_FOUND, - )), - flags: EntryFlags::empty(), - }); + self.push_response_entry(StatusCode::NOT_FOUND); } Ok(Some(Message::Chunk(chunk))) => { if let Some(ref mut payload) = self.payload { @@ -453,6 +457,7 @@ where } else { error!("Internal server error: unexpected payload chunk"); self.flags.insert(Flags::ERROR); + self.push_response_entry(StatusCode::INTERNAL_SERVER_ERROR); break; } } @@ -462,6 +467,7 @@ where } else { error!("Internal server error: unexpected eof"); self.flags.insert(Flags::ERROR); + self.push_response_entry(StatusCode::INTERNAL_SERVER_ERROR); break; } } @@ -482,6 +488,9 @@ where }; payload.set_error(e); } + + //Malformed requests should be responded with 400 + self.push_response_entry(StatusCode::BAD_REQUEST); break; } } @@ -660,6 +669,7 @@ mod tests { h1.poll_io(); h1.poll_io(); assert!(h1.flags.contains(Flags::ERROR)); + assert_eq!(h1.tasks.len(), 1); } #[test] diff --git a/tests/test_server.rs b/tests/test_server.rs index 97161a30f..52c47dd27 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -11,6 +11,7 @@ extern crate rand; extern crate tokio; extern crate tokio_reactor; extern crate tokio_tcp; +extern crate tokio_current_thread as current_thread; use std::io::{Read, Write}; use std::sync::Arc; @@ -28,7 +29,6 @@ use h2::client as h2client; use modhttp::Request; use rand::distributions::Alphanumeric; use rand::Rng; -use tokio::executor::current_thread; use tokio::runtime::current_thread::Runtime; use tokio_tcp::TcpStream;