mirror of
https://github.com/fafhrd91/actix-web
synced 2025-01-18 05:41:50 +01:00
added content-encoding support to h2
This commit is contained in:
parent
bddd8e9c2e
commit
2379bcbf39
@ -395,6 +395,7 @@ impl Reader {
|
|||||||
let payload = if let Some(decoder) = decoder {
|
let payload = if let Some(decoder) = decoder {
|
||||||
let (tx, rx) = Payload::new(false);
|
let (tx, rx) = Payload::new(false);
|
||||||
|
|
||||||
|
// Content-Encoding
|
||||||
let enc = if let Some(enc) = msg.headers().get(CONTENT_ENCODING) {
|
let enc = if let Some(enc) = msg.headers().get(CONTENT_ENCODING) {
|
||||||
if let Ok(enc) = enc.to_str() {
|
if let Ok(enc) = enc.to_str() {
|
||||||
ContentEncoding::from(enc)
|
ContentEncoding::from(enc)
|
||||||
|
48
src/h2.rs
48
src/h2.rs
@ -7,6 +7,7 @@ use std::collections::VecDeque;
|
|||||||
|
|
||||||
use actix::Arbiter;
|
use actix::Arbiter;
|
||||||
use http::request::Parts;
|
use http::request::Parts;
|
||||||
|
use http::header::CONTENT_ENCODING;
|
||||||
use http2::{Reason, RecvStream};
|
use http2::{Reason, RecvStream};
|
||||||
use http2::server::{Server, Handshake, Respond};
|
use http2::server::{Server, Handshake, Respond};
|
||||||
use bytes::{Buf, Bytes};
|
use bytes::{Buf, Bytes};
|
||||||
@ -19,7 +20,8 @@ use h2writer::H2Writer;
|
|||||||
use channel::HttpHandler;
|
use channel::HttpHandler;
|
||||||
use httpcodes::HTTPNotFound;
|
use httpcodes::HTTPNotFound;
|
||||||
use httprequest::HttpRequest;
|
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
|
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 {
|
struct Entry {
|
||||||
task: Task,
|
task: Task,
|
||||||
req: UnsafeCell<HttpRequest>,
|
req: UnsafeCell<HttpRequest>,
|
||||||
payload: PayloadSender,
|
payload: PayloadInfo,
|
||||||
recv: RecvStream,
|
recv: RecvStream,
|
||||||
stream: H2Writer,
|
stream: H2Writer,
|
||||||
eof: bool,
|
eof: bool,
|
||||||
@ -218,7 +236,23 @@ impl Entry {
|
|||||||
|
|
||||||
let mut req = HttpRequest::new(
|
let mut req = HttpRequest::new(
|
||||||
parts.method, path, parts.version, parts.headers, query);
|
parts.method, path, parts.version, parts.headers, query);
|
||||||
|
|
||||||
|
// Payload and Content-Encoding
|
||||||
let (psender, payload) = Payload::new(false);
|
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
|
// start request processing
|
||||||
let mut task = None;
|
let mut task = None;
|
||||||
@ -231,7 +265,7 @@ impl Entry {
|
|||||||
|
|
||||||
Entry {task: task.unwrap_or_else(|| Task::reply(HTTPNotFound)),
|
Entry {task: task.unwrap_or_else(|| Task::reply(HTTPNotFound)),
|
||||||
req: UnsafeCell::new(req),
|
req: UnsafeCell::new(req),
|
||||||
payload: psender,
|
payload: PayloadInfo(psender),
|
||||||
recv: recv,
|
recv: recv,
|
||||||
stream: H2Writer::new(resp),
|
stream: H2Writer::new(resp),
|
||||||
eof: false,
|
eof: false,
|
||||||
@ -246,22 +280,22 @@ impl Entry {
|
|||||||
if !self.reof {
|
if !self.reof {
|
||||||
match self.recv.poll() {
|
match self.recv.poll() {
|
||||||
Ok(Async::Ready(Some(chunk))) => {
|
Ok(Async::Ready(Some(chunk))) => {
|
||||||
self.payload.feed_data(chunk);
|
self.payload.as_mut().feed_data(chunk);
|
||||||
},
|
},
|
||||||
Ok(Async::Ready(None)) => {
|
Ok(Async::Ready(None)) => {
|
||||||
self.reof = true;
|
self.reof = true;
|
||||||
},
|
},
|
||||||
Ok(Async::NotReady) => (),
|
Ok(Async::NotReady) => (),
|
||||||
Err(err) => {
|
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 {
|
if self.capacity != capacity {
|
||||||
self.capacity = capacity;
|
self.capacity = capacity;
|
||||||
if let Err(err) = self.recv.release_capacity().release_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,
|
Identity,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// should go after write::GzDecoder get implemented
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Wrapper {
|
struct Wrapper {
|
||||||
buf: BytesMut
|
buf: BytesMut
|
||||||
@ -247,6 +248,7 @@ impl io::Write for BytesWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// should go after brotli2::write::BrotliDecoder::get_mut get implemented
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct WrapperRc {
|
struct WrapperRc {
|
||||||
buf: Rc<RefCell<BytesMut>>,
|
buf: Rc<RefCell<BytesMut>>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user