@@ -8,7 +8,7 @@ use std::time::Duration;
88
99use crate :: rt:: { Read , Write } ;
1010use bytes:: { Buf , Bytes } ;
11- use http:: header:: { HeaderValue , CONNECTION } ;
11+ use http:: header:: { HeaderValue , CONNECTION , TE } ;
1212use http:: { HeaderMap , Method , Version } ;
1313use httparse:: ParserConfig ;
1414
7575 // We assume a modern world where the remote speaks HTTP/1.1.
7676 // If they tell us otherwise, we'll downgrade in `read_head`.
7777 version : Version :: HTTP_11 ,
78+ allow_trailer_fields : false ,
7879 } ,
7980 _marker : PhantomData ,
8081 }
@@ -264,6 +265,13 @@ where
264265 self . state . reading = Reading :: Body ( Decoder :: new ( msg. decode ) ) ;
265266 }
266267
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+
267275 Poll :: Ready ( Some ( Ok ( ( msg. head , msg. decode , wants) ) ) )
268276 }
269277
@@ -640,6 +648,31 @@ where
640648 self . state . writing = state;
641649 }
642650
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+
643676 pub ( crate ) fn write_body_and_end ( & mut self , chunk : B ) {
644677 debug_assert ! ( self . can_write_body( ) && self . can_buffer_body( ) ) ;
645678 // empty chunks should be discarded at Dispatcher level
@@ -842,6 +875,8 @@ struct State {
842875 upgrade : Option < crate :: upgrade:: Pending > ,
843876 /// Either HTTP/1.0 or 1.1 connection
844877 version : Version ,
878+ /// Flag to track if trailer fields are allowed to be sent
879+ allow_trailer_fields : bool ,
845880}
846881
847882#[ derive( Debug ) ]
0 commit comments