From 0dc96658f24f3e61842e1b5461a8492ef1c90649 Mon Sep 17 00:00:00 2001 From: Douman Date: Fri, 21 Sep 2018 07:24:10 +0300 Subject: [PATCH 1/2] 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; From 1b298142e3b954003b419db015796bbcc702adcd Mon Sep 17 00:00:00 2001 From: Douman Date: Fri, 21 Sep 2018 08:45:22 +0300 Subject: [PATCH 2/2] Correct composing of multiple origins in cors (#518) --- CHANGES.md | 1 + src/middleware/cors.rs | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 36b6dc765..ecdb65ef1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ ### Fixed * HTTP1 decoding errors are reported to the client. #512 +* Correctly compose multiple allowed origins in CORS. #517 ## [0.7.8] - 2018-09-17 diff --git a/src/middleware/cors.rs b/src/middleware/cors.rs index e75dc73ee..f1adf0c4b 100644 --- a/src/middleware/cors.rs +++ b/src/middleware/cors.rs @@ -826,8 +826,8 @@ impl CorsBuilder { if let AllOrSome::Some(ref origins) = cors.origins { let s = origins .iter() - .fold(String::new(), |s, v| s + &v.to_string()); - cors.origins_str = Some(HeaderValue::try_from(s.as_str()).unwrap()); + .fold(String::new(), |s, v| format!("{}, {}", s, v)); + cors.origins_str = Some(HeaderValue::try_from(&s[2..]).unwrap()); } if !self.expose_hdrs.is_empty() { @@ -1122,16 +1122,18 @@ mod tests { let cors = Cors::build() .disable_vary_header() .allowed_origin("https://www.example.com") + .allowed_origin("https://www.google.com") .finish(); let resp: HttpResponse = HttpResponse::Ok().into(); let resp = cors.response(&req, resp).unwrap().response(); - assert_eq!( - &b"https://www.example.com"[..], - resp.headers() - .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) - .unwrap() - .as_bytes() - ); + + let origins_str = resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().to_str().unwrap(); + + if origins_str.starts_with("https://www.example.com") { + assert_eq!("https://www.example.com, https://www.google.com", origins_str); + } else { + assert_eq!("https://www.google.com, https://www.example.com", origins_str); + } } #[test]