@@ -100,11 +100,10 @@ impl<E> std::error::Error for Error<E> where E: std::error::Error {}
100
100
impl < ' b , const N : usize > RequestHeaders < ' b , N > {
101
101
/// Parse the headers from the input stream
102
102
pub async fn receive < R > (
103
- & mut self ,
104
103
buf : & ' b mut [ u8 ] ,
105
104
mut input : R ,
106
105
exact : bool ,
107
- ) -> Result < ( & ' b mut [ u8 ] , usize ) , Error < R :: Error > >
106
+ ) -> Result < ( Self , & ' b mut [ u8 ] , usize ) , Error < R :: Error > >
108
107
where
109
108
R : Read ,
110
109
{
@@ -114,7 +113,8 @@ impl<'b, const N: usize> RequestHeaders<'b, N> {
114
113
Err ( e) => return Err ( e) ,
115
114
} ;
116
115
117
- let mut parser = httparse:: Request :: new ( & mut self . headers . 0 ) ;
116
+ let mut headers = Headers :: < ' b , N > :: new ( ) ;
117
+ let mut parser = httparse:: Request :: new ( & mut headers. 0 ) ;
118
118
119
119
let ( headers_buf, body_buf) = buf. split_at_mut ( headers_len) ;
120
120
@@ -128,31 +128,34 @@ impl<'b, const N: usize> RequestHeaders<'b, N> {
128
128
unreachable ! ( "Should not happen. HTTP header parsing is indeterminate." )
129
129
}
130
130
131
- self . http11 = if let Some ( version) = parser. version {
132
- if version > 1 {
133
- Err ( Error :: InvalidHeaders ) ?;
134
- }
135
-
136
- Some ( version == 1 )
137
- } else {
138
- None
131
+ let http11 = match parser. version {
132
+ Some ( 0 ) => false ,
133
+ Some ( 1 ) => true ,
134
+ _ => Err ( Error :: InvalidHeaders ) ?,
139
135
} ;
140
136
141
- self . method = parser. method . and_then ( Method :: new) ;
142
- self . path = parser. path ;
137
+ let method_str = parser. method . ok_or ( Error :: InvalidHeaders ) ?;
138
+ let method = Method :: new ( method_str) . ok_or ( Error :: InvalidHeaders ) ?;
139
+ let path = parser. path . ok_or ( Error :: InvalidHeaders ) ?;
143
140
144
- trace ! ( "Received:\n {}" , self ) ;
141
+ let result = Self {
142
+ http11,
143
+ method,
144
+ path,
145
+ headers,
146
+ } ;
145
147
146
- Ok ( ( body_buf, read_len - headers_len) )
148
+ trace ! ( "Received:\n {}" , result) ;
149
+
150
+ Ok ( ( result, body_buf, read_len - headers_len) )
147
151
} else {
148
152
unreachable ! ( "Secondary parse of already loaded buffer failed." )
149
153
}
150
154
}
151
155
152
156
/// Resolve the connection type and body type from the headers
153
157
pub fn resolve < E > ( & self ) -> Result < ( ConnectionType , BodyType ) , Error < E > > {
154
- self . headers
155
- . resolve :: < E > ( None , true , self . http11 . unwrap_or ( false ) )
158
+ self . headers . resolve :: < E > ( None , true , self . http11 )
156
159
}
157
160
158
161
/// Send the headers to the output stream, returning the connection type and body type
@@ -164,31 +167,29 @@ impl<'b, const N: usize> RequestHeaders<'b, N> {
164
167
where
165
168
W : Write ,
166
169
{
167
- let http11 = self . http11 . unwrap_or ( false ) ;
168
-
169
- send_request ( http11, self . method , self . path , & mut output) . await ?;
170
+ send_request ( self . http11 , self . method , self . path , & mut output) . await ?;
170
171
171
172
self . headers
172
- . send ( None , true , http11, chunked_if_unspecified, output)
173
+ . send ( None , true , self . http11 , chunked_if_unspecified, output)
173
174
. await
174
175
}
175
176
}
176
177
177
178
impl < ' b , const N : usize > ResponseHeaders < ' b , N > {
178
179
/// Parse the headers from the input stream
179
180
pub async fn receive < R > (
180
- & mut self ,
181
181
buf : & ' b mut [ u8 ] ,
182
182
mut input : R ,
183
183
exact : bool ,
184
- ) -> Result < ( & ' b mut [ u8 ] , usize ) , Error < R :: Error > >
184
+ ) -> Result < ( Self , & ' b mut [ u8 ] , usize ) , Error < R :: Error > >
185
185
where
186
186
R : Read ,
187
187
{
188
188
let ( read_len, headers_len) =
189
189
raw:: read_reply_buf :: < N , _ > ( & mut input, buf, false , exact) . await ?;
190
190
191
- let mut parser = httparse:: Response :: new ( & mut self . headers . 0 ) ;
191
+ let mut headers = Headers :: < ' b , N > :: new ( ) ;
192
+ let mut parser = httparse:: Response :: new ( & mut headers. 0 ) ;
192
193
193
194
let ( headers_buf, body_buf) = buf. split_at_mut ( headers_len) ;
194
195
@@ -199,22 +200,25 @@ impl<'b, const N: usize> ResponseHeaders<'b, N> {
199
200
unreachable ! ( "Should not happen. HTTP header parsing is indeterminate." )
200
201
}
201
202
202
- self . http11 = if let Some ( version) = parser. version {
203
- if version > 1 {
204
- Err ( Error :: InvalidHeaders ) ?;
205
- }
206
-
207
- Some ( version == 1 )
208
- } else {
209
- None
203
+ let http11 = match parser. version {
204
+ Some ( 0 ) => false ,
205
+ Some ( 1 ) => true ,
206
+ _ => Err ( Error :: InvalidHeaders ) ?,
210
207
} ;
211
208
212
- self . code = parser. code ;
213
- self . reason = parser. reason ;
209
+ let code = parser. code . ok_or ( Error :: InvalidHeaders ) ?;
210
+ let reason = parser. reason ;
211
+
212
+ let result = Self {
213
+ http11,
214
+ code,
215
+ reason,
216
+ headers,
217
+ } ;
214
218
215
- trace ! ( "Received:\n {}" , self ) ;
219
+ trace ! ( "Received:\n {}" , result ) ;
216
220
217
- Ok ( ( body_buf, read_len - headers_len) )
221
+ Ok ( ( result , body_buf, read_len - headers_len) )
218
222
} else {
219
223
unreachable ! ( "Secondary parse of already loaded buffer failed." )
220
224
}
@@ -225,11 +229,8 @@ impl<'b, const N: usize> ResponseHeaders<'b, N> {
225
229
& self ,
226
230
request_connection_type : ConnectionType ,
227
231
) -> Result < ( ConnectionType , BodyType ) , Error < E > > {
228
- self . headers . resolve :: < E > (
229
- Some ( request_connection_type) ,
230
- false ,
231
- self . http11 . unwrap_or ( false ) ,
232
- )
232
+ self . headers
233
+ . resolve :: < E > ( Some ( request_connection_type) , false , self . http11 )
233
234
}
234
235
235
236
/// Send the headers to the output stream, returning the connection type and body type
@@ -242,15 +243,13 @@ impl<'b, const N: usize> ResponseHeaders<'b, N> {
242
243
where
243
244
W : Write ,
244
245
{
245
- let http11 = self . http11 . unwrap_or ( false ) ;
246
-
247
- send_status ( http11, self . code , self . reason , & mut output) . await ?;
246
+ send_status ( self . http11 , self . code , self . reason , & mut output) . await ?;
248
247
249
248
self . headers
250
249
. send (
251
250
Some ( request_connection_type) ,
252
251
false ,
253
- http11,
252
+ self . http11 ,
254
253
chunked_if_unspecified,
255
254
output,
256
255
)
@@ -260,42 +259,56 @@ impl<'b, const N: usize> ResponseHeaders<'b, N> {
260
259
261
260
pub ( crate ) async fn send_request < W > (
262
261
http11 : bool ,
263
- method : Option < Method > ,
264
- path : Option < & str > ,
265
- output : W ,
262
+ method : Method ,
263
+ path : & str ,
264
+ mut output : W ,
266
265
) -> Result < ( ) , Error < W :: Error > >
267
266
where
268
267
W : Write ,
269
268
{
270
- raw:: send_status_line (
271
- true ,
272
- http11,
273
- method. map ( |method| method. as_str ( ) ) ,
274
- path,
275
- output,
276
- )
277
- . await
269
+ // RFC 9112: request-line = method SP request-target SP HTTP-version
270
+
271
+ output
272
+ . write_all ( method. as_str ( ) . as_bytes ( ) )
273
+ . await
274
+ . map_err ( Error :: Io ) ?;
275
+ output. write_all ( b" " ) . await . map_err ( Error :: Io ) ?;
276
+ output. write_all ( path. as_bytes ( ) ) . await . map_err ( Error :: Io ) ?;
277
+ output. write_all ( b" " ) . await . map_err ( Error :: Io ) ?;
278
+ raw:: send_version ( & mut output, http11) . await ?;
279
+ output. write_all ( b"\r \n " ) . await . map_err ( Error :: Io ) ?;
280
+
281
+ Ok ( ( ) )
278
282
}
279
283
280
284
pub ( crate ) async fn send_status < W > (
281
285
http11 : bool ,
282
- status : Option < u16 > ,
286
+ status : u16 ,
283
287
reason : Option < & str > ,
284
- output : W ,
288
+ mut output : W ,
285
289
) -> Result < ( ) , Error < W :: Error > >
286
290
where
287
291
W : Write ,
288
292
{
289
- let status_str : Option < heapless :: String < 5 > > = status. map ( |status| status. try_into ( ) . unwrap ( ) ) ;
293
+ // RFC 9112: status-line = HTTP-version SP status-code SP [ reason-phrase ]
290
294
291
- raw:: send_status_line (
292
- false ,
293
- http11,
294
- status_str. as_ref ( ) . map ( |status| status. as_str ( ) ) ,
295
- reason,
296
- output,
297
- )
298
- . await
295
+ raw:: send_version ( & mut output, http11) . await ?;
296
+ output. write_all ( b" " ) . await . map_err ( Error :: Io ) ?;
297
+ let status_str: heapless:: String < 5 > = status. try_into ( ) . unwrap ( ) ;
298
+ output
299
+ . write_all ( status_str. as_bytes ( ) )
300
+ . await
301
+ . map_err ( Error :: Io ) ?;
302
+ output. write_all ( b" " ) . await . map_err ( Error :: Io ) ?;
303
+ if let Some ( reason) = reason {
304
+ output
305
+ . write_all ( reason. as_bytes ( ) )
306
+ . await
307
+ . map_err ( Error :: Io ) ?;
308
+ }
309
+ output. write_all ( b"\r \n " ) . await . map_err ( Error :: Io ) ?;
310
+
311
+ Ok ( ( ) )
299
312
}
300
313
301
314
pub ( crate ) async fn send_headers < ' a , H , W > (
@@ -1181,61 +1194,6 @@ mod raw {
1181
1194
}
1182
1195
}
1183
1196
1184
- pub ( crate ) async fn send_status_line < W > (
1185
- request : bool ,
1186
- http11 : bool ,
1187
- token : Option < & str > ,
1188
- extra : Option < & str > ,
1189
- mut output : W ,
1190
- ) -> Result < ( ) , Error < W :: Error > >
1191
- where
1192
- W : Write ,
1193
- {
1194
- let mut written = false ;
1195
-
1196
- if !request {
1197
- send_version ( & mut output, http11) . await ?;
1198
- written = true ;
1199
- }
1200
-
1201
- if let Some ( token) = token {
1202
- if written {
1203
- output. write_all ( b" " ) . await . map_err ( Error :: Io ) ?;
1204
- }
1205
-
1206
- output
1207
- . write_all ( token. as_bytes ( ) )
1208
- . await
1209
- . map_err ( Error :: Io ) ?;
1210
-
1211
- written = true ;
1212
- }
1213
-
1214
- if written {
1215
- output. write_all ( b" " ) . await . map_err ( Error :: Io ) ?;
1216
- }
1217
- if let Some ( extra) = extra {
1218
- output
1219
- . write_all ( extra. as_bytes ( ) )
1220
- . await
1221
- . map_err ( Error :: Io ) ?;
1222
-
1223
- written = true ;
1224
- }
1225
-
1226
- if request {
1227
- if written {
1228
- output. write_all ( b" " ) . await . map_err ( Error :: Io ) ?;
1229
- }
1230
-
1231
- send_version ( & mut output, http11) . await ?;
1232
- }
1233
-
1234
- output. write_all ( b"\r \n " ) . await . map_err ( Error :: Io ) ?;
1235
-
1236
- Ok ( ( ) )
1237
- }
1238
-
1239
1197
pub ( crate ) async fn send_version < W > ( mut output : W , http11 : bool ) -> Result < ( ) , Error < W :: Error > >
1240
1198
where
1241
1199
W : Write ,
0 commit comments