mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-30 18:44:35 +01:00
fix back pressure for h1 import stream
This commit is contained in:
parent
728377a447
commit
74377ef73d
@ -260,6 +260,7 @@ impl PayloadWriter for PayloadSender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn capacity(&self) -> usize {
|
fn capacity(&self) -> usize {
|
||||||
if let Some(shared) = self.inner.upgrade() {
|
if let Some(shared) = self.inner.upgrade() {
|
||||||
shared.borrow().capacity()
|
shared.borrow().capacity()
|
||||||
@ -327,10 +328,10 @@ impl Inner {
|
|||||||
if let Some(data) = self.items.pop_front() {
|
if let Some(data) = self.items.pop_front() {
|
||||||
self.len -= data.len();
|
self.len -= data.len();
|
||||||
Ok(Async::Ready(Some(PayloadItem(data))))
|
Ok(Async::Ready(Some(PayloadItem(data))))
|
||||||
} else if self.eof {
|
|
||||||
Ok(Async::Ready(None))
|
|
||||||
} else if let Some(err) = self.err.take() {
|
} else if let Some(err) = self.err.take() {
|
||||||
Err(err)
|
Err(err)
|
||||||
|
} else if self.eof {
|
||||||
|
Ok(Async::Ready(None))
|
||||||
} else {
|
} else {
|
||||||
self.task = Some(current_task());
|
self.task = Some(current_task());
|
||||||
Ok(Async::NotReady)
|
Ok(Async::NotReady)
|
||||||
@ -439,6 +440,7 @@ impl Inner {
|
|||||||
self.items.push_front(data);
|
self.items.push_front(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn capacity(&self) -> usize {
|
fn capacity(&self) -> usize {
|
||||||
if self.len > self.buf_size {
|
if self.len > self.buf_size {
|
||||||
0
|
0
|
||||||
|
@ -94,6 +94,7 @@ impl PayloadType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PayloadWriter for PayloadType {
|
impl PayloadWriter for PayloadType {
|
||||||
|
#[inline]
|
||||||
fn set_error(&mut self, err: PayloadError) {
|
fn set_error(&mut self, err: PayloadError) {
|
||||||
match *self {
|
match *self {
|
||||||
PayloadType::Sender(ref mut sender) => sender.set_error(err),
|
PayloadType::Sender(ref mut sender) => sender.set_error(err),
|
||||||
@ -101,6 +102,7 @@ impl PayloadWriter for PayloadType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn feed_eof(&mut self) {
|
fn feed_eof(&mut self) {
|
||||||
match *self {
|
match *self {
|
||||||
PayloadType::Sender(ref mut sender) => sender.feed_eof(),
|
PayloadType::Sender(ref mut sender) => sender.feed_eof(),
|
||||||
@ -108,6 +110,7 @@ impl PayloadWriter for PayloadType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn feed_data(&mut self, data: Bytes) {
|
fn feed_data(&mut self, data: Bytes) {
|
||||||
match *self {
|
match *self {
|
||||||
PayloadType::Sender(ref mut sender) => sender.feed_data(data),
|
PayloadType::Sender(ref mut sender) => sender.feed_data(data),
|
||||||
@ -115,6 +118,7 @@ impl PayloadWriter for PayloadType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn capacity(&self) -> usize {
|
fn capacity(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
PayloadType::Sender(ref sender) => sender.capacity(),
|
PayloadType::Sender(ref sender) => sender.capacity(),
|
||||||
|
@ -16,7 +16,7 @@ use pipeline::Pipeline;
|
|||||||
use httpcodes::HTTPNotFound;
|
use httpcodes::HTTPNotFound;
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
use error::{ParseError, PayloadError, ResponseError};
|
use error::{ParseError, PayloadError, ResponseError};
|
||||||
use payload::{Payload, PayloadWriter, DEFAULT_BUFFER_SIZE};
|
use payload::{Payload, PayloadWriter};
|
||||||
|
|
||||||
use super::{utils, Writer};
|
use super::{utils, Writer};
|
||||||
use super::h1writer::H1Writer;
|
use super::h1writer::H1Writer;
|
||||||
@ -319,7 +319,6 @@ struct Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum Decoding {
|
enum Decoding {
|
||||||
Paused,
|
|
||||||
Ready,
|
Ready,
|
||||||
NotReady,
|
NotReady,
|
||||||
}
|
}
|
||||||
@ -343,11 +342,10 @@ impl Reader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(&mut self, buf: &mut BytesMut) -> std::result::Result<Decoding, ReaderError> {
|
#[inline]
|
||||||
if let Some(ref mut payload) = self.payload {
|
fn decode(&mut self, buf: &mut BytesMut, payload: &mut PayloadInfo)
|
||||||
if payload.tx.capacity() > DEFAULT_BUFFER_SIZE {
|
-> std::result::Result<Decoding, ReaderError>
|
||||||
return Ok(Decoding::Paused)
|
{
|
||||||
}
|
|
||||||
loop {
|
loop {
|
||||||
match payload.decoder.decode(buf) {
|
match payload.decoder.decode(buf) {
|
||||||
Ok(Async::Ready(Some(bytes))) => {
|
Ok(Async::Ready(Some(bytes))) => {
|
||||||
@ -364,9 +362,6 @@ impl Reader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return Ok(Decoding::Ready)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse<T, H>(&mut self, io: &mut T,
|
pub fn parse<T, H>(&mut self, io: &mut T,
|
||||||
@ -375,29 +370,48 @@ impl Reader {
|
|||||||
where T: IoStream
|
where T: IoStream
|
||||||
{
|
{
|
||||||
// read payload
|
// read payload
|
||||||
if self.payload.is_some() {
|
let done = {
|
||||||
|
if let Some(ref mut payload) = self.payload {
|
||||||
|
if payload.tx.capacity() == 0 {
|
||||||
|
return Ok(Async::NotReady)
|
||||||
|
}
|
||||||
match utils::read_from_io(io, buf) {
|
match utils::read_from_io(io, buf) {
|
||||||
Ok(Async::Ready(0)) => {
|
Ok(Async::Ready(0)) => {
|
||||||
if let Some(ref mut payload) = self.payload {
|
|
||||||
payload.tx.set_error(PayloadError::Incomplete);
|
payload.tx.set_error(PayloadError::Incomplete);
|
||||||
}
|
|
||||||
// http channel should not deal with payload errors
|
// http channel should not deal with payload errors
|
||||||
return Err(ReaderError::Payload)
|
return Err(ReaderError::Payload)
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if let Some(ref mut payload) = self.payload {
|
|
||||||
payload.tx.set_error(err.into());
|
payload.tx.set_error(err.into());
|
||||||
}
|
|
||||||
// http channel should not deal with payload errors
|
// http channel should not deal with payload errors
|
||||||
return Err(ReaderError::Payload)
|
return Err(ReaderError::Payload)
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
match self.decode(buf)? {
|
loop {
|
||||||
Decoding::Ready => self.payload = None,
|
match payload.decoder.decode(buf) {
|
||||||
Decoding::Paused | Decoding::NotReady => return Ok(Async::NotReady),
|
Ok(Async::Ready(Some(bytes))) => {
|
||||||
|
payload.tx.feed_data(bytes)
|
||||||
|
},
|
||||||
|
Ok(Async::Ready(None)) => {
|
||||||
|
payload.tx.feed_eof();
|
||||||
|
break true
|
||||||
|
},
|
||||||
|
Ok(Async::NotReady) =>
|
||||||
|
break false,
|
||||||
|
Err(err) => {
|
||||||
|
payload.tx.set_error(err.into());
|
||||||
|
return Err(ReaderError::Payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if done { self.payload = None }
|
||||||
|
|
||||||
// if buf is empty parse_message will always return NotReady, let's avoid that
|
// if buf is empty parse_message will always return NotReady, let's avoid that
|
||||||
let read = if buf.is_empty() {
|
let read = if buf.is_empty() {
|
||||||
@ -421,11 +435,10 @@ impl Reader {
|
|||||||
match Reader::parse_message(buf, settings).map_err(ReaderError::Error)? {
|
match Reader::parse_message(buf, settings).map_err(ReaderError::Error)? {
|
||||||
Async::Ready((msg, decoder)) => {
|
Async::Ready((msg, decoder)) => {
|
||||||
// process payload
|
// process payload
|
||||||
if let Some(payload) = decoder {
|
if let Some(mut payload) = decoder {
|
||||||
self.payload = Some(payload);
|
match self.decode(buf, &mut payload)? {
|
||||||
match self.decode(buf)? {
|
Decoding::Ready => (),
|
||||||
Decoding::Paused | Decoding::NotReady => (),
|
Decoding::NotReady => self.payload = Some(payload),
|
||||||
Decoding::Ready => self.payload = None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(Async::Ready(msg));
|
return Ok(Async::Ready(msg));
|
||||||
|
Loading…
Reference in New Issue
Block a user