mirror of
https://github.com/actix/actix-web.git
synced 2024-11-18 15:41:17 +00:00
added content-encoding support to h2
This commit is contained in:
parent
bddd8e9c2e
commit
2379bcbf39
3 changed files with 44 additions and 7 deletions
|
@ -395,6 +395,7 @@ impl Reader {
|
|||
let payload = if let Some(decoder) = decoder {
|
||||
let (tx, rx) = Payload::new(false);
|
||||
|
||||
// Content-Encoding
|
||||
let enc = if let Some(enc) = msg.headers().get(CONTENT_ENCODING) {
|
||||
if let Ok(enc) = enc.to_str() {
|
||||
ContentEncoding::from(enc)
|
||||
|
|
48
src/h2.rs
48
src/h2.rs
|
@ -7,6 +7,7 @@ use std::collections::VecDeque;
|
|||
|
||||
use actix::Arbiter;
|
||||
use http::request::Parts;
|
||||
use http::header::CONTENT_ENCODING;
|
||||
use http2::{Reason, RecvStream};
|
||||
use http2::server::{Server, Handshake, Respond};
|
||||
use bytes::{Buf, Bytes};
|
||||
|
@ -19,7 +20,8 @@ use h2writer::H2Writer;
|
|||
use channel::HttpHandler;
|
||||
use httpcodes::HTTPNotFound;
|
||||
use httprequest::HttpRequest;
|
||||
use payload::{Payload, PayloadError, PayloadSender, PayloadWriter};
|
||||
use httpresponse::ContentEncoding;
|
||||
use payload::{Payload, PayloadError, PayloadSender, PayloadWriter, EncodedPayload};
|
||||
|
||||
const KEEPALIVE_PERIOD: u64 = 15; // seconds
|
||||
|
||||
|
@ -193,10 +195,26 @@ impl<T, A, H> Http2<T, A, H>
|
|||
}
|
||||
}
|
||||
|
||||
struct PayloadInfo(PayloadInfoItem);
|
||||
enum PayloadInfoItem {
|
||||
Sender(PayloadSender),
|
||||
Encoding(EncodedPayload),
|
||||
}
|
||||
|
||||
impl PayloadInfo {
|
||||
|
||||
fn as_mut(&mut self) -> &mut PayloadWriter {
|
||||
match self.0 {
|
||||
PayloadInfoItem::Sender(ref mut sender) => sender,
|
||||
PayloadInfoItem::Encoding(ref mut enc) => enc,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
task: Task,
|
||||
req: UnsafeCell<HttpRequest>,
|
||||
payload: PayloadSender,
|
||||
payload: PayloadInfo,
|
||||
recv: RecvStream,
|
||||
stream: H2Writer,
|
||||
eof: bool,
|
||||
|
@ -218,7 +236,23 @@ impl Entry {
|
|||
|
||||
let mut req = HttpRequest::new(
|
||||
parts.method, path, parts.version, parts.headers, query);
|
||||
|
||||
// Payload and Content-Encoding
|
||||
let (psender, payload) = Payload::new(false);
|
||||
let enc = if let Some(enc) = req.headers().get(CONTENT_ENCODING) {
|
||||
if let Ok(enc) = enc.to_str() {
|
||||
ContentEncoding::from(enc)
|
||||
} else {
|
||||
ContentEncoding::Auto
|
||||
}
|
||||
} else {
|
||||
ContentEncoding::Auto
|
||||
};
|
||||
let psender = match enc {
|
||||
ContentEncoding::Auto | ContentEncoding::Identity =>
|
||||
PayloadInfoItem::Sender(psender),
|
||||
_ => PayloadInfoItem::Encoding(EncodedPayload::new(psender, enc)),
|
||||
};
|
||||
|
||||
// start request processing
|
||||
let mut task = None;
|
||||
|
@ -231,7 +265,7 @@ impl Entry {
|
|||
|
||||
Entry {task: task.unwrap_or_else(|| Task::reply(HTTPNotFound)),
|
||||
req: UnsafeCell::new(req),
|
||||
payload: psender,
|
||||
payload: PayloadInfo(psender),
|
||||
recv: recv,
|
||||
stream: H2Writer::new(resp),
|
||||
eof: false,
|
||||
|
@ -246,22 +280,22 @@ impl Entry {
|
|||
if !self.reof {
|
||||
match self.recv.poll() {
|
||||
Ok(Async::Ready(Some(chunk))) => {
|
||||
self.payload.feed_data(chunk);
|
||||
self.payload.as_mut().feed_data(chunk);
|
||||
},
|
||||
Ok(Async::Ready(None)) => {
|
||||
self.reof = true;
|
||||
},
|
||||
Ok(Async::NotReady) => (),
|
||||
Err(err) => {
|
||||
self.payload.set_error(PayloadError::Http2(err))
|
||||
self.payload.as_mut().set_error(PayloadError::Http2(err))
|
||||
}
|
||||
}
|
||||
|
||||
let capacity = self.payload.capacity();
|
||||
let capacity = self.payload.as_mut().capacity();
|
||||
if self.capacity != capacity {
|
||||
self.capacity = capacity;
|
||||
if let Err(err) = self.recv.release_capacity().release_capacity(capacity) {
|
||||
self.payload.set_error(PayloadError::Http2(err))
|
||||
self.payload.as_mut().set_error(PayloadError::Http2(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,6 +212,7 @@ enum Decoder {
|
|||
Identity,
|
||||
}
|
||||
|
||||
// should go after write::GzDecoder get implemented
|
||||
#[derive(Debug)]
|
||||
struct Wrapper {
|
||||
buf: BytesMut
|
||||
|
@ -247,6 +248,7 @@ impl io::Write for BytesWriter {
|
|||
}
|
||||
|
||||
|
||||
// should go after brotli2::write::BrotliDecoder::get_mut get implemented
|
||||
#[derive(Debug)]
|
||||
struct WrapperRc {
|
||||
buf: Rc<RefCell<BytesMut>>,
|
||||
|
|
Loading…
Reference in a new issue