@@ -9,6 +9,14 @@ use std::future::Future;
9
9
use std:: pin:: Pin ;
10
10
use std:: task:: { Context , Poll } ;
11
11
12
+ #[ cfg( any(
13
+ feature = "gzip" ,
14
+ feature = "zstd" ,
15
+ feature = "brotli" ,
16
+ feature = "deflate"
17
+ ) ) ]
18
+ use futures_util:: stream:: Fuse ;
19
+
12
20
#[ cfg( feature = "gzip" ) ]
13
21
use async_compression:: tokio:: bufread:: GzipDecoder ;
14
22
@@ -108,19 +116,19 @@ enum Inner {
108
116
109
117
/// A `Gzip` decoder will uncompress the gzipped response content before returning it.
110
118
#[ cfg( feature = "gzip" ) ]
111
- Gzip ( Pin < Box < FramedRead < GzipDecoder < PeekableIoStreamReader > , BytesCodec > > > ) ,
119
+ Gzip ( Pin < Box < Fuse < FramedRead < GzipDecoder < PeekableIoStreamReader > , BytesCodec > > > > ) ,
112
120
113
121
/// A `Brotli` decoder will uncompress the brotlied response content before returning it.
114
122
#[ cfg( feature = "brotli" ) ]
115
- Brotli ( Pin < Box < FramedRead < BrotliDecoder < PeekableIoStreamReader > , BytesCodec > > > ) ,
123
+ Brotli ( Pin < Box < Fuse < FramedRead < BrotliDecoder < PeekableIoStreamReader > , BytesCodec > > > > ) ,
116
124
117
125
/// A `Zstd` decoder will uncompress the zstd compressed response content before returning it.
118
126
#[ cfg( feature = "zstd" ) ]
119
- Zstd ( Pin < Box < FramedRead < ZstdDecoder < PeekableIoStreamReader > , BytesCodec > > > ) ,
127
+ Zstd ( Pin < Box < Fuse < FramedRead < ZstdDecoder < PeekableIoStreamReader > , BytesCodec > > > > ) ,
120
128
121
129
/// A `Deflate` decoder will uncompress the deflated response content before returning it.
122
130
#[ cfg( feature = "deflate" ) ]
123
- Deflate ( Pin < Box < FramedRead < ZlibDecoder < PeekableIoStreamReader > , BytesCodec > > > ) ,
131
+ Deflate ( Pin < Box < Fuse < FramedRead < ZlibDecoder < PeekableIoStreamReader > , BytesCodec > > > > ) ,
124
132
125
133
/// A decoder that doesn't have a value yet.
126
134
#[ cfg( any(
@@ -365,34 +373,74 @@ impl HttpBody for Decoder {
365
373
}
366
374
#[ cfg( feature = "gzip" ) ]
367
375
Inner :: Gzip ( ref mut decoder) => {
368
- match futures_core:: ready!( Pin :: new( decoder) . poll_next( cx) ) {
376
+ match futures_core:: ready!( Pin :: new( & mut * decoder) . poll_next( cx) ) {
369
377
Some ( Ok ( bytes) ) => Poll :: Ready ( Some ( Ok ( Frame :: data ( bytes. freeze ( ) ) ) ) ) ,
370
378
Some ( Err ( err) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode_io ( err) ) ) ) ,
371
- None => Poll :: Ready ( None ) ,
379
+ None => {
380
+ // poll inner connection until EOF after gzip stream is finished
381
+ let inner_stream = decoder. get_mut ( ) . get_mut ( ) . get_mut ( ) . get_mut ( ) ;
382
+ match futures_core:: ready!( Pin :: new( inner_stream) . poll_next( cx) ) {
383
+ Some ( Ok ( _) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode (
384
+ "there are extra bytes after body has been decompressed" ,
385
+ ) ) ) ) ,
386
+ Some ( Err ( err) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode_io ( err) ) ) ) ,
387
+ None => Poll :: Ready ( None ) ,
388
+ }
389
+ }
372
390
}
373
391
}
374
392
#[ cfg( feature = "brotli" ) ]
375
393
Inner :: Brotli ( ref mut decoder) => {
376
- match futures_core:: ready!( Pin :: new( decoder) . poll_next( cx) ) {
394
+ match futures_core:: ready!( Pin :: new( & mut * decoder) . poll_next( cx) ) {
377
395
Some ( Ok ( bytes) ) => Poll :: Ready ( Some ( Ok ( Frame :: data ( bytes. freeze ( ) ) ) ) ) ,
378
396
Some ( Err ( err) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode_io ( err) ) ) ) ,
379
- None => Poll :: Ready ( None ) ,
397
+ None => {
398
+ // poll inner connection until EOF after brotli stream is finished
399
+ let inner_stream = decoder. get_mut ( ) . get_mut ( ) . get_mut ( ) . get_mut ( ) ;
400
+ match futures_core:: ready!( Pin :: new( inner_stream) . poll_next( cx) ) {
401
+ Some ( Ok ( _) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode (
402
+ "there are extra bytes after body has been decompressed" ,
403
+ ) ) ) ) ,
404
+ Some ( Err ( err) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode_io ( err) ) ) ) ,
405
+ None => Poll :: Ready ( None ) ,
406
+ }
407
+ }
380
408
}
381
409
}
382
410
#[ cfg( feature = "zstd" ) ]
383
411
Inner :: Zstd ( ref mut decoder) => {
384
- match futures_core:: ready!( Pin :: new( decoder) . poll_next( cx) ) {
412
+ match futures_core:: ready!( Pin :: new( & mut * decoder) . poll_next( cx) ) {
385
413
Some ( Ok ( bytes) ) => Poll :: Ready ( Some ( Ok ( Frame :: data ( bytes. freeze ( ) ) ) ) ) ,
386
414
Some ( Err ( err) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode_io ( err) ) ) ) ,
387
- None => Poll :: Ready ( None ) ,
415
+ None => {
416
+ // poll inner connection until EOF after zstd stream is finished
417
+ let inner_stream = decoder. get_mut ( ) . get_mut ( ) . get_mut ( ) . get_mut ( ) ;
418
+ match futures_core:: ready!( Pin :: new( inner_stream) . poll_next( cx) ) {
419
+ Some ( Ok ( _) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode (
420
+ "there are extra bytes after body has been decompressed" ,
421
+ ) ) ) ) ,
422
+ Some ( Err ( err) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode_io ( err) ) ) ) ,
423
+ None => Poll :: Ready ( None ) ,
424
+ }
425
+ }
388
426
}
389
427
}
390
428
#[ cfg( feature = "deflate" ) ]
391
429
Inner :: Deflate ( ref mut decoder) => {
392
- match futures_core:: ready!( Pin :: new( decoder) . poll_next( cx) ) {
430
+ match futures_core:: ready!( Pin :: new( & mut * decoder) . poll_next( cx) ) {
393
431
Some ( Ok ( bytes) ) => Poll :: Ready ( Some ( Ok ( Frame :: data ( bytes. freeze ( ) ) ) ) ) ,
394
432
Some ( Err ( err) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode_io ( err) ) ) ) ,
395
- None => Poll :: Ready ( None ) ,
433
+ None => {
434
+ // poll inner connection until EOF after deflate stream is finished
435
+ let inner_stream = decoder. get_mut ( ) . get_mut ( ) . get_mut ( ) . get_mut ( ) ;
436
+ match futures_core:: ready!( Pin :: new( inner_stream) . poll_next( cx) ) {
437
+ Some ( Ok ( _) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode (
438
+ "there are extra bytes after body has been decompressed" ,
439
+ ) ) ) ) ,
440
+ Some ( Err ( err) ) => Poll :: Ready ( Some ( Err ( crate :: error:: decode_io ( err) ) ) ) ,
441
+ None => Poll :: Ready ( None ) ,
442
+ }
443
+ }
396
444
}
397
445
}
398
446
}
@@ -456,25 +504,37 @@ impl Future for Pending {
456
504
457
505
match self . 1 {
458
506
#[ cfg( feature = "brotli" ) ]
459
- DecoderType :: Brotli => Poll :: Ready ( Ok ( Inner :: Brotli ( Box :: pin ( FramedRead :: new (
460
- BrotliDecoder :: new ( StreamReader :: new ( _body) ) ,
461
- BytesCodec :: new ( ) ,
462
- ) ) ) ) ) ,
507
+ DecoderType :: Brotli => Poll :: Ready ( Ok ( Inner :: Brotli ( Box :: pin (
508
+ FramedRead :: new (
509
+ BrotliDecoder :: new ( StreamReader :: new ( _body) ) ,
510
+ BytesCodec :: new ( ) ,
511
+ )
512
+ . fuse ( ) ,
513
+ ) ) ) ) ,
463
514
#[ cfg( feature = "zstd" ) ]
464
- DecoderType :: Zstd => Poll :: Ready ( Ok ( Inner :: Zstd ( Box :: pin ( FramedRead :: new (
465
- ZstdDecoder :: new ( StreamReader :: new ( _body) ) ,
466
- BytesCodec :: new ( ) ,
467
- ) ) ) ) ) ,
515
+ DecoderType :: Zstd => Poll :: Ready ( Ok ( Inner :: Zstd ( Box :: pin (
516
+ FramedRead :: new (
517
+ ZstdDecoder :: new ( StreamReader :: new ( _body) ) ,
518
+ BytesCodec :: new ( ) ,
519
+ )
520
+ . fuse ( ) ,
521
+ ) ) ) ) ,
468
522
#[ cfg( feature = "gzip" ) ]
469
- DecoderType :: Gzip => Poll :: Ready ( Ok ( Inner :: Gzip ( Box :: pin ( FramedRead :: new (
470
- GzipDecoder :: new ( StreamReader :: new ( _body) ) ,
471
- BytesCodec :: new ( ) ,
472
- ) ) ) ) ) ,
523
+ DecoderType :: Gzip => Poll :: Ready ( Ok ( Inner :: Gzip ( Box :: pin (
524
+ FramedRead :: new (
525
+ GzipDecoder :: new ( StreamReader :: new ( _body) ) ,
526
+ BytesCodec :: new ( ) ,
527
+ )
528
+ . fuse ( ) ,
529
+ ) ) ) ) ,
473
530
#[ cfg( feature = "deflate" ) ]
474
- DecoderType :: Deflate => Poll :: Ready ( Ok ( Inner :: Deflate ( Box :: pin ( FramedRead :: new (
475
- ZlibDecoder :: new ( StreamReader :: new ( _body) ) ,
476
- BytesCodec :: new ( ) ,
477
- ) ) ) ) ) ,
531
+ DecoderType :: Deflate => Poll :: Ready ( Ok ( Inner :: Deflate ( Box :: pin (
532
+ FramedRead :: new (
533
+ ZlibDecoder :: new ( StreamReader :: new ( _body) ) ,
534
+ BytesCodec :: new ( ) ,
535
+ )
536
+ . fuse ( ) ,
537
+ ) ) ) ) ,
478
538
}
479
539
}
480
540
}
0 commit comments