mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-27 17:52:56 +01:00
Fix websockets connection drop if request contains content-length header #567
This commit is contained in:
parent
7065c540e1
commit
61b1030882
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
* Fix websockets connection drop if request contains "content-length" header #567
|
||||||
|
|
||||||
* Fix keep-alive timer reset
|
* Fix keep-alive timer reset
|
||||||
|
|
||||||
* HttpServer now treats streaming bodies the same for HTTP/1.x protocols. #549
|
* HttpServer now treats streaming bodies the same for HTTP/1.x protocols. #549
|
||||||
|
@ -61,8 +61,8 @@ flate2-rust = ["flate2/rust_backend"]
|
|||||||
cell = ["actix-net/cell"]
|
cell = ["actix-net/cell"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix = "^0.7.5"
|
actix = "0.7.6"
|
||||||
actix-net = "0.2.0"
|
actix-net = "0.2.1"
|
||||||
|
|
||||||
askama_escape = "0.1.0"
|
askama_escape = "0.1.0"
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
|
@ -43,7 +43,9 @@ impl H1Decoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode<H>(
|
pub fn decode<H>(
|
||||||
&mut self, src: &mut BytesMut, settings: &ServiceConfig<H>,
|
&mut self,
|
||||||
|
src: &mut BytesMut,
|
||||||
|
settings: &ServiceConfig<H>,
|
||||||
) -> Result<Option<Message>, DecoderError> {
|
) -> Result<Option<Message>, DecoderError> {
|
||||||
// read payload
|
// read payload
|
||||||
if self.decoder.is_some() {
|
if self.decoder.is_some() {
|
||||||
@ -80,7 +82,9 @@ impl H1Decoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_message<H>(
|
fn parse_message<H>(
|
||||||
&self, buf: &mut BytesMut, settings: &ServiceConfig<H>,
|
&self,
|
||||||
|
buf: &mut BytesMut,
|
||||||
|
settings: &ServiceConfig<H>,
|
||||||
) -> Poll<(Request, Option<EncodingDecoder>), ParseError> {
|
) -> Poll<(Request, Option<EncodingDecoder>), ParseError> {
|
||||||
// Parse http message
|
// Parse http message
|
||||||
let mut has_upgrade = false;
|
let mut has_upgrade = false;
|
||||||
@ -178,6 +182,13 @@ impl H1Decoder {
|
|||||||
}
|
}
|
||||||
header::UPGRADE => {
|
header::UPGRADE => {
|
||||||
has_upgrade = true;
|
has_upgrade = true;
|
||||||
|
// check content-length, some clients (dart)
|
||||||
|
// sends "content-length: 0" with websocket upgrade
|
||||||
|
if let Ok(val) = value.to_str() {
|
||||||
|
if val == "websocket" {
|
||||||
|
content_length = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@ -221,7 +232,9 @@ pub(crate) struct HeaderIndex {
|
|||||||
|
|
||||||
impl HeaderIndex {
|
impl HeaderIndex {
|
||||||
pub(crate) fn record(
|
pub(crate) fn record(
|
||||||
bytes: &[u8], headers: &[httparse::Header], indices: &mut [HeaderIndex],
|
bytes: &[u8],
|
||||||
|
headers: &[httparse::Header],
|
||||||
|
indices: &mut [HeaderIndex],
|
||||||
) {
|
) {
|
||||||
let bytes_ptr = bytes.as_ptr() as usize;
|
let bytes_ptr = bytes.as_ptr() as usize;
|
||||||
for (header, indices) in headers.iter().zip(indices.iter_mut()) {
|
for (header, indices) in headers.iter().zip(indices.iter_mut()) {
|
||||||
@ -369,7 +382,10 @@ macro_rules! byte (
|
|||||||
|
|
||||||
impl ChunkedState {
|
impl ChunkedState {
|
||||||
fn step(
|
fn step(
|
||||||
&self, body: &mut BytesMut, size: &mut u64, buf: &mut Option<Bytes>,
|
&self,
|
||||||
|
body: &mut BytesMut,
|
||||||
|
size: &mut u64,
|
||||||
|
buf: &mut Option<Bytes>,
|
||||||
) -> Poll<ChunkedState, io::Error> {
|
) -> Poll<ChunkedState, io::Error> {
|
||||||
use self::ChunkedState::*;
|
use self::ChunkedState::*;
|
||||||
match *self {
|
match *self {
|
||||||
@ -432,7 +448,8 @@ impl ChunkedState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn read_size_lf(
|
fn read_size_lf(
|
||||||
rdr: &mut BytesMut, size: &mut u64,
|
rdr: &mut BytesMut,
|
||||||
|
size: &mut u64,
|
||||||
) -> Poll<ChunkedState, io::Error> {
|
) -> Poll<ChunkedState, io::Error> {
|
||||||
match byte!(rdr) {
|
match byte!(rdr) {
|
||||||
b'\n' if *size > 0 => Ok(Async::Ready(ChunkedState::Body)),
|
b'\n' if *size > 0 => Ok(Async::Ready(ChunkedState::Body)),
|
||||||
@ -445,7 +462,9 @@ impl ChunkedState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_body(
|
fn read_body(
|
||||||
rdr: &mut BytesMut, rem: &mut u64, buf: &mut Option<Bytes>,
|
rdr: &mut BytesMut,
|
||||||
|
rem: &mut u64,
|
||||||
|
buf: &mut Option<Bytes>,
|
||||||
) -> Poll<ChunkedState, io::Error> {
|
) -> Poll<ChunkedState, io::Error> {
|
||||||
trace!("Chunked read, remaining={:?}", rem);
|
trace!("Chunked read, remaining={:?}", rem);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ where
|
|||||||
Ok(Async::Ready(()))
|
Ok(Async::Ready(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, mut req: Self::Request) -> Self::Future {
|
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||||
HttpChannel::new(self.settings.clone(), req)
|
HttpChannel::new(self.settings.clone(), req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user