@@ -8,7 +8,7 @@ use std::time::Duration;
8
8
9
9
use crate :: rt:: { Read , Write } ;
10
10
use bytes:: { Buf , Bytes } ;
11
- use http:: header:: { HeaderValue , CONNECTION } ;
11
+ use http:: header:: { HeaderValue , CONNECTION , TE } ;
12
12
use http:: { HeaderMap , Method , Version } ;
13
13
use httparse:: ParserConfig ;
14
14
75
75
// We assume a modern world where the remote speaks HTTP/1.1.
76
76
// If they tell us otherwise, we'll downgrade in `read_head`.
77
77
version : Version :: HTTP_11 ,
78
+ allow_trailer_fields : false ,
78
79
} ,
79
80
_marker : PhantomData ,
80
81
}
@@ -264,6 +265,13 @@ where
264
265
self . state . reading = Reading :: Body ( Decoder :: new ( msg. decode ) ) ;
265
266
}
266
267
268
+ self . state . allow_trailer_fields = msg
269
+ . head
270
+ . headers
271
+ . get ( TE )
272
+ . map ( |te_header| te_header == "trailers" )
273
+ . unwrap_or ( false ) ;
274
+
267
275
Poll :: Ready ( Some ( Ok ( ( msg. head , msg. decode , wants) ) ) )
268
276
}
269
277
@@ -640,6 +648,31 @@ where
640
648
self . state . writing = state;
641
649
}
642
650
651
+ pub ( crate ) fn write_trailers ( & mut self , trailers : HeaderMap ) {
652
+ if T :: is_server ( ) && self . state . allow_trailer_fields == false {
653
+ debug ! ( "trailers not allowed to be sent" ) ;
654
+ return ;
655
+ }
656
+ debug_assert ! ( self . can_write_body( ) && self . can_buffer_body( ) ) ;
657
+
658
+ match self . state . writing {
659
+ Writing :: Body ( ref encoder) => {
660
+ if let Some ( enc_buf) =
661
+ encoder. encode_trailers ( trailers, self . state . title_case_headers )
662
+ {
663
+ self . io . buffer ( enc_buf) ;
664
+
665
+ self . state . writing = if encoder. is_last ( ) || encoder. is_close_delimited ( ) {
666
+ Writing :: Closed
667
+ } else {
668
+ Writing :: KeepAlive
669
+ } ;
670
+ }
671
+ }
672
+ _ => unreachable ! ( "write_trailers invalid state: {:?}" , self . state. writing) ,
673
+ }
674
+ }
675
+
643
676
pub ( crate ) fn write_body_and_end ( & mut self , chunk : B ) {
644
677
debug_assert ! ( self . can_write_body( ) && self . can_buffer_body( ) ) ;
645
678
// empty chunks should be discarded at Dispatcher level
@@ -842,6 +875,8 @@ struct State {
842
875
upgrade : Option < crate :: upgrade:: Pending > ,
843
876
/// Either HTTP/1.0 or 1.1 connection
844
877
version : Version ,
878
+ /// Flag to track if trailer fields are allowed to be sent
879
+ allow_trailer_fields : bool ,
845
880
}
846
881
847
882
#[ derive( Debug ) ]
0 commit comments