Skip to content

Commit 1f9cb09

Browse files
committed
Some fixes for chunked
1 parent 41437aa commit 1f9cb09

File tree

1 file changed

+37
-23
lines changed

1 file changed

+37
-23
lines changed

src/server.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ impl Encoder {
116116

117117
let reason = self.res.status().canonical_reason();
118118
let status = self.res.status();
119-
std::io::Write::write_fmt(&mut head, format_args!("HTTP/1.1 {} {}\r\n", status, reason))?;
119+
std::io::Write::write_fmt(
120+
&mut head,
121+
format_args!("HTTP/1.1 {} {}\r\n", status, reason),
122+
)?;
120123

121124
// If the body isn't streaming, we can set the content-length ahead of time. Else we need to
122125
// send all items in chunks.
@@ -127,7 +130,10 @@ impl Encoder {
127130
}
128131

129132
for (header, value) in self.res.headers().iter() {
130-
std::io::Write::write_fmt(&mut head, format_args!("{}: {}\r\n", header.as_str(), value))?
133+
std::io::Write::write_fmt(
134+
&mut head,
135+
format_args!("{}: {}\r\n", header.as_str(), value),
136+
)?
131137
}
132138

133139
std::io::Write::write_fmt(&mut head, format_args!("\r\n"))?;
@@ -148,8 +154,8 @@ impl Read for Encoder {
148154
self.encode_head()?;
149155
}
150156

151-
// Send the headers. As long as the headers aren't fully sent yet we
152-
// keep sending more of the headers.
157+
// we must keep track how many bytes of the head and body we've read
158+
// in this call of `poll_read`
153159
let mut head_bytes_read = 0;
154160
let mut body_bytes_read = 0;
155161

@@ -167,44 +173,52 @@ impl Read for Encoder {
167173
head_bytes_read += len;
168174
}
169175

170-
// Read from the AsyncRead impl on the inner Response struct.
176+
// Read from the AsyncRead impl on the inner Response struct only if
177+
// done reading from the head.
171178
// We must ensure there's space to write at least 2 bytes into the
172179
// response stream.
173-
if !self.body_done && head_bytes_read < (buf.len() + 1) {
180+
if self.head_done && !self.body_done && head_bytes_read <= buf.len() - 2 {
174181
// figure out how many bytes we can read. If a len was set, we need
175182
// to make sure we don't read more than that.
176183
let upper_bound = match self.res.len() {
177-
Some(len) => (head_bytes_read + len - self.body_bytes_read).min(buf.len()),
184+
Some(len) => {
185+
debug_assert!(head_bytes_read == 0 || self.body_bytes_read == 0);
186+
(head_bytes_read + len - self.body_bytes_read).min(buf.len())
187+
}
178188
None => buf.len() - 2,
179189
};
180190

181191
// Read bytes, and update internal tracking stuff.
182-
let n = ready!(Pin::new(&mut self.res).poll_read(cx, &mut buf[head_bytes_read..upper_bound]))?;
183-
body_bytes_read += n; // body bytes read on this poll
184-
self.body_bytes_read += n; // total body bytes read on all polls
192+
body_bytes_read = ready!(
193+
Pin::new(&mut self.res).poll_read(cx, &mut buf[head_bytes_read..upper_bound])
194+
)?;
195+
self.body_bytes_read += body_bytes_read; // total body bytes read on all polls
185196

186197
match self.res.len() {
187-
Some(len) => {
188-
if len == self.body_bytes_read {
189-
self.body_done = true;
190-
}
191-
debug_assert!(self.body_bytes_read <= len, "Too many bytes read. Expected: {}, read: {}", len, self.body_bytes_read);
192-
193-
// If our stream no longer gives bytes, end.
194-
if body_bytes_read == 0 {
198+
Some(len) => {
199+
debug_assert!(
200+
self.body_bytes_read <= len,
201+
"Too many bytes read. Expected: {}, read: {}",
202+
len,
203+
self.body_bytes_read
204+
);
205+
// If we've read the `len` number of bytes or the stream no longer gives bytes, end.
206+
if len == self.body_bytes_read || body_bytes_read == 0 {
195207
self.body_done = true;
196208
}
197209
}
198210
None => {
199-
debug_assert!(buf.len() >= 4, "Buffers should be at least 4 bytes long when using chunked encoding");
211+
// TODO: relax this constraint at some point by adding extra state
212+
let bytes_read = head_bytes_read + body_bytes_read;
213+
assert!(buf.len() >= bytes_read + 4, "Buffers should have room for the head, the body, and 4 extra bytes when using chunked encoding");
200214

201-
buf[n] = b'\r';
202-
buf[n + 1] = b'\n';
215+
buf[bytes_read] = b'\r';
216+
buf[bytes_read + 1] = b'\n';
203217

204218
if body_bytes_read == 0 {
205219
self.body_done = true;
206-
buf[2] = b'\r';
207-
buf[3] = b'\n';
220+
buf[bytes_read + 2] = b'\r';
221+
buf[bytes_read + 3] = b'\n';
208222
}
209223
}
210224
}

0 commit comments

Comments
 (0)