http_parser.rb 0.5.1-x86-mswin32-60 → 0.5.2-x86-mswin32-60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/Gemfile.lock +16 -16
  2. data/LICENSE-MIT +20 -0
  3. data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +68 -11
  4. data/ext/ruby_http_parser/ruby_http_parser.c +74 -6
  5. data/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT +26 -1
  6. data/ext/ruby_http_parser/vendor/http-parser-java/README.md +23 -143
  7. data/ext/ruby_http_parser/vendor/http-parser-java/TODO +3 -0
  8. data/ext/ruby_http_parser/vendor/http-parser-java/build.xml +74 -0
  9. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c +115 -61
  10. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h +19 -3
  11. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPCallback.java +8 -0
  12. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPDataCallback.java +34 -0
  13. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPErrorCallback.java +12 -0
  14. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java +4 -2
  15. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java +64 -52
  16. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java +5 -0
  17. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java +323 -0
  18. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/{lolevel/Util.java → Util.java} +27 -28
  19. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java +259 -85
  20. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java +1 -0
  21. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java +324 -0
  22. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Requests.java +69 -0
  23. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Responses.java +51 -0
  24. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Test.java +15 -0
  25. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestHeaderOverflowError.java +47 -0
  26. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java +183 -447
  27. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestNoOverflowLongBody.java +61 -0
  28. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java +2 -1
  29. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Upgrade.java +26 -0
  30. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Util.java +165 -0
  31. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/WrongContentLength.java +58 -0
  32. data/ext/ruby_http_parser/vendor/http-parser-java/test.c +232 -29
  33. data/ext/ruby_http_parser/vendor/http-parser-java/test_permutations +1 -1
  34. data/ext/ruby_http_parser/vendor/http-parser-java/test_unit +1 -1
  35. data/ext/ruby_http_parser/vendor/http-parser-java/test_utf8 +1 -0
  36. data/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped +154 -7
  37. data/ext/ruby_http_parser/vendor/http-parser-java/tests.utf8 +17 -0
  38. data/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT +1 -1
  39. data/ext/ruby_http_parser/vendor/http-parser/http_parser.c +52 -10
  40. data/ext/ruby_http_parser/vendor/http-parser/http_parser.h +3 -1
  41. data/ext/ruby_http_parser/vendor/http-parser/test.c +89 -3
  42. data/http_parser.rb.gemspec +8 -2
  43. data/lib/http_parser.rb +17 -0
  44. data/spec/parser_spec.rb +97 -6
  45. data/tasks/compile.rake +3 -1
  46. metadata +83 -20
  47. data/ext/ruby_http_parser/vendor/http-parser-java/CONTRIBUTIONS +0 -4
@@ -1 +1 @@
1
- javac -d classes/ `find src -name '*.java'` && java -cp classes http_parser.lolevel.TestLoaderNG tests.dumped
1
+ javac -cp ext/primitives.jar -d classes/ `find src -name '*.java'` && java -cp classes:ext/primitives.jar http_parser.lolevel.TestLoaderNG tests.dumped
@@ -1 +1 @@
1
- javac -d classes/ `find src -name '*.java'` && java -cp classes http_parser.lolevel.UnitTest
1
+ javac -cp ext/primitives.jar -d classes/ `find src -name '*.java'` && java -cp classes:ext/primitives.jar http_parser.lolevel.UnitTest
@@ -0,0 +1 @@
1
+ javac -cp ext/primitives.jar -d classes/ `find src -name '*.java'` && java -cp classes:ext/primitives.jar http_parser.lolevel.TestLoaderNG tests.utf8
@@ -304,12 +304,12 @@ http_major :1
304
304
  http_minor :1
305
305
 
306
306
  name :connect request
307
- raw :"CONNECT home.netscape.com:443 HTTP/1.0\r\nUser-agent: Mozilla/1.1N\r\nProxy-authorization: basic aGVsbG86d29ybGQ=\r\n\r\n"
307
+ raw :"CONNECT home0.netscape.com:443 HTTP/1.0\r\nUser-agent: Mozilla/1.1N\r\nProxy-authorization: basic aGVsbG86d29ybGQ=\r\n\r\n"
308
308
  type :HTTP_REQUEST
