Skip to content

Commit 6e36a6a

Browse files
authored
Merge pull request #97 from http-rs/more-logs
Server encoder state machine
2 parents 030d9d4 + 9fb31d1 commit 6e36a6a

File tree

3 files changed

+150
-118
lines changed

3 files changed

+150
-118
lines changed

src/chunked/encoder.rs

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,37 @@ impl ChunkedEncoder {
7272
buf: &mut [u8],
7373
) -> Poll<io::Result<usize>> {
7474
self.bytes_written = 0;
75+
let res = self.run(res, cx, buf);
76+
log::trace!("ChunkedEncoder {} bytes written", self.bytes_written);
77+
res
78+
}
79+
80+
/// Execute the right method for the current state.
81+
fn run(
82+
&mut self,
83+
res: &mut Response,
84+
cx: &mut Context<'_>,
85+
buf: &mut [u8],
86+
) -> Poll<io::Result<usize>> {
7587
match self.state {
76-
State::Start => self.init(res, cx, buf),
88+
State::Start => self.dispatch(State::EncodeChunks, res, cx, buf),
7789
State::EncodeChunks => self.encode_chunks(res, cx, buf),
7890
State::EndOfChunks => self.encode_chunks_eos(res, cx, buf),
79-
State::ReceiveTrailers => self.encode_trailers(res, cx, buf),
91+
State::ReceiveTrailers => self.receive_trailers(res, cx, buf),
8092
State::EncodeTrailers => self.encode_trailers(res, cx, buf),
81-
State::EndOfStream => self.encode_eos(cx, buf),
82-
State::End => Poll::Ready(Ok(0)),
93+
State::EndOfStream => self.encode_eos(res, cx, buf),
94+
State::End => Poll::Ready(Ok(self.bytes_written)),
8395
}
8496
}
8597

8698
/// Switch the internal state to a new state.
87-
fn set_state(&mut self, state: State) {
99+
fn dispatch(
100+
&mut self,
101+
state: State,
102+
res: &mut Response,
103+
cx: &mut Context<'_>,
104+
buf: &mut [u8],
105+
) -> Poll<io::Result<usize>> {
88106
use State::*;
89107
log::trace!("ChunkedEncoder state: {:?} -> {:?}", self.state, state);
90108

@@ -96,21 +114,11 @@ impl ChunkedEncoder {
96114
ReceiveTrailers => assert!(matches!(state, EncodeTrailers | EndOfStream)),
97115
EncodeTrailers => assert!(matches!(state, EndOfStream)),
98116
EndOfStream => assert!(matches!(state, End)),
99-
End => panic!("No state transitions allowed after the stream has ended"),
117+
End => panic!("No state transitions allowed after the ChunkedEncoder has ended"),
100118
}
101119

102120
self.state = state;
103-
}
104-
105-
/// Init encoding.
106-
fn init(
107-
&mut self,
108-
res: &mut Response,
109-
cx: &mut Context<'_>,
110-
buf: &mut [u8],
111-
) -> Poll<io::Result<usize>> {
112-
self.set_state(State::EncodeChunks);
113-
self.encode_chunks(res, cx, buf)
121+
self.run(res, cx, buf)
114122
}
115123

116124
/// Stream out data using chunked encoding.
@@ -134,8 +142,7 @@ impl ChunkedEncoder {
134142
// If the stream doesn't have any more bytes left to read we're done
135143
// sending chunks and it's time to move on.
136144
if src.len() == 0 {
137-
self.set_state(State::EndOfChunks);
138-
return self.encode_chunks_eos(res, cx, buf);
145+
return self.dispatch(State::EndOfChunks, res, cx, buf);
139146
}
140147

141148
// Each chunk is prefixed with the length of the data in hex, then a
@@ -180,7 +187,6 @@ impl ChunkedEncoder {
180187
self.bytes_written += CRLF_LEN;
181188

182189
// Finally return how many bytes we've written to the buffer.
183-
log::trace!("sending {} bytes", self.bytes_written);
184190
Poll::Ready(Ok(self.bytes_written))
185191
}
186192

@@ -203,8 +209,7 @@ impl ChunkedEncoder {
203209
buf[idx + 2] = LF;
204210
self.bytes_written += 1 + CRLF_LEN;
205211

206-
self.set_state(State::ReceiveTrailers);
207-
return self.receive_trailers(res, cx, buf);
212+
self.dispatch(State::ReceiveTrailers, res, cx, buf)
208213
}
209214

210215
/// Receive trailers sent to the response, and store them in an internal
@@ -216,31 +221,32 @@ impl ChunkedEncoder {
216221
buf: &mut [u8],
217222
) -> Poll<io::Result<usize>> {
218223
// TODO: actually wait for trailers to be received.
219-
self.set_state(State::EncodeTrailers);
220-
self.encode_trailers(res, cx, buf)
224+
self.dispatch(State::EncodeTrailers, res, cx, buf)
221225
}
222226

223227
/// Send trailers to the buffer.
224228
fn encode_trailers(
225229
&mut self,
226-
_res: &mut Response,
230+
res: &mut Response,
227231
cx: &mut Context<'_>,
228232
buf: &mut [u8],
229233
) -> Poll<io::Result<usize>> {
230234
// TODO: actually encode trailers here.
231-
self.set_state(State::EndOfStream);
232-
self.encode_eos(cx, buf)
235+
self.dispatch(State::EndOfStream, res, cx, buf)
233236
}
234237

235238
/// Encode the end of the stream.
236-
fn encode_eos(&mut self, _cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<io::Result<usize>> {
239+
fn encode_eos(
240+
&mut self,
241+
res: &mut Response,
242+
cx: &mut Context<'_>,
243+
buf: &mut [u8],
244+
) -> Poll<io::Result<usize>> {
237245
let idx = self.bytes_written;
238246
// Write the final CRLF
239247
buf[idx] = CR;
240248
buf[idx + 1] = LF;
241249
self.bytes_written += CRLF_LEN;
242-
243-
self.set_state(State::End);
244-
return Poll::Ready(Ok(self.bytes_written));
250+
self.dispatch(State::End, res, cx, buf)
245251
}
246252
}

0 commit comments

Comments
 (0)