Skip to content

Commit 1c3fbfd

Browse files
sfacklerseanmonstar
authored andcommitted
feat(h2): implement flow control for h2 bodies
Closes #1548
1 parent 386fc0d commit 1c3fbfd

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

src/proto/h2/mod.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,20 +103,21 @@ where
103103
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
104104
loop {
105105
if !self.data_done {
106-
// TODO: make use of flow control on SendStream
107-
// If you're looking at this and thinking of trying to fix this TODO,
108-
// you may want to look at:
109-
// https://docs.rs/h2/0.1.*/h2/struct.SendStream.html
110-
//
111-
// With that doc open, we'd want to do these things:
112-
// - check self.body_tx.capacity() to see if we can send *any* data
113-
// - if > 0:
114-
// - poll self.stream
115-
// - reserve chunk.len() more capacity (because its about to be used)?
116-
// - send the chunk
117-
// - else:
118-
// - try reserve a smallish amount of capacity
119-
// - call self.body_tx.poll_capacity(), return if NotReady
106+
// we don't have the next chunk of data yet, so just reserve 1 byte to make
107+
// sure there's some capacity available. h2 will handle the capacity management
108+
// for the actual body chunk.
109+
self.body_tx.reserve_capacity(1);
110+
111+
if self.body_tx.capacity() == 0 {
112+
loop {
113+
match try_ready!(self.body_tx.poll_capacity().map_err(::Error::new_h2)) {
114+
Some(0) => {}
115+
Some(_) => break,
116+
None => return Err(::Error::new_canceled(None::<::Error>)),
117+
}
118+
}
119+
}
120+
120121
match try_ready!(self.stream.poll_data().map_err(|e| self.on_err(e))) {
121122
Some(chunk) => {
122123
let is_eos = self.stream.is_end_stream();
@@ -136,6 +137,7 @@ where
136137
}
137138
}
138139
None => {
140+
self.body_tx.reserve_capacity(0);
139141
let is_eos = self.stream.is_end_stream();
140142
if is_eos {
141143
return self.send_eos_frame().map(Async::Ready);

0 commit comments

Comments
 (0)