@@ -100,11 +100,10 @@ impl<E> std::error::Error for Error<E> where E: std::error::Error {}
100100impl < ' b , const N : usize > RequestHeaders < ' b , N > {
101101 /// Parse the headers from the input stream
102102 pub async fn receive < R > (
103- & mut self ,
104103 buf : & ' b mut [ u8 ] ,
105104 mut input : R ,
106105 exact : bool ,
107- ) -> Result < ( & ' b mut [ u8 ] , usize ) , Error < R :: Error > >
106+ ) -> Result < ( Self , & ' b mut [ u8 ] , usize ) , Error < R :: Error > >
108107 where
109108 R : Read ,
110109 {
@@ -114,7 +113,8 @@ impl<'b, const N: usize> RequestHeaders<'b, N> {
114113 Err ( e) => return Err ( e) ,
115114 } ;
116115
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 ) ;
118118
119119 let ( headers_buf, body_buf) = buf. split_at_mut ( headers_len) ;
120120
@@ -128,31 +128,34 @@ impl<'b, const N: usize> RequestHeaders<'b, N> {
128128 unreachable ! ( "Should not happen. HTTP header parsing is indeterminate." )
129129 }
130130
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 ) ?,
139135 } ;
140136
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 ) ?;
143140
144- trace ! ( "Received:\n {}" , self ) ;
141+ let result = Self {
142+ http11,
143+ method,
144+ path,
145+ headers,
146+ } ;
145147
146- Ok ( ( body_buf, read_len - headers_len) )
148+ trace ! ( "Received:\n {}" , result) ;
149+
150+ Ok ( ( result, body_buf, read_len - headers_len) )
147151 } else {
148152 unreachable ! ( "Secondary parse of already loaded buffer failed." )
149153 }
150154 }
151155
152156 /// Resolve the connection type and body type from the headers
153157 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 )
156159 }
157160
158161 /// 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> {
164167 where
165168 W : Write ,
166169 {
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 ?;
170171
171172 self . headers
172- . send ( None , true , http11, chunked_if_unspecified, output)
173+ . send ( None , true , self . http11 , chunked_if_unspecified, output)
173174 . await
174175 }
175176}
176177
177178impl < ' b , const N : usize > ResponseHeaders < ' b , N > {
178179 /// Parse the headers from the input stream
179180 pub async fn receive < R > (
180- & mut self ,
181181 buf : & ' b mut [ u8 ] ,
182182 mut input : R ,
183183 exact : bool ,
184- ) -> Result < ( & ' b mut [ u8 ] , usize ) , Error < R :: Error > >
184+ ) -> Result < ( Self , & ' b mut [ u8 ] , usize ) , Error < R :: Error > >
185185 where
186186 R : Read ,
187187 {
188188 let ( read_len, headers_len) =
189189 raw:: read_reply_buf :: < N , _ > ( & mut input, buf, false , exact) . await ?;
190190
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 ) ;
192193
193194 let ( headers_buf, body_buf) = buf. split_at_mut ( headers_len) ;
194195
@@ -199,22 +200,25 @@ impl<'b, const N: usize> ResponseHeaders<'b, N> {
199200 unreachable ! ( "Should not happen. HTTP header parsing is indeterminate." )
200201 }
201202
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 ) ?,
210207 } ;
211208
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+ } ;
214218
215- trace ! ( "Received:\n {}" , self ) ;
219+ trace ! ( "Received:\n {}" , result ) ;
216220
217- Ok ( ( body_buf, read_len - headers_len) )
221+ Ok ( ( result , body_buf, read_len - headers_len) )
218222 } else {
219223 unreachable ! ( "Secondary parse of already loaded buffer failed." )
220224 }
@@ -225,11 +229,8 @@ impl<'b, const N: usize> ResponseHeaders<'b, N> {
225229 & self ,
226230 request_connection_type : ConnectionType ,
227231 ) -> 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 )
233234 }
234235
235236 /// 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> {
242243 where
243244 W : Write ,
244245 {
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 ?;
248247
249248 self . headers
250249 . send (
251250 Some ( request_connection_type) ,
252251 false ,
253- http11,
252+ self . http11 ,
254253 chunked_if_unspecified,
255254 output,
256255 )
@@ -260,42 +259,56 @@ impl<'b, const N: usize> ResponseHeaders<'b, N> {
260259
261260pub ( crate ) async fn send_request < W > (
262261 http11 : bool ,
263- method : Option < Method > ,
264- path : Option < & str > ,
265- output : W ,
262+ method : Method ,
263+ path : & str ,
264+ mut output : W ,
266265) -> Result < ( ) , Error < W :: Error > >
267266where
268267 W : Write ,
269268{
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 ( ( ) )
278282}
279283
280284pub ( crate ) async fn send_status < W > (
281285 http11 : bool ,
282- status : Option < u16 > ,
286+ status : u16 ,
283287 reason : Option < & str > ,
284- output : W ,
288+ mut output : W ,
285289) -> Result < ( ) , Error < W :: Error > >
286290where
287291 W : Write ,
288292{
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 ]
290294
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 ( ( ) )
299312}
300313
301314pub ( crate ) async fn send_headers < ' a , H , W > (
@@ -1181,61 +1194,6 @@ mod raw {
11811194 }
11821195 }
11831196
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-
12391197 pub ( crate ) async fn send_version < W > ( mut output : W , http11 : bool ) -> Result < ( ) , Error < W :: Error > >
12401198 where
12411199 W : Write ,
0 commit comments