1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

Fix compression #103 and #104

This commit is contained in:
Nikolay Kim 2018-03-06 11:02:03 -08:00
parent 9cc6f6b1e4
commit a0e6313d56
6 changed files with 162 additions and 32 deletions

View File

@ -2,6 +2,8 @@
## 0.4.5 (2018-03-xx) ## 0.4.5 (2018-03-xx)
* Fix compression #103 and #104
* Enable compression support for `NamedFile` * Enable compression support for `NamedFile`
* Better support for `NamedFile` type * Better support for `NamedFile` type

View File

@ -78,6 +78,7 @@ impl HttpResponseParser {
-> Poll<Option<Bytes>, PayloadError> -> Poll<Option<Bytes>, PayloadError>
where T: IoStream where T: IoStream
{ {
println!("PARSE payload, {:?}", self.decoder.is_some());
if self.decoder.is_some() { if self.decoder.is_some() {
loop { loop {
// read payload // read payload

View File

@ -154,7 +154,7 @@ pub(crate) const HAS_OPENSSL: bool = false;
// #[cfg(not(feature="tls"))] // #[cfg(not(feature="tls"))]
// pub(crate) const HAS_TLS: bool = false; // pub(crate) const HAS_TLS: bool = false;
#[doc(hidden)]
#[deprecated(since="0.4.4", note="please use `actix::header` module")] #[deprecated(since="0.4.4", note="please use `actix::header` module")]
pub mod headers { pub mod headers {
//! Headers implementation //! Headers implementation

View File

@ -246,18 +246,14 @@ impl PayloadStream {
if let Some(ref mut decoder) = *decoder { if let Some(ref mut decoder) = *decoder {
decoder.as_mut().get_mut().eof = true; decoder.as_mut().get_mut().eof = true;
loop { self.dst.reserve(8192);
self.dst.reserve(8192); match decoder.read(unsafe{self.dst.bytes_mut()}) {
match decoder.read(unsafe{self.dst.bytes_mut()}) { Ok(n) => {
Ok(n) => { unsafe{self.dst.advance_mut(n)};
if n == 0 { return Ok(Some(self.dst.take().freeze()))
return Ok(Some(self.dst.take().freeze()))
} else {
unsafe{self.dst.advance_mut(n)};
}
}
Err(e) => return Err(e),
} }
Err(e) =>
return Err(e),
} }
} else { } else {
Ok(None) Ok(None)
@ -283,8 +279,9 @@ impl PayloadStream {
pub fn feed_data(&mut self, data: Bytes) -> io::Result<Option<Bytes>> { pub fn feed_data(&mut self, data: Bytes) -> io::Result<Option<Bytes>> {
match self.decoder { match self.decoder {
Decoder::Br(ref mut decoder) => { Decoder::Br(ref mut decoder) => {
match decoder.write(&data).and_then(|_| decoder.flush()) { match decoder.write_all(&data) {
Ok(_) => { Ok(_) => {
decoder.flush()?;
let b = decoder.get_mut().take(); let b = decoder.get_mut().take();
if !b.is_empty() { if !b.is_empty() {
Ok(Some(b)) Ok(Some(b))
@ -306,23 +303,31 @@ impl PayloadStream {
loop { loop {
self.dst.reserve(8192); self.dst.reserve(8192);
match decoder.as_mut().as_mut().unwrap().read(unsafe{self.dst.bytes_mut()}) { match decoder.as_mut()
.as_mut().unwrap().read(unsafe{self.dst.bytes_mut()})
{
Ok(n) => { Ok(n) => {
if n != 0 {
unsafe{self.dst.advance_mut(n)};
}
if n == 0 { if n == 0 {
return Ok(Some(self.dst.take().freeze())); return Ok(Some(self.dst.take().freeze()));
} else {
unsafe{self.dst.advance_mut(n)};
} }
} }
Err(e) => { Err(e) => {
if e.kind() == io::ErrorKind::WouldBlock && !self.dst.is_empty()
{
return Ok(Some(self.dst.take().freeze()));
}
return Err(e) return Err(e)
} }
} }
} }
}, },
Decoder::Deflate(ref mut decoder) => { Decoder::Deflate(ref mut decoder) => {
match decoder.write(&data).and_then(|_| decoder.flush()) { match decoder.write_all(&data) {
Ok(_) => { Ok(_) => {
decoder.flush()?;
let b = decoder.get_mut().take(); let b = decoder.get_mut().take();
if !b.is_empty() { if !b.is_empty() {
Ok(Some(b)) Ok(Some(b))
@ -590,9 +595,8 @@ impl ContentEncoder {
pub fn write(&mut self, data: Binary) -> Result<(), io::Error> { pub fn write(&mut self, data: Binary) -> Result<(), io::Error> {
match *self { match *self {
ContentEncoder::Br(ref mut encoder) => { ContentEncoder::Br(ref mut encoder) => {
match encoder.write(data.as_ref()) { match encoder.write_all(data.as_ref()) {
Ok(_) => Ok(_) => Ok(()),
encoder.flush(),
Err(err) => { Err(err) => {
trace!("Error decoding br encoding: {}", err); trace!("Error decoding br encoding: {}", err);
Err(err) Err(err)
@ -600,9 +604,8 @@ impl ContentEncoder {
} }
}, },
ContentEncoder::Gzip(ref mut encoder) => { ContentEncoder::Gzip(ref mut encoder) => {
match encoder.write(data.as_ref()) { match encoder.write_all(data.as_ref()) {
Ok(_) => Ok(_) => Ok(()),
encoder.flush(),
Err(err) => { Err(err) => {
trace!("Error decoding gzip encoding: {}", err); trace!("Error decoding gzip encoding: {}", err);
Err(err) Err(err)
@ -610,9 +613,8 @@ impl ContentEncoder {
} }
} }
ContentEncoder::Deflate(ref mut encoder) => { ContentEncoder::Deflate(ref mut encoder) => {
match encoder.write(data.as_ref()) { match encoder.write_all(data.as_ref()) {
Ok(_) => Ok(_) => Ok(()),
encoder.flush(),
Err(err) => { Err(err) => {
trace!("Error decoding deflate encoding: {}", err); trace!("Error decoding deflate encoding: {}", err);
Err(err) Err(err)

View File

@ -3,6 +3,7 @@ extern crate actix_web;
extern crate bytes; extern crate bytes;
extern crate futures; extern crate futures;
extern crate flate2; extern crate flate2;
extern crate rand;
use std::io::Read; use std::io::Read;
@ -10,6 +11,7 @@ use bytes::Bytes;
use futures::Future; use futures::Future;
use futures::stream::once; use futures::stream::once;
use flate2::read::GzDecoder; use flate2::read::GzDecoder;
use rand::Rng;
use actix_web::*; use actix_web::*;
@ -143,7 +145,12 @@ fn test_client_gzip_encoding_large() {
} }
#[test] #[test]
fn test_client_brotli_encoding() { fn test_client_gzip_encoding_large_random() {
let data = rand::thread_rng()
.gen_ascii_chars()
.take(100_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| { let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
req.body() req.body()
.and_then(|bytes: Bytes| { .and_then(|bytes: Bytes| {
@ -154,6 +161,30 @@ fn test_client_brotli_encoding() {
}).responder()} }).responder()}
)); ));
// client request
let request = srv.post()
.content_encoding(headers::ContentEncoding::Gzip)
.body(data.clone()).unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from(data));
}
#[test]
fn test_client_brotli_encoding() {
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
req.body()
.and_then(|bytes: Bytes| {
Ok(httpcodes::HTTPOk
.build()
.content_encoding(headers::ContentEncoding::Gzip)
.body(bytes))
}).responder()}
));
// client request // client request
let request = srv.client(Method::POST, "/") let request = srv.client(Method::POST, "/")
.content_encoding(headers::ContentEncoding::Br) .content_encoding(headers::ContentEncoding::Br)
@ -166,6 +197,36 @@ fn test_client_brotli_encoding() {
assert_eq!(bytes, Bytes::from_static(STR.as_ref())); assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
} }
#[test]
fn test_client_brotli_encoding_large_random() {
let data = rand::thread_rng()
.gen_ascii_chars()
.take(70_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
req.body()
.and_then(move |bytes: Bytes| {
Ok(httpcodes::HTTPOk
.build()
.content_encoding(headers::ContentEncoding::Gzip)
.body(bytes))
}).responder()}
));
// client request
let request = srv.client(Method::POST, "/")
.content_encoding(headers::ContentEncoding::Br)
.body(data.clone()).unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data));
}
#[test] #[test]
fn test_client_deflate_encoding() { fn test_client_deflate_encoding() {
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| { let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
@ -190,6 +251,35 @@ fn test_client_deflate_encoding() {
assert_eq!(bytes, Bytes::from_static(STR.as_ref())); assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
} }
#[test]
fn test_client_deflate_encoding_large_random() {
let data = rand::thread_rng()
.gen_ascii_chars()
.take(70_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
req.body()
.and_then(|bytes: Bytes| {
Ok(httpcodes::HTTPOk
.build()
.content_encoding(headers::ContentEncoding::Br)
.body(bytes))
}).responder()}
));
// client request
let request = srv.post()
.content_encoding(headers::ContentEncoding::Deflate)
.body(data.clone()).unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from(data));
}
#[test] #[test]
fn test_client_streaming_explicit() { fn test_client_streaming_explicit() {
let mut srv = test::TestServer::new( let mut srv = test::TestServer::new(

View File

@ -241,7 +241,7 @@ fn test_body_gzip_large() {
fn test_body_gzip_large_random() { fn test_body_gzip_large_random() {
let data = rand::thread_rng() let data = rand::thread_rng()
.gen_ascii_chars() .gen_ascii_chars()
.take(70000) .take(70_000)
.collect::<String>(); .collect::<String>();
let srv_data = Arc::new(data.clone()); let srv_data = Arc::new(data.clone());
@ -525,10 +525,10 @@ fn test_gzip_encoding_large() {
} }
#[test] #[test]
fn test_gzip_encoding_large_random() { fn test_reading_gzip_encoding_large_random() {
let data = rand::thread_rng() let data = rand::thread_rng()
.gen_ascii_chars() .gen_ascii_chars()
.take(6000) .take(60_000)
.collect::<String>(); .collect::<String>();
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| { let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
@ -554,11 +554,12 @@ fn test_gzip_encoding_large_random() {
// read response // read response
let bytes = srv.execute(response.body()).unwrap(); let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data)); assert_eq!(bytes, Bytes::from(data));
} }
#[test] #[test]
fn test_deflate_encoding() { fn test_reading_deflate_encoding() {
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| { let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
req.body() req.body()
.and_then(|bytes: Bytes| { .and_then(|bytes: Bytes| {
@ -586,7 +587,7 @@ fn test_deflate_encoding() {
} }
#[test] #[test]
fn test_deflate_encoding_large() { fn test_reading_deflate_encoding_large() {
let data = STR.repeat(10); let data = STR.repeat(10);
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| { let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
req.body() req.body()
@ -614,6 +615,40 @@ fn test_deflate_encoding_large() {
assert_eq!(bytes, Bytes::from(data)); assert_eq!(bytes, Bytes::from(data));
} }
#[test]
fn test_reading_deflate_encoding_large_random() {
let data = rand::thread_rng()
.gen_ascii_chars()
.take(160_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
req.body()
.and_then(|bytes: Bytes| {
Ok(httpcodes::HTTPOk
.build()
.content_encoding(headers::ContentEncoding::Identity)
.body(bytes))
}).responder()}
));
let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
e.write_all(data.as_ref()).unwrap();
let enc = e.finish().unwrap();
// client request
let request = srv.post()
.header(header::CONTENT_ENCODING, "deflate")
.body(enc).unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data));
}
#[test] #[test]
fn test_brotli_encoding() { fn test_brotli_encoding() {
let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| { let mut srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {