@@ -151,21 +151,19 @@ func TestParser(t *testing.T) {
151151 }
152152
153153 compareRequests (t , wanted , request )
154- request .Reset ()
155154 })
156155
157- t .Run ("simple GET with leading CRLF" , func (t * testing.T ) {
156+ t .Run ("leading CRLF" , func (t * testing.T ) {
158157 raw := "\r \n \r \n GET / HTTP/1.1\r \n \r \n "
159- parser , request := getParser (cfg )
158+ parser , _ := getParser (cfg )
160159 done , extra , err := parser .Parse ([]byte (raw ))
161160 // unfortunately, we don't support this. Such clients must die.
162161 require .Error (t , err , status .ErrBadRequest .Error ())
163162 require .True (t , done )
164163 require .Empty (t , extra )
165- request .Reset ()
166164 })
167165
168- t .Run ("normal GET" , func (t * testing.T ) {
166+ t .Run ("GET with headers " , func (t * testing.T ) {
169167 raw := "GET / HTTP/1.1\r \n Hello: World!\r \n Easter: Egg\r \n \r \n "
170168 parser , request := getParser (cfg )
171169 done , extra , err := parser .Parse ([]byte (raw ))
@@ -183,7 +181,6 @@ func TestParser(t *testing.T) {
183181 }
184182
185183 compareRequests (t , wanted , request )
186- request .Reset ()
187184 })
188185
189186 t .Run ("multiple header values" , func (t * testing.T ) {
@@ -204,7 +201,6 @@ func TestParser(t *testing.T) {
204201 }
205202
206203 compareRequests (t , wanted , request )
207- request .Reset ()
208204 })
209205
210206 t .Run ("only lf" , func (t * testing.T ) {
@@ -225,7 +221,6 @@ func TestParser(t *testing.T) {
225221 }
226222
227223 compareRequests (t , wanted , request )
228- request .Reset ()
229224 })
230225
231226 t .Run ("fuzz GET" , func (t * testing.T ) {
@@ -268,7 +263,6 @@ func TestParser(t *testing.T) {
268263 }
269264
270265 compareRequests (t , wanted , request )
271- request .Reset ()
272266 })
273267
274268 t .Run ("content length" , func (t * testing.T ) {
@@ -279,6 +273,7 @@ func TestParser(t *testing.T) {
279273 require .True (t , done )
280274 require .Equal (t , "Hello, world!" , string (extra ))
281275 require .Equal (t , 13 , request .ContentLength )
276+ require .Equal (t , "13" , request .Headers .Value ("content-length" ))
282277 request .Reset ()
283278
284279 raw = "GET / HTTP/1.1\r \n Content-Length: 13\r \n Hi-Hi: ha-ha\r \n \r \n Hello, world!"
@@ -287,9 +282,8 @@ func TestParser(t *testing.T) {
287282 require .True (t , done )
288283 require .Equal (t , "Hello, world!" , string (extra ))
289284 require .Equal (t , 13 , request .ContentLength )
290- require .True (t , request .Headers .Has ( "hi-hi " ))
285+ require .Equal (t , "13" , request .Headers .Value ( "content-length " ))
291286 require .Equal (t , "ha-ha" , request .Headers .Value ("hi-hi" ))
292- request .Reset ()
293287 })
294288
295289 t .Run ("connection" , func (t * testing.T ) {
@@ -300,7 +294,6 @@ func TestParser(t *testing.T) {
300294 require .True (t , done )
301295 require .Empty (t , string (extra ))
302296 require .Equal (t , "Keep-Alive" , request .Connection )
303- request .Reset ()
304297 })
305298
306299 t .Run ("Transfer-Encoding and Content-Encoding" , func (t * testing.T ) {
@@ -313,22 +306,26 @@ func TestParser(t *testing.T) {
313306 require .Equal (t , []string {"chunked" }, request .TransferEncoding )
314307 require .True (t , request .Chunked )
315308 require .Equal (t , []string {"gzip" , "deflate" }, request .ContentEncoding )
316- request .Reset ()
317309 })
318310
319311 t .Run ("urldecode" , func (t * testing.T ) {
320- parsePath := func (encodedPath string ) (string , error ) {
321- raw := fmt .Sprintf ("GET %s " , encodedPath )
312+ parseRequestLine := func (path string ) (* http. Request , error ) {
313+ raw := fmt .Sprintf ("GET %s " , path )
322314 parser , request := getParser (cfg )
323315
324316 for i := 0 ; i < len (raw ); i ++ {
325317 _ , _ , err := parser .Parse ([]byte {raw [i ]})
326318 if err != nil {
327- return "" , err
319+ return request , err
328320 }
329321 }
330322
331- return request .Path , nil
323+ return request , nil
324+ }
325+
326+ parsePath := func (path string ) (string , error ) {
327+ request , err := parseRequestLine (path )
328+ return request .Path , err
332329 }
333330
334331 t .Run ("path" , func (t * testing.T ) {
@@ -342,6 +339,26 @@ func TestParser(t *testing.T) {
342339 require .EqualError (t , err , status .ErrBadRequest .Error ())
343340 })
344341
342+ t .Run ("unsafe" , func (t * testing.T ) {
343+ test := func (t * testing.T , request * http.Request ) {
344+ require .Equal (t , "/ foo%2fbar#?" , request .Path )
345+ require .Equal (t , "bar" , request .Params .Value ("foo+=" ))
346+ }
347+
348+ t .Run ("slowpath" , func (t * testing.T ) {
349+ request , err := parseRequestLine ("/%20foo%2fbar%23%3f?foo%2b%3d=bar" )
350+ require .NoError (t , err )
351+ test (t , request )
352+ })
353+
354+ t .Run ("fastpath" , func (t * testing.T ) {
355+ parser , request := getParser (config .Default ())
356+ _ , _ , err := parser .Parse ([]byte ("GET /%20foo%2fbar%23%3f?foo%2b%3d=bar " ))
357+ require .NoError (t , err )
358+ test (t , request )
359+ })
360+ })
361+
345362 t .Run ("params" , func (t * testing.T ) {
346363 parseParams := func (params ... string ) (http.Params , error ) {
347364 parser , request := getParser (config .Default ())
0 commit comments