309
309
  method: HTTP_CONNECT
310
310
  status_code :0
311
311
  request_path:
312
- request_url :home.netscape.com:443
312
+ request_url :home0.netscape.com:443
313
313
  fragment :
314
314
  query_string:
315
315
  body :""
@@ -324,7 +324,7 @@ http_minor :0
324
324
  name :report request
325
325
  raw :"REPORT /test HTTP/1.1\r\n\r\n"
326
326
  type :HTTP_REQUEST
327
- method: REPORT
327
+ method: HTTP_REPORT
328
328
  status_code :0
329
329
  request_path:/test
330
330
  request_url :/test
@@ -337,8 +337,108 @@ upgrade :0
337
337
  http_major :1
338
338
  http_minor :1
339
339
 
340
+ name :request with no http version
341
+ raw :"GET /\r\n\r\n"
342
+ type :HTTP_REQUEST
343
+ method: HTTP_GET
344
+ status_code :0
345
+ request_path:/
346
+ request_url :/
347
+ fragment :
348
+ query_string:
349
+ body :""
350
+ body_size :0
351
+ should_keep_alive :0
352
+ upgrade :0
353
+ http_major :0
354
+ http_minor :9
355
+
356
+ name :m-search request
357
+ raw :"M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nST: \"ssdp:all\"\r\n\r\n"
358
+ type :HTTP_REQUEST
359
+ method: HTTP_MSEARCH
360
+ status_code :0
361
+ request_path:*
362
+ request_url :*
363
+ fragment :
364
+ query_string:
365
+ body :""
366
+ body_size :0
367
+ header_0 :{ "HOST": "239.255.255.250:1900"}
368
+ header_1 :{ "MAN": ""ssdp:discover""}
369
+ header_2 :{ "ST": ""ssdp:all""}
370
+ should_keep_alive :1
371
+ upgrade :0
372
+ http_major :1
373
+ http_minor :1
374
+
375
+ name :utf-8 path request
376
+ raw :"GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\nHost: github.com\r\n\r\n"
377
+ type :HTTP_REQUEST
378
+ method: HTTP_GET
379
+ status_code :0
380
+ request_path:/δ¶/δt/pope
381
+ request_url :/δ¶/δt/pope?q=1#narf
382
+ fragment :narf
383
+ query_string:q=1
384
+ body :""
385
+ body_size :0
386
+ header_0 :{ "Host": "github.com"}
387
+ should_keep_alive :1
388
+ upgrade :0
389
+ http_major :1
390
+ http_minor :1
391
+
392
+ name :host terminated by a query string
393
+ raw :"GET http://hypnotoad.org?hail=all HTTP/1.1\r\n\r\n"
394
+ type :HTTP_REQUEST
395
+ method: HTTP_GET
396
+ status_code :0
397
+ request_path:
398
+ request_url :http://hypnotoad.org?hail=all
399
+ fragment :
400
+ query_string:hail=all
401
+ body :""
402
+ body_size :0
403
+ should_keep_alive :1
404
+ upgrade :0
405
+ http_major :1
406
+ http_minor :1
407
+
408
+ name :host:port terminated by a query string
409
+ raw :"GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n\r\n"
410
+ type :HTTP_REQUEST
411
+ method: HTTP_GET
412
+ status_code :0
413
+ request_path:
414
+ request_url :http://hypnotoad.org:1234?hail=all
415
+ fragment :
416
+ query_string:hail=all
417
+ body :""
418
+ body_size :0
419
+ should_keep_alive :1
420
+ upgrade :0
421
+ http_major :1
422
+ http_minor :1
423
+
424
+ name :host:port terminated by a space
425
+ raw :"GET http://hypnotoad.org:1234 HTTP/1.1\r\n\r\n"
426
+ type :HTTP_REQUEST
427
+ method: HTTP_GET
428
+ status_code :0
429
+ request_path:
430
+ request_url :http://hypnotoad.org:1234
431
+ fragment :
432
+ query_string:
433
+ body :""
434
+ body_size :0
435
+ should_keep_alive :1
436
+ upgrade :0
437
+ http_major :1
438
+ http_minor :1
439
+
340
440
  name :google 301
