@@ -3,7 +3,7 @@ use std::borrow::Cow;
3
3
use std:: fmt;
4
4
5
5
use bytes:: Bytes ;
6
- use futures:: { Async , Future , Poll , Stream , StreamExt } ;
6
+ use futures:: { Async , Future , Never , Poll , Stream , StreamExt } ;
7
7
use futures:: task;
8
8
use futures:: channel:: { mpsc, oneshot} ;
9
9
use http:: HeaderMap ;
@@ -125,6 +125,15 @@ impl<E: Entity> Stream for EntityStream<E> {
125
125
#[ must_use = "streams do nothing unless polled" ]
126
126
pub struct Body {
127
127
kind : Kind ,
128
+ /// Allow the client to pass a future to delay the `Body` from returning
129
+ /// EOF. This allows the `Client` to try to put the idle connection
130
+ /// back into the pool before the body is "finished".
131
+ ///
132
+ /// The reason for this is so that creating a new request after finishing
133
+ /// streaming the body of a response could sometimes result in creating
134
+ /// a brand new connection, since the pool didn't know about the idle
135
+ /// connection yet.
136
+ delayed_eof : Option < DelayEof > ,
128
137
}
129
138
130
139
enum Kind {
@@ -137,6 +146,17 @@ enum Kind {
137
146
Empty ,
138
147
}
139
148
149
+ type DelayEofUntil = oneshot:: Receiver < Never > ;
150
+
151
+ enum DelayEof {
152
+ /// Initial state, stream hasn't seen EOF yet.
153
+ NotEof ( DelayEofUntil ) ,
154
+ /// Transitions to this state once we've seen `poll` try to
155
+ /// return EOF (`None`). This future is then polled, and
156
+ /// when it completes, the Body finally returns EOF (`None`).
157
+ Eof ( DelayEofUntil ) ,
158
+ }
159
+
140
160
/// A sender half used with `Body::channel()`.
141
161
#[ derive( Debug ) ]
142
162
pub struct Sender {
@@ -253,22 +273,53 @@ impl Body {
253
273
fn new ( kind : Kind ) -> Body {
254
274
Body {
255
275
kind : kind,
276
+ delayed_eof : None ,
256
277
}
257
278
}
258
- }
259
279
260
- impl Default for Body {
261
- #[ inline]
262
- fn default ( ) -> Body {
263
- Body :: empty ( )
280
+ pub ( crate ) fn delayed_eof ( & mut self , fut : DelayEofUntil ) {
281
+ self . delayed_eof = Some ( DelayEof :: NotEof ( fut) ) ;
264
282
}
265
- }
266
283
267
- impl Entity for Body {
268
- type Data = Chunk ;
269
- type Error = :: Error ;
284
+ fn poll_eof ( & mut self , cx : & mut task:: Context ) -> Poll < Option < Chunk > , :: Error > {
285
+ match self . delayed_eof . take ( ) {
286
+ Some ( DelayEof :: NotEof ( mut delay) ) => {
287
+ match self . poll_inner ( cx) {
288
+ ok @ Ok ( Async :: Ready ( Some ( ..) ) ) |
289
+ ok @ Ok ( Async :: Pending ) => {
290
+ self . delayed_eof = Some ( DelayEof :: NotEof ( delay) ) ;
291
+ ok
292
+ } ,
293
+ Ok ( Async :: Ready ( None ) ) => match delay. poll ( cx) {
294
+ Ok ( Async :: Ready ( never) ) => match never { } ,
295
+ Ok ( Async :: Pending ) => {
296
+ self . delayed_eof = Some ( DelayEof :: Eof ( delay) ) ;
297
+ Ok ( Async :: Pending )
298
+ } ,
299
+ Err ( _done) => {
300
+ Ok ( Async :: Ready ( None ) )
301
+ } ,
302
+ } ,
303
+ Err ( e) => Err ( e) ,
304
+ }
305
+ } ,
306
+ Some ( DelayEof :: Eof ( mut delay) ) => {
307
+ match delay. poll ( cx) {
308
+ Ok ( Async :: Ready ( never) ) => match never { } ,
309
+ Ok ( Async :: Pending ) => {
310
+ self . delayed_eof = Some ( DelayEof :: Eof ( delay) ) ;
311
+ Ok ( Async :: Pending )
312
+ } ,
313
+ Err ( _done) => {
314
+ Ok ( Async :: Ready ( None ) )
315
+ } ,
316
+ }
317
+ } ,
318
+ None => self . poll_inner ( cx) ,
319
+ }
320
+ }
270
321
271
- fn poll_data ( & mut self , cx : & mut task:: Context ) -> Poll < Option < Self :: Data > , Self :: Error > {
322
+ fn poll_inner ( & mut self , cx : & mut task:: Context ) -> Poll < Option < Chunk > , :: Error > {
272
323
match self . kind {
273
324
Kind :: Chan { ref mut rx, .. } => match rx. poll_next ( cx) . expect ( "mpsc cannot error" ) {
274
325
Async :: Ready ( Some ( Ok ( chunk) ) ) => Ok ( Async :: Ready ( Some ( chunk) ) ) ,
@@ -281,6 +332,22 @@ impl Entity for Body {
281
332
Kind :: Empty => Ok ( Async :: Ready ( None ) ) ,
282
333
}
283
334
}
335
+ }
336
+
337
+ impl Default for Body {
338
+ #[ inline]
339
+ fn default ( ) -> Body {
340
+ Body :: empty ( )
341
+ }
342
+ }
343
+
344
+ impl Entity for Body {
345
+ type Data = Chunk ;
346
+ type Error = :: Error ;
347
+
348
+ fn poll_data ( & mut self , cx : & mut task:: Context ) -> Poll < Option < Self :: Data > , Self :: Error > {
349
+ self . poll_eof ( cx)
350
+ }
284
351
285
352
fn is_end_stream ( & self ) -> bool {
286
353
match self . kind {
@@ -300,6 +367,7 @@ impl Entity for Body {
300
367
Kind :: Empty => Some ( 0 )
301
368
}
302
369
}
370
+
303
371
}
304
372
305
373
impl fmt:: Debug for Body {
0 commit comments