1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-12-19 22:56:39 +00:00

http/2 end-of-frame is not set if body is empty bytes #307

This commit is contained in:
Nikolay Kim 2018-06-12 14:47:45 -07:00
parent b5b9f9656e
commit 8a22558f25
2 changed files with 28 additions and 20 deletions

View file

@ -4,6 +4,8 @@
### Fixed ### Fixed
* http/2 end-of-frame is not set if body is empty bytes #307
* InternalError can trigger memory unsafety #301 * InternalError can trigger memory unsafety #301
* Fix docs.rs build * Fix docs.rs build

View file

@ -89,9 +89,6 @@ impl<H: 'static> Writer for H2Writer<H> {
self.flags.insert(Flags::STARTED); self.flags.insert(Flags::STARTED);
self.encoder = self.encoder =
ContentEncoder::for_server(self.buffer.clone(), req, msg, encoding); ContentEncoder::for_server(self.buffer.clone(), req, msg, encoding);
if let Body::Empty = *msg.body() {
self.flags.insert(Flags::EOF);
}
// http2 specific // http2 specific
msg.headers_mut().remove(CONNECTION); msg.headers_mut().remove(CONNECTION);
@ -108,15 +105,22 @@ impl<H: 'static> Writer for H2Writer<H> {
let body = msg.replace_body(Body::Empty); let body = msg.replace_body(Body::Empty);
match body { match body {
Body::Binary(ref bytes) => { Body::Binary(ref bytes) => {
let mut val = BytesMut::new(); if bytes.is_empty() {
helpers::convert_usize(bytes.len(), &mut val); msg.headers_mut()
let l = val.len(); .insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
msg.headers_mut().insert( self.flags.insert(Flags::EOF);
CONTENT_LENGTH, } else {
HeaderValue::try_from(val.split_to(l - 2).freeze()).unwrap(), let mut val = BytesMut::new();
); helpers::convert_usize(bytes.len(), &mut val);
let l = val.len();
msg.headers_mut().insert(
CONTENT_LENGTH,
HeaderValue::try_from(val.split_to(l - 2).freeze()).unwrap(),
);
}
} }
Body::Empty => { Body::Empty => {
self.flags.insert(Flags::EOF);
msg.headers_mut() msg.headers_mut()
.insert(CONTENT_LENGTH, HeaderValue::from_static("0")); .insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
} }
@ -141,14 +145,18 @@ impl<H: 'static> Writer for H2Writer<H> {
trace!("Response: {:?}", msg); trace!("Response: {:?}", msg);
if let Body::Binary(bytes) = body { if let Body::Binary(bytes) = body {
self.flags.insert(Flags::EOF); if bytes.is_empty() {
self.written = bytes.len() as u64; Ok(WriterState::Done)
self.encoder.write(bytes)?; } else {
if let Some(ref mut stream) = self.stream { self.flags.insert(Flags::EOF);
self.flags.insert(Flags::RESERVED); self.written = bytes.len() as u64;
stream.reserve_capacity(cmp::min(self.buffer.len(), CHUNK_SIZE)); self.encoder.write(bytes)?;
if let Some(ref mut stream) = self.stream {
self.flags.insert(Flags::RESERVED);
stream.reserve_capacity(cmp::min(self.buffer.len(), CHUNK_SIZE));
}
Ok(WriterState::Pause)
} }
Ok(WriterState::Pause)
} else { } else {
msg.replace_body(body); msg.replace_body(body);
self.buffer_capacity = msg.write_buffer_capacity(); self.buffer_capacity = msg.write_buffer_capacity();
@ -177,10 +185,8 @@ impl<H: 'static> Writer for H2Writer<H> {
} }
fn write_eof(&mut self) -> io::Result<WriterState> { fn write_eof(&mut self) -> io::Result<WriterState> {
self.encoder.write_eof()?;
self.flags.insert(Flags::EOF); self.flags.insert(Flags::EOF);
if !self.encoder.is_eof() { if !self.encoder.write_eof()? {
Err(io::Error::new( Err(io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
"Last payload item, but eof is not reached", "Last payload item, but eof is not reached",