1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-10-21 17:33:59 +00:00

fix socket polling

This commit is contained in:
Nikolay Kim 2018-03-03 12:17:26 -08:00
parent 058630d041
commit 2ccbd5fa18
2 changed files with 55 additions and 58 deletions

View file

@ -2,7 +2,7 @@ use std::mem;
use httparse;
use http::{Version, HttpTryFrom, HeaderMap, StatusCode};
use http::header::{self, HeaderName, HeaderValue};
use bytes::{Bytes, BytesMut, BufMut};
use bytes::{Bytes, BytesMut};
use futures::{Poll, Async};
use error::{ParseError, PayloadError};
@ -37,7 +37,7 @@ impl HttpResponseParser {
where T: IoStream
{
// if buf is empty parse_message will always return NotReady, let's avoid that
let read = if buf.is_empty() {
if buf.is_empty() {
match utils::read_from_io(io, buf) {
Ok(Async::Ready(0)) =>
return Err(HttpResponseParserError::Disconnect),
@ -47,13 +47,12 @@ impl HttpResponseParser {
Err(err) =>
return Err(HttpResponseParserError::Error(err.into()))
}
false
} else {
true
};
}
loop {
match HttpResponseParser::parse_message(buf).map_err(HttpResponseParserError::Error)? {
match HttpResponseParser::parse_message(buf)
.map_err(HttpResponseParserError::Error)?
{
Async::Ready((msg, decoder)) => {
self.decoder = decoder;
return Ok(Async::Ready(msg));
@ -62,7 +61,6 @@ impl HttpResponseParser {
if buf.capacity() >= MAX_BUFFER_SIZE {
return Err(HttpResponseParserError::Error(ParseError::TooLarge));
}
if read || buf.remaining_mut() == 0 {
match utils::read_from_io(io, buf) {
Ok(Async::Ready(0)) =>
return Err(HttpResponseParserError::Disconnect),
@ -71,9 +69,6 @@ impl HttpResponseParser {
Err(err) =>
return Err(HttpResponseParserError::Error(err.into())),
}
} else {
return Ok(Async::NotReady)
}
},
}
}
@ -84,25 +79,34 @@ impl HttpResponseParser {
where T: IoStream
{
if self.decoder.is_some() {
loop {
// read payload
match utils::read_from_io(io, buf) {
let not_ready = match utils::read_from_io(io, buf) {
Ok(Async::Ready(0)) => {
if buf.is_empty() {
return Err(PayloadError::Incomplete)
}
true
}
Err(err) => return Err(err.into()),
_ => (),
}
Ok(Async::NotReady) => true,
_ => false,
};
match self.decoder.as_mut().unwrap().decode(buf) {
Ok(Async::Ready(Some(b))) => Ok(Async::Ready(Some(b))),
Ok(Async::Ready(Some(b))) =>
return Ok(Async::Ready(Some(b))),
Ok(Async::Ready(None)) => {
self.decoder.take();
Ok(Async::Ready(None))
return Ok(Async::Ready(None))
}
Ok(Async::NotReady) => {
if not_ready {
return Ok(Async::NotReady)
}
}
Err(err) => return Err(err.into()),
}
Ok(Async::NotReady) => Ok(Async::NotReady),
Err(err) => Err(err.into()),
}
} else {
Ok(Async::Ready(None))

View file

@ -10,7 +10,7 @@ use actix::Arbiter;
use httparse;
use http::{Uri, Method, Version, HttpTryFrom, HeaderMap};
use http::header::{self, HeaderName, HeaderValue};
use bytes::{Bytes, BytesMut, BufMut};
use bytes::{Bytes, BytesMut};
use futures::{Future, Poll, Async};
use tokio_core::reactor::Timeout;
@ -403,22 +403,22 @@ impl Reader {
let done = {
if let Some(ref mut payload) = self.payload {
'buf: loop {
match utils::read_from_io(io, buf) {
let not_ready = match utils::read_from_io(io, buf) {
Ok(Async::Ready(0)) => {
payload.tx.set_error(PayloadError::Incomplete);
// http channel should not deal with payload errors
return Err(ReaderError::Payload)
},
Ok(Async::NotReady) => true,
Err(err) => {
payload.tx.set_error(err.into());
// http channel should not deal with payload errors
return Err(ReaderError::Payload)
}
_ => (),
}
let is_full = buf.remaining_mut() == 0;
_ => false,
};
loop {
match payload.decoder.decode(buf) {
Ok(Async::Ready(Some(bytes))) => {
@ -435,10 +435,10 @@ impl Reader {
Ok(Async::NotReady) => {
// if buffer is full then
// socket still can contain more data
if is_full {
continue 'buf
}
if not_ready {
return Ok(Async::NotReady)
}
continue 'buf
},
Err(err) => {
payload.tx.set_error(err.into());
@ -454,16 +454,13 @@ impl Reader {
if done { self.payload = None }
// if buf is empty parse_message will always return NotReady, let's avoid that
let read = if buf.is_empty() {
if buf.is_empty() {
match utils::read_from_io(io, buf) {
Ok(Async::Ready(0)) => return Err(ReaderError::Disconnect),
Ok(Async::Ready(_)) => (),
Ok(Async::NotReady) => return Ok(Async::NotReady),
Err(err) => return Err(ReaderError::Error(err.into()))
}
false
} else {
true
};
loop {
@ -483,7 +480,6 @@ impl Reader {
error!("MAX_BUFFER_SIZE unprocessed data reached, closing");
return Err(ReaderError::Error(ParseError::TooLarge));
}
if read || buf.remaining_mut() == 0 {
match utils::read_from_io(io, buf) {
Ok(Async::Ready(0)) => {
debug!("Ignored premature client disconnection");
@ -493,9 +489,6 @@ impl Reader {
Ok(Async::NotReady) => return Ok(Async::NotReady),
Err(err) => return Err(ReaderError::Error(err.into())),
}
} else {
return Ok(Async::NotReady)
}
},
}
}