mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-30 18:34:36 +01:00
fix missing content-encoding header for h2 connections #421
This commit is contained in:
parent
6048817ba7
commit
f58065082e
15
CHANGES.md
15
CHANGES.md
@ -4,19 +4,24 @@
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Add implementation of `FromRequest<S>` for `Option<T>` and `Result<T, Error>`
|
* Add implementation of `FromRequest<S>` for `Option<T>` and `Result<T, Error>`
|
||||||
|
|
||||||
* Allow to handle application prefix, i.e. allow to handle `/app` path
|
* Allow to handle application prefix, i.e. allow to handle `/app` path
|
||||||
for application with `/app` prefix.
|
for application with `/app` prefix.
|
||||||
Check [`App::prefix()`](https://actix.rs/actix-web/actix_web/struct.App.html#method.prefix)
|
Check [`App::prefix()`](https://actix.rs/actix-web/actix_web/struct.App.html#method.prefix)
|
||||||
api doc.
|
api doc.
|
||||||
|
|
||||||
|
* Add `CookieSessionBackend::http_only` method to set `HttpOnly` directive of cookies
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Upgrade to cookie 0.11
|
||||||
|
|
||||||
|
* Removed the timestamp from the default logger middleware
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
* removed the timestamp from the default logger middleware
|
* Missing response header "content-encoding" #421
|
||||||
|
|
||||||
* Add `CookieSessionBackend::http_only` method to set `HttpOnly` directive of cookies
|
|
||||||
|
|
||||||
|
|
||||||
## [0.7.1] - 2018-07-21
|
## [0.7.1] - 2018-07-21
|
||||||
|
@ -8,16 +8,18 @@ use modhttp::Response;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::{cmp, io};
|
use std::{cmp, io};
|
||||||
|
|
||||||
use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING};
|
|
||||||
use http::{HttpTryFrom, Method, Version};
|
use http::{HttpTryFrom, Method, Version};
|
||||||
|
|
||||||
use super::helpers;
|
use super::helpers;
|
||||||
use super::message::Request;
|
use super::message::Request;
|
||||||
use super::output::{Output, ResponseInfo};
|
use super::output::{Output, ResponseInfo, ResponseLength};
|
||||||
use super::settings::WorkerSettings;
|
use super::settings::WorkerSettings;
|
||||||
use super::{Writer, WriterState, MAX_WRITE_BUFFER_SIZE};
|
use super::{Writer, WriterState, MAX_WRITE_BUFFER_SIZE};
|
||||||
use body::{Binary, Body};
|
use body::{Binary, Body};
|
||||||
use header::ContentEncoding;
|
use header::ContentEncoding;
|
||||||
|
use http::header::{
|
||||||
|
HeaderValue, CONNECTION, CONTENT_ENCODING, CONTENT_LENGTH, DATE, TRANSFER_ENCODING,
|
||||||
|
};
|
||||||
use httpresponse::HttpResponse;
|
use httpresponse::HttpResponse;
|
||||||
|
|
||||||
const CHUNK_SIZE: usize = 16_384;
|
const CHUNK_SIZE: usize = 16_384;
|
||||||
@ -92,50 +94,63 @@ impl<H: 'static> Writer for H2Writer<H> {
|
|||||||
let mut info = ResponseInfo::new(req.inner.method == Method::HEAD);
|
let mut info = ResponseInfo::new(req.inner.method == Method::HEAD);
|
||||||
self.buffer.for_server(&mut info, &req.inner, msg, encoding);
|
self.buffer.for_server(&mut info, &req.inner, msg, encoding);
|
||||||
|
|
||||||
// http2 specific
|
let mut has_date = false;
|
||||||
msg.headers_mut().remove(CONNECTION);
|
|
||||||
msg.headers_mut().remove(TRANSFER_ENCODING);
|
|
||||||
|
|
||||||
// using helpers::date is quite a lot faster
|
|
||||||
if !msg.headers().contains_key(DATE) {
|
|
||||||
let mut bytes = BytesMut::with_capacity(29);
|
|
||||||
self.settings.set_date(&mut bytes, false);
|
|
||||||
msg.headers_mut()
|
|
||||||
.insert(DATE, HeaderValue::try_from(bytes.freeze()).unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
let body = msg.replace_body(Body::Empty);
|
|
||||||
match body {
|
|
||||||
Body::Binary(ref bytes) => {
|
|
||||||
if bytes.is_empty() {
|
|
||||||
msg.headers_mut()
|
|
||||||
.insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
|
|
||||||
self.flags.insert(Flags::EOF);
|
|
||||||
} else {
|
|
||||||
let mut val = BytesMut::new();
|
|
||||||
helpers::convert_usize(bytes.len(), &mut val);
|
|
||||||
let l = val.len();
|
|
||||||
msg.headers_mut().insert(
|
|
||||||
CONTENT_LENGTH,
|
|
||||||
HeaderValue::try_from(val.split_to(l - 2).freeze()).unwrap(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Body::Empty => {
|
|
||||||
self.flags.insert(Flags::EOF);
|
|
||||||
msg.headers_mut()
|
|
||||||
.insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut resp = Response::new(());
|
let mut resp = Response::new(());
|
||||||
*resp.status_mut() = msg.status();
|
*resp.status_mut() = msg.status();
|
||||||
*resp.version_mut() = Version::HTTP_2;
|
*resp.version_mut() = Version::HTTP_2;
|
||||||
for (key, value) in msg.headers().iter() {
|
for (key, value) in msg.headers().iter() {
|
||||||
|
match *key {
|
||||||
|
// http2 specific
|
||||||
|
CONNECTION | TRANSFER_ENCODING => continue,
|
||||||
|
CONTENT_ENCODING => if encoding != ContentEncoding::Identity {
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
CONTENT_LENGTH => match info.length {
|
||||||
|
ResponseLength::None => (),
|
||||||
|
_ => continue,
|
||||||
|
},
|
||||||
|
DATE => has_date = true,
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
resp.headers_mut().insert(key, value.clone());
|
resp.headers_mut().insert(key, value.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set date header
|
||||||
|
if !has_date {
|
||||||
|
let mut bytes = BytesMut::with_capacity(29);
|
||||||
|
self.settings.set_date(&mut bytes, false);
|
||||||
|
resp.headers_mut()
|
||||||
|
.insert(DATE, HeaderValue::try_from(bytes.freeze()).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
// content length
|
||||||
|
match info.length {
|
||||||
|
ResponseLength::Zero => {
|
||||||
|
resp.headers_mut()
|
||||||
|
.insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
|
||||||
|
self.flags.insert(Flags::EOF);
|
||||||
|
}
|
||||||
|
ResponseLength::Length(len) => {
|
||||||
|
let mut val = BytesMut::new();
|
||||||
|
helpers::convert_usize(len, &mut val);
|
||||||
|
let l = val.len();
|
||||||
|
resp.headers_mut().insert(
|
||||||
|
CONTENT_LENGTH,
|
||||||
|
HeaderValue::try_from(val.split_to(l - 2).freeze()).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ResponseLength::Length64(len) => {
|
||||||
|
let l = format!("{}", len);
|
||||||
|
resp.headers_mut()
|
||||||
|
.insert(CONTENT_LENGTH, HeaderValue::try_from(l.as_str()).unwrap());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
if let Some(ce) = info.content_encoding {
|
||||||
|
resp.headers_mut()
|
||||||
|
.insert(CONTENT_ENCODING, HeaderValue::try_from(ce).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
match self
|
match self
|
||||||
.respond
|
.respond
|
||||||
.send_response(resp, self.flags.contains(Flags::EOF))
|
.send_response(resp, self.flags.contains(Flags::EOF))
|
||||||
@ -146,6 +161,7 @@ impl<H: 'static> Writer for H2Writer<H> {
|
|||||||
|
|
||||||
trace!("Response: {:?}", msg);
|
trace!("Response: {:?}", msg);
|
||||||
|
|
||||||
|
let body = msg.replace_body(Body::Empty);
|
||||||
if let Body::Binary(bytes) = body {
|
if let Body::Binary(bytes) = body {
|
||||||
if bytes.is_empty() {
|
if bytes.is_empty() {
|
||||||
Ok(WriterState::Done)
|
Ok(WriterState::Done)
|
||||||
|
Loading…
Reference in New Issue
Block a user