341
- raw :"HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.google.com/\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Sun, 26 Apr 2009 11:11:49 GMT\r\nExpires: Tue, 26 May 2009 11:11:49 GMT\r\nCache-Control: public, max-age=2592000\r\nServer: gws\r\nContent-Length: 219\r\n\r\n<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n<TITLE>301 Moved</TITLE></HEAD><BODY>\n<H1>301 Moved</H1>\nThe document has moved\n<A HREF=\"http://www.google.com/\">here</A>.\r\n</BODY></HTML>\r\n"
441
+ raw :"HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.google.com/\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Sun, 26 Apr 2009 11:11:49 GMT\r\nExpires: Tue, 26 May 2009 11:11:49 GMT\r\nX-$PrototypeBI-Version: 1.6.0.3\r\nCache-Control: public, max-age=2592000\r\nServer: gws\r\nContent-Length: 219 \r\n\r\n<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n<TITLE>301 Moved</TITLE></HEAD><BODY>\n<H1>301 Moved</H1>\nThe document has moved\n<A HREF=\"http://www.google.com/\">here</A>.\r\n</BODY></HTML>\r\n"
342
442
  type :HTTP_RESPONSE
343
443
  method: HTTP_DELETE
344
444
  status_code :301
@@ -352,9 +452,10 @@ header_0 :{ "Location": "http://www.google.com/"}
352
452
  header_1 :{ "Content-Type": "text/html; charset=UTF-8"}
353
453
  header_2 :{ "Date": "Sun, 26 Apr 2009 11:11:49 GMT"}
354
454
  header_3 :{ "Expires": "Tue, 26 May 2009 11:11:49 GMT"}
355
- header_4 :{ "Cache-Control": "public, max-age=2592000"}
356
- header_5 :{ "Server": "gws"}
357
- header_6 :{ "Content-Length": "219"}
455
+ header_4 :{ "X-$PrototypeBI-Version": "1.6.0.3"}
456
+ header_5 :{ "Cache-Control": "public, max-age=2592000"}
457
+ header_6 :{ "Server": "gws"}
458
+ header_7 :{ "Content-Length": "219 "}
358
459
  should_keep_alive :1
359
460
  upgrade :0
360
461
  http_major :1
@@ -537,3 +638,49 @@ upgrade :0
537
638
  http_major :1
538
639
  http_minor :1
539
640
 
