diff --git a/CHANGES.md b/CHANGES.md index ad84784dc..39f763b5b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,8 @@ ### Fixed +* http/2 end-of-frame is not set if body is empty bytes #307 + * InternalError can trigger memory unsafety #301 * Fix docs.rs build diff --git a/src/server/h2writer.rs b/src/server/h2writer.rs index 5fc13154a..363ef5e7b 100644 --- a/src/server/h2writer.rs +++ b/src/server/h2writer.rs @@ -89,9 +89,6 @@ impl Writer for H2Writer { self.flags.insert(Flags::STARTED); self.encoder = ContentEncoder::for_server(self.buffer.clone(), req, msg, encoding); - if let Body::Empty = *msg.body() { - self.flags.insert(Flags::EOF); - } // http2 specific msg.headers_mut().remove(CONNECTION); @@ -108,15 +105,22 @@ impl Writer for H2Writer { let body = msg.replace_body(Body::Empty); match body { Body::Binary(ref bytes) => { - 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(), - ); + if bytes.is_empty() { + msg.headers_mut() + .insert(CONTENT_LENGTH, HeaderValue::from_static("0")); + self.flags.insert(Flags::EOF); + } else { + 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 => { + self.flags.insert(Flags::EOF); msg.headers_mut() .insert(CONTENT_LENGTH, HeaderValue::from_static("0")); } @@ -141,14 +145,18 @@ impl Writer for H2Writer { trace!("Response: {:?}", msg); if let Body::Binary(bytes) = body { - self.flags.insert(Flags::EOF); - self.written = bytes.len() as u64; - 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)); + if bytes.is_empty() { + Ok(WriterState::Done) + } else { + self.flags.insert(Flags::EOF); + self.written = bytes.len() as u64; + 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 { msg.replace_body(body); self.buffer_capacity = msg.write_buffer_capacity(); @@ -177,10 +185,8 @@ impl Writer for H2Writer { } fn write_eof(&mut self) -> io::Result { - self.encoder.write_eof()?; - self.flags.insert(Flags::EOF); - if !self.encoder.is_eof() { + if !self.encoder.write_eof()? { Err(io::Error::new( io::ErrorKind::Other, "Last payload item, but eof is not reached",