1
1
use bytes:: Buf ;
2
2
use futures:: { Async , Future , Poll } ;
3
3
use h2:: { Reason , SendStream } ;
4
+ use http:: header:: {
5
+ HeaderName , CONNECTION , PROXY_AUTHENTICATE , PROXY_AUTHORIZATION , TE , TRAILER ,
6
+ TRANSFER_ENCODING , UPGRADE ,
7
+ } ;
4
8
use http:: HeaderMap ;
5
- use http:: header:: { CONNECTION , TRANSFER_ENCODING } ;
6
9
7
- use :: body:: Payload ;
10
+ use body:: Payload ;
8
11
9
12
mod client;
10
13
mod server;
@@ -13,13 +16,42 @@ pub(crate) use self::client::Client;
13
16
pub ( crate ) use self :: server:: Server ;
14
17
15
18
fn strip_connection_headers ( headers : & mut HeaderMap ) {
16
- if headers. remove ( TRANSFER_ENCODING ) . is_some ( ) {
17
- trace ! ( "removed illegal Transfer-Encoding header" ) ;
19
+ // List of connection headers from:
20
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
21
+ let connection_headers = [
22
+ HeaderName :: from_lowercase ( b"keep-alive" ) . unwrap ( ) ,
23
+ HeaderName :: from_lowercase ( b"proxy-connection" ) . unwrap ( ) ,
24
+ PROXY_AUTHENTICATE ,
25
+ PROXY_AUTHORIZATION ,
26
+ TE ,
27
+ TRAILER ,
28
+ TRANSFER_ENCODING ,
29
+ UPGRADE ,
30
+ ] ;
31
+
32
+ for header in connection_headers. iter ( ) {
33
+ if headers. remove ( header) . is_some ( ) {
34
+ warn ! ( "Connection header illegal in HTTP/2: {}" , header. as_str( ) ) ;
35
+ }
18
36
}
19
- if headers. contains_key ( CONNECTION ) {
20
- warn ! ( "Connection header illegal in HTTP/2" ) ;
21
- //TODO: actually remove it, after checking the value
22
- //and removing all related headers
37
+
38
+ if let Some ( header) = headers. remove ( CONNECTION ) {
39
+ warn ! (
40
+ "Connection header illegal in HTTP/2: {}" ,
41
+ CONNECTION . as_str( )
42
+ ) ;
43
+ let header_contents = header. to_str ( ) . unwrap ( ) ;
44
+
45
+ // A `Connection` header may have a comma-separated list of names of other headers that
46
+ // are meant for only this specific connection.
47
+ //
48
+ // Iterate these names and remove them as headers. Connection-specific headers are
49
+ // forbidden in HTTP2, as that information has been moved into frame types of the h2
50
+ // protocol.
51
+ for name in header_contents. split ( ',' ) {
52
+ let name = name. trim ( ) ;
53
+ headers. remove ( name) ;
54
+ }
23
55
}
24
56
}
25
57
55
87
56
88
fn send_eos_frame ( & mut self ) -> :: Result < ( ) > {
57
89
trace ! ( "send body eos" ) ;
58
- self . body_tx . send_data ( SendBuf ( None ) , true )
90
+ self . body_tx
91
+ . send_data ( SendBuf ( None ) , true )
59
92
. map_err ( :: Error :: new_body_write)
60
93
}
61
94
}
@@ -94,13 +127,14 @@ where
94
127
) ;
95
128
96
129
let buf = SendBuf ( Some ( chunk) ) ;
97
- self . body_tx . send_data ( buf, is_eos)
130
+ self . body_tx
131
+ . send_data ( buf, is_eos)
98
132
. map_err ( :: Error :: new_body_write) ?;
99
133
100
134
if is_eos {
101
- return Ok ( Async :: Ready ( ( ) ) )
135
+ return Ok ( Async :: Ready ( ( ) ) ) ;
102
136
}
103
- } ,
137
+ }
104
138
None => {
105
139
let is_eos = self . stream . is_end_stream ( ) ;
106
140
if is_eos {
@@ -109,19 +143,20 @@ where
109
143
self . data_done = true ;
110
144
// loop again to poll_trailers
111
145
}
112
- } ,
146
+ }
113
147
}
114
148
} else {
115
149
match try_ready ! ( self . stream. poll_trailers( ) . map_err( |e| self . on_err( e) ) ) {
116
150
Some ( trailers) => {
117
- self . body_tx . send_trailers ( trailers)
151
+ self . body_tx
152
+ . send_trailers ( trailers)
118
153
. map_err ( :: Error :: new_body_write) ?;
119
154
return Ok ( Async :: Ready ( ( ) ) ) ;
120
- } ,
155
+ }
121
156
None => {
122
157
// There were no trailers, so send an empty DATA frame...
123
158
return self . send_eos_frame ( ) . map ( Async :: Ready ) ;
124
- } ,
159
+ }
125
160
}
126
161
}
127
162
}
@@ -133,24 +168,16 @@ struct SendBuf<B>(Option<B>);
133
168
impl < B : Buf > Buf for SendBuf < B > {
134
169
#[ inline]
135
170
fn remaining ( & self ) -> usize {
136
- self . 0
137
- . as_ref ( )
138
- . map ( |b| b. remaining ( ) )
139
- . unwrap_or ( 0 )
171
+ self . 0 . as_ref ( ) . map ( |b| b. remaining ( ) ) . unwrap_or ( 0 )
140
172
}
141
173
142
174
#[ inline]
143
175
fn bytes ( & self ) -> & [ u8 ] {
144
- self . 0
145
- . as_ref ( )
146
- . map ( |b| b. bytes ( ) )
147
- . unwrap_or ( & [ ] )
176
+ self . 0 . as_ref ( ) . map ( |b| b. bytes ( ) ) . unwrap_or ( & [ ] )
148
177
}
149
178
150
179
#[ inline]
151
180
fn advance ( & mut self , cnt : usize ) {
152
- self . 0
153
- . as_mut ( )
154
- . map ( |b| b. advance ( cnt) ) ;
181
+ self . 0 . as_mut ( ) . map ( |b| b. advance ( cnt) ) ;
155
182
}
156
183
}
0 commit comments