641
+ name :field underscore
642
+ raw :"HTTP/1.1 200 OK\r\nDate: Tue, 28 Sep 2010 01:14:13 GMT\r\nServer: Apache\r\nCache-Control: no-cache, must-revalidate\r\nExpires: Mon, 26 Jul 1997 05:00:00 GMT\r\n.et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\nVary: Accept-Encoding\r\n_eep-Alive: timeout=45\r\n_onnection: Keep-Alive\r\nTransfer-Encoding: chunked\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n0\r\n\r\n"
643
+ type :HTTP_RESPONSE
644
+ method: HTTP_DELETE
645
+ status_code :200
646
+ request_path:
647
+ request_url :
648
+ fragment :
649
+ query_string:
650
+ body :""
651
+ body_size :0
652
+ header_0 :{ "Date": "Tue, 28 Sep 2010 01:14:13 GMT"}
653
+ header_1 :{ "Server": "Apache"}
654
+ header_2 :{ "Cache-Control": "no-cache, must-revalidate"}
655
+ header_3 :{ "Expires": "Mon, 26 Jul 1997 05:00:00 GMT"}
656
+ header_4 :{ ".et-Cookie": "PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com"}
657
+ header_5 :{ "Vary": "Accept-Encoding"}
658
+ header_6 :{ "_eep-Alive": "timeout=45"}
659
+ header_7 :{ "_onnection": "Keep-Alive"}
660
+ header_8 :{ "Transfer-Encoding": "chunked"}
661
+ header_9 :{ "Content-Type": "text/html"}
662
+ header_10 :{ "Connection": "close"}
663
+ should_keep_alive :0
664
+ upgrade :0
665
+ http_major :1
666
+ http_minor :1
667
+
668
+ name :non-ASCII in status line
669
+ raw :"HTTP/1.1 500 Oriëntatieprobleem\r\nDate: Fri, 5 Nov 2010 23:07:12 GMT+2\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"
670
+ type :HTTP_RESPONSE
671
+ method: HTTP_DELETE
672
+ status_code :500
673
+ request_path:
674
+ request_url :
675
+ fragment :
676
+ query_string:
677
+ body :""
678
+ body_size :0
679
+ header_0 :{ "Date": "Fri, 5 Nov 2010 23:07:12 GMT+2"}
680
+ header_1 :{ "Content-Length": "0"}
681
+ header_2 :{ "Connection": "close"}
682
+ should_keep_alive :0
683
+ upgrade :0
684
+ http_major :1
685
+ http_minor :1
686
+
@@ -0,0 +1,17 @@
1
+ name :utf-8 path request
2
+ raw :"GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\nHost: github.com\r\n\r\n"
3
+ type :HTTP_REQUEST
4
+ method: HTTP_GET
5
+ status_code :0
6
+ request_path:/δ¶/δt/pope
7
+ request_url :/δ¶/δt/pope?q=1#narf
8
+ fragment :narf
9
+ query_string:q=1
10
+ body :""
11
+ body_size :0
12
+ header_0 :{ "Host": "github.com"}
13
+ should_keep_alive :1
14
+ upgrade :0
15
+ http_major :1
16
+ http_minor :1
17
+
@@ -1,4 +1,4 @@
1
- Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
1
+ Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
@@ -1,4 +1,4 @@
1
- /* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
2
  *
3
3
  * Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  * of this software and associated documentation files (the "Software"), to
@@ -186,7 +186,28 @@ static const uint8_t normal_url_char[256] = {
186
186
  /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
187
187
  1, 1, 1, 1, 1, 1, 1, 1,
188
188
  /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
189
- 1, 1, 1, 1, 1, 1, 1, 0 };
189
+ 1, 1, 1, 1, 1, 1, 1, 0,
190
+
191
+ /* Remainder of non-ASCII range are accepted as-is to support implicitly UTF-8
192
+ encoded paths. This is out of spec, but clients generate this and most other
193
+ HTTP servers support it. We should, too. */
194
+
195
+ 1, 1, 1, 1, 1, 1, 1, 1,
196
+ 1, 1, 1, 1, 1, 1, 1, 1,
197
+ 1, 1, 1, 1, 1, 1, 1, 1,
198
+ 1, 1, 1, 1, 1, 1, 1, 1,
199
+ 1, 1, 1, 1, 1, 1, 1, 1,
200
+ 1, 1, 1, 1, 1, 1, 1, 1,
201
+ 1, 1, 1, 1, 1, 1, 1, 1,
202
+ 1, 1, 1, 1, 1, 1, 1, 1,
203
+ 1, 1, 1, 1, 1, 1, 1, 1,
204
+ 1, 1, 1, 1, 1, 1, 1, 1,
205
+ 1, 1, 1, 1, 1, 1, 1, 1,
206
+ 1, 1, 1, 1, 1, 1, 1, 1,
207
+ 1, 1, 1, 1, 1, 1, 1, 1,
208
+ 1, 1, 1, 1, 1, 1, 1, 1,
209
+ 1, 1, 1, 1, 1, 1, 1, 1,
210
+ 1, 1, 1, 1, 1, 1, 1, 1 };
190
211
 
191
212
 
192
213
  enum state
@@ -240,15 +261,17 @@ enum state
240
261
 
241
262
  , s_header_almost_done
242
263
 
264
+ , s_chunk_size_start
265
+ , s_chunk_size
266
+ , s_chunk_parameters
267
+ , s_chunk_size_almost_done
268
+
243
269
  , s_headers_almost_done
244
270
  /* Important: 's_headers_almost_done' must be the last 'header' state. All
245
271
  * states beyond this must be 'body' states. It is used for overflow
246
272
  * checking. See the PARSING_HEADER() macro.
247
273
  */
248
- , s_chunk_size_start
249
- , s_chunk_size
250
- , s_chunk_size_almost_done
251
- , s_chunk_parameters
274
+
252
275
  , s_chunk_data
