1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-23 23:51:06 +01:00

do not encode payload less that 1024 bytes

This commit is contained in:
Nikolay Kim 2017-11-29 19:18:37 -08:00
parent d2eae3d5b3
commit 559b1c50a3
2 changed files with 32 additions and 15 deletions

View File

@ -45,7 +45,7 @@ impl Body {
/// Does this body streaming. /// Does this body streaming.
pub fn is_streaming(&self) -> bool { pub fn is_streaming(&self) -> bool {
match *self { match *self {
Body::Length(_) | Body::Streaming => true, Body::Length(_) | Body::Streaming | Body::Upgrade => true,
_ => false _ => false
} }
} }

View File

@ -13,7 +13,7 @@ use flate2::write::{GzEncoder, DeflateDecoder, DeflateEncoder};
use brotli2::write::{BrotliDecoder, BrotliEncoder}; use brotli2::write::{BrotliDecoder, BrotliEncoder};
use bytes::{Bytes, BytesMut, BufMut, Writer}; use bytes::{Bytes, BytesMut, BufMut, Writer};
use body::Body; use body::{Body, Binary};
use error::PayloadError; use error::PayloadError;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;
@ -338,11 +338,15 @@ impl PayloadEncoder {
pub fn new(req: &HttpRequest, resp: &mut HttpResponse) -> PayloadEncoder { pub fn new(req: &HttpRequest, resp: &mut HttpResponse) -> PayloadEncoder {
let version = resp.version().unwrap_or_else(|| req.version()); let version = resp.version().unwrap_or_else(|| req.version());
let body = resp.replace_body(Body::Empty); let mut body = resp.replace_body(Body::Empty);
let has_body = if let Body::Empty = body { false } else { true }; let has_body = match body {
Body::Empty => false,
Body::Binary(ref bin) => bin.len() >= 1024,
_ => true,
};
// Enable content encoding only if response does not contain Content-Encoding header // Enable content encoding only if response does not contain Content-Encoding header
let encoding = if has_body && !resp.headers.contains_key(CONTENT_ENCODING) { let mut encoding = if has_body && !resp.headers.contains_key(CONTENT_ENCODING) {
let encoding = match *resp.content_encoding() { let encoding = match *resp.content_encoding() {
ContentEncoding::Auto => { ContentEncoding::Auto => {
// negotiate content-encoding // negotiate content-encoding
@ -399,17 +403,30 @@ impl PayloadEncoder {
TransferEncoding::length(n) TransferEncoding::length(n)
} }
}, },
Body::Binary(ref bytes) => { Body::Binary(ref mut bytes) => {
if compression { if compression {
resp.headers.remove(CONTENT_LENGTH); let transfer = TransferEncoding::eof();
if version == Version::HTTP_2 { let mut enc = match encoding {
resp.headers.remove(TRANSFER_ENCODING); ContentEncoding::Deflate => ContentEncoder::Deflate(
TransferEncoding::eof() DeflateEncoder::new(transfer, Compression::Default)),
} else { ContentEncoding::Gzip => ContentEncoder::Gzip(
resp.headers.insert( GzEncoder::new(transfer, Compression::Default)),
TRANSFER_ENCODING, HeaderValue::from_static("chunked")); ContentEncoding::Br => ContentEncoder::Br(
TransferEncoding::chunked() BrotliEncoder::new(transfer, 5)),
} ContentEncoding::Identity => ContentEncoder::Identity(transfer),
ContentEncoding::Auto => unreachable!()
};
// TODO return error!
let _ = enc.write(bytes.as_ref());
let _ = enc.write_eof();
let b = enc.get_mut().take();
resp.headers.insert(
CONTENT_LENGTH,
HeaderValue::from_str(format!("{}", b.len()).as_str()).unwrap());
*bytes = Binary::from(b);
encoding = ContentEncoding::Identity;
TransferEncoding::eof()
} else { } else {
resp.headers.insert( resp.headers.insert(
CONTENT_LENGTH, CONTENT_LENGTH,