Skip to content

Commit

Permalink
Merge pull request #85 from rmja/fix-exact-write
Browse files Browse the repository at this point in the history
Fix exact write
  • Loading branch information
rmja authored Jul 2, 2024
2 parents 51d1b46 + 31e21d6 commit a3ce81a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
### Fixes

* Fix bug where buffering chunked body writer could return `Ok(0)` on calls to `write()` ([#81](https://github.com/drogue-iot/reqwless/pull/81))
* Fix bug in buffering chunked body writer where a call to `write()` with a buffer length exactly matching the remaining size of the remainder of the current chunk causes the entire chunk to be discarded ([#85](https://github.com/drogue-iot/reqwless/pull/85))

## v0.12 (2024-05-23)

Expand Down
27 changes: 24 additions & 3 deletions src/body_writer/buffering_chunked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ where
self.pos = self.header_pos + self.allocated_header;
}

fn current_chunk_is_full(&self) -> bool {
self.pos + NEWLINE.len() == self.buf.len()
}

async fn emit_buffered(&mut self) -> Result<(), C::Error> {
self.conn.write_all(&self.buf[..self.header_pos]).await?;
self.header_pos = 0;
Expand Down Expand Up @@ -149,7 +153,7 @@ where
self.emit_buffered().await.map_err(|e| e.kind())?;
written = self.append_current_chunk(buf);
}
if written < buf.len() {
if self.current_chunk_is_full() {
self.finish_current_chunk();
self.emit_buffered().await.map_err(|e| e.kind())?;
}
Expand Down Expand Up @@ -330,19 +334,36 @@ mod tests {
}

#[tokio::test]
async fn current_chunk_is_emitted_before_empty_chunk_is_emitted() {
async fn written_bytes_fit_exactly() {
// Given
let mut conn = Vec::new();
let mut buf = [0; 14];
buf[..5].copy_from_slice(b"HELLO");

// When
let mut writer = BufferingChunkedBodyWriter::new_with_data(&mut conn, &mut buf, 5);
writer.write_all(b"BODY").await.unwrap(); // Can fit exactly
writer.write_all(b"BODY").await.unwrap(); // Can fit
writer.terminate().await.unwrap(); // Can fit

// Then
assert_eq!(b"HELLO4\r\nBODY\r\n4\r\nBODY\r\n0\r\n\r\n", conn.as_slice());
}

#[tokio::test]
async fn current_chunk_is_emitted_on_termination_before_empty_chunk_is_emitted() {
// Given
let mut conn = Vec::new();
let mut buf = [0; 14];
buf[..5].copy_from_slice(b"HELLO");

// When
let mut writer = BufferingChunkedBodyWriter::new_with_data(&mut conn, &mut buf, 5);
writer.write_all(b"BOD").await.unwrap(); // Can fit
writer.terminate().await.unwrap(); // Cannot fit

// Then
assert_eq!(b"HELLO4\r\nBODY\r\n0\r\n\r\n", conn.as_slice());
assert_eq!(b"HELLO3\r\nBOD\r\n0\r\n\r\n", conn.as_slice());
}

#[tokio::test]
Expand Down

0 comments on commit a3ce81a

Please sign in to comment.