253
276
  , s_chunk_data_almost_done
254
277
  , s_chunk_data_done
@@ -258,7 +281,7 @@ enum state
258
281
  };
259
282
 
260
283
 
261
- #define PARSING_HEADER(state) (state <= s_headers_almost_done && 0 == (parser->flags & F_TRAILING))
284
+ #define PARSING_HEADER(state) (state <= s_headers_almost_done)
262
285
 
263
286
 
264
287
  enum header_states
@@ -331,10 +354,20 @@ size_t http_parser_execute (http_parser *parser,
331
354
  uint64_t nread = parser->nread;
332
355
 
333
356
  if (len == 0) {
334
- if (state == s_body_identity_eof) {
335
- CALLBACK2(message_complete);
357
+ switch (state) {
358
+ case s_body_identity_eof:
359
+ CALLBACK2(message_complete);
360
+ return 0;
361
+
362
+ case s_dead:
363
+ case s_start_req_or_res:
364
+ case s_start_res:
365
+ case s_start_req:
366
+ return 0;
367
+
368
+ default:
369
+ return 1; // error
336
370
  }
337
- return 0;
338
371
  }
339
372
 
340
373
  /* technically we could combine all of these (except for url_mark) into one
@@ -707,6 +740,9 @@ size_t http_parser_execute (http_parser *parser,
707
740
  CALLBACK(url);
708
741
  state = s_req_http_start;
709
742
  break;
743
+ case '?':
744
+ state = s_req_query_string_start;
745
+ break;
710
746
  default:
711
747
  goto error;
712
748
  }
@@ -729,6 +765,9 @@ size_t http_parser_execute (http_parser *parser,
729
765
  CALLBACK(url);
730
766
  state = s_req_http_start;
731
767
  break;
768
+ case '?':
769
+ state = s_req_query_string_start;
770
+ break;
732
771
  default:
733
772
  goto error;
734
773
  }
@@ -1448,6 +1487,7 @@ size_t http_parser_execute (http_parser *parser,
1448
1487
 
1449
1488
  case s_chunk_size_start:
1450
1489
  {
1490
+ assert(nread == 1);
1451
1491
  assert(parser->flags & F_CHUNKED);
1452
1492
 
1453
1493
  c = unhex[(unsigned char)ch];
@@ -1497,6 +1537,8 @@ size_t http_parser_execute (http_parser *parser,
1497
1537
  assert(parser->flags & F_CHUNKED);
1498
1538
  STRICT_CHECK(ch != LF);
1499
1539
 
1540
+ nread = 0;
1541
+
1500
1542
  if (parser->content_length == 0) {
1501
1543
  parser->flags |= F_TRAILING;
1502
1544
  state = s_header_field_start;
@@ -1,4 +1,4 @@
1
- /* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
2
  *
3
3
  * Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  * of this software and associated documentation files (the "Software"), to
@@ -24,6 +24,8 @@
24
24
  extern "C" {
25
25
  #endif
26
26
 
27
+ #define HTTP_PARSER_VERSION_MAJOR 1
28
+ #define HTTP_PARSER_VERSION_MINOR 0
27
29
 
28
30
  #include <sys/types.h>
29
31
  #if defined(_WIN32) && !defined(__MINGW32__)
@@ -1,4 +1,4 @@
1
- /* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
2
  *
3
3
  * Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  * of this software and associated documentation files (the "Software"), to
@@ -557,7 +557,7 @@ const struct message requests[] =
557
557
  ,.body= ""
558
558
  }
559
559
 
560
- #define MSEARCH_REQ 19
560
+ #define MSEARCH_REQ 20
561
561
  , {.name= "m-search request"
562
562
  ,.type= HTTP_REQUEST
563
563
  ,.raw= "M-SEARCH * HTTP/1.1\r\n"
@@ -582,6 +582,84 @@ const struct message requests[] =
582
582
  ,.body= ""
583
583
  }
584
584
 
585
+ #define UTF8_PATH_REQ 21
586
+ , {.name= "utf-8 path request"
587
+ ,.type= HTTP_REQUEST
588
+ ,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n"
589
+ "Host: github.com\r\n"
590
+ "\r\n"
591
+ ,.should_keep_alive= TRUE
592
+ ,.message_complete_on_eof= FALSE
593
+ ,.http_major= 1
594
+ ,.http_minor= 1
595
+ ,.method= HTTP_GET
596
+ ,.query_string= "q=1"
597
+ ,.fragment= "narf"
598
+ ,.request_path= "/δ¶/δt/pope"
599
+ ,.request_url= "/δ¶/δt/pope?q=1#narf"
600
+ ,.num_headers= 1
601
+ ,.headers= { {"Host", "github.com" }
602
+ }
603
+ ,.body= ""
604
+ }
605
+
606
+ #define QUERY_TERMINATED_HOST 22
607
+ , {.name= "host terminated by a query string"
608
+ ,.type= HTTP_REQUEST
609
+ ,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n"
610
+ "\r\n"
611
+ ,.should_keep_alive= TRUE
612
+ ,.message_complete_on_eof= FALSE
613
+ ,.http_major= 1
614
+ ,.http_minor= 1
615
+ ,.method= HTTP_GET
616
+ ,.query_string= "hail=all"
617
+ ,.fragment= ""
618
+ ,.request_path= ""
619
+ ,.request_url= "http://hypnotoad.org?hail=all"
620
+ ,.num_headers= 0
621
+ ,.headers= { }
622
+ ,.body= ""
623
+ }
624
+
625
+ #define QUERY_TERMINATED_HOSTPORT 23
626
+ , {.name= "host:port terminated by a query string"
627
+ ,.type= HTTP_REQUEST
628
+ ,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n"
629
+ "\r\n"
630
+ ,.should_keep_alive= TRUE
631
+ ,.message_complete_on_eof= FALSE
632
+ ,.http_major= 1
633
+ ,.http_minor= 1
634
+ ,.method= HTTP_GET
635
+ ,.query_string= "hail=all"
636
+ ,.fragment= ""
637
+ ,.request_path= ""
638
+ ,.request_url= "http://hypnotoad.org:1234?hail=all"
639
+ ,.num_headers= 0
640
+ ,.headers= { }
641
+ ,.body= ""
642
+ }
643
+
644
+ #define SPACE_TERMINATED_HOSTPORT 24
645
+ , {.name= "host:port terminated by a space"
646
+ ,.type= HTTP_REQUEST
647
+ ,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n"
648
+ "\r\n"
649
+ ,.should_keep_alive= TRUE
650
+ ,.message_complete_on_eof= FALSE
651
+ ,.http_major= 1
652
+ ,.http_minor= 1
653
+ ,.method= HTTP_GET
654
+ ,.query_string= ""
655
+ ,.fragment= ""
656
+ ,.request_path= ""
657
+ ,.request_url= "http://hypnotoad.org:1234"
658
+ ,.num_headers= 0
659
+ ,.headers= { }
660
+ ,.body= ""
661
+ }
662
+
585
663
  , {.name= NULL } /* sentinel */
586
664
  };
587
665
 
@@ -1735,14 +1813,22 @@ main (void)
1735
1813
 
1736
1814
  /// REQUESTS
1737
1815
 
1738
-
1739
1816
  test_simple("hello world", 0);
1740
1817
  test_simple("GET / HTP/1.1\r\n\r\n", 0);
1741
1818
 
1819
+
1742
1820
  test_simple("ASDF / HTTP/1.1\r\n\r\n", 0);
1743
1821
  test_simple("PROPPATCHA / HTTP/1.1\r\n\r\n", 0);
1744
1822
  test_simple("GETA / HTTP/1.1\r\n\r\n", 0);
1745
1823
 
1824
+ // Well-formed but incomplete
1825
+ test_simple("GET / HTTP/1.1\r\n"
1826
+ "Content-Type: text/plain\r\n"
1827
+ "Content-Length: 6\r\n"
1828
+ "\r\n"
1829
+ "fooba",
1830
+ 0);
1831
+
1746
1832
  static const char *all_methods[] = {
1747
1833
  "DELETE",
1748
1834
  "GET",