unicorn 5.0.1 → 6.1.0

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 (92) hide show
  1. checksums.yaml +5 -5
  2. data/.manifest +11 -5
  3. data/.olddoc.yml +16 -6
  4. data/Application_Timeouts +4 -4
  5. data/CONTRIBUTORS +6 -2
  6. data/Documentation/.gitignore +1 -3
  7. data/Documentation/unicorn.1 +222 -0
  8. data/Documentation/unicorn_rails.1 +207 -0
  9. data/FAQ +1 -1
  10. data/GIT-VERSION-FILE +1 -1
  11. data/GIT-VERSION-GEN +1 -1
  12. data/GNUmakefile +118 -58
  13. data/HACKING +2 -10
  14. data/ISSUES +40 -35
  15. data/KNOWN_ISSUES +2 -2
  16. data/LATEST +23 -28
  17. data/LICENSE +2 -2
  18. data/Links +13 -11
  19. data/NEWS +612 -0
  20. data/README +30 -29
  21. data/SIGNALS +1 -1
  22. data/Sandbox +8 -7
  23. data/TODO +0 -2
  24. data/TUNING +19 -1
  25. data/archive/slrnpull.conf +1 -1
  26. data/bin/unicorn +3 -1
  27. data/bin/unicorn_rails +2 -2
  28. data/examples/big_app_gc.rb +1 -1
  29. data/examples/init.sh +36 -8
  30. data/examples/logrotate.conf +17 -2
  31. data/examples/nginx.conf +4 -3
  32. data/examples/unicorn.conf.minimal.rb +2 -2
  33. data/examples/unicorn.conf.rb +2 -2
  34. data/examples/unicorn@.service +14 -0
  35. data/ext/unicorn_http/c_util.h +5 -13
  36. data/ext/unicorn_http/common_field_optimization.h +22 -5
  37. data/ext/unicorn_http/epollexclusive.h +124 -0
  38. data/ext/unicorn_http/ext_help.h +0 -44
  39. data/ext/unicorn_http/extconf.rb +32 -6
  40. data/ext/unicorn_http/global_variables.h +2 -2
  41. data/ext/unicorn_http/httpdate.c +2 -1
  42. data/ext/unicorn_http/unicorn_http.c +853 -498
  43. data/ext/unicorn_http/unicorn_http.rl +86 -30
  44. data/ext/unicorn_http/unicorn_http_common.rl +1 -1
  45. data/lib/unicorn/configurator.rb +93 -13
  46. data/lib/unicorn/http_request.rb +101 -11
  47. data/lib/unicorn/http_response.rb +8 -4
  48. data/lib/unicorn/http_server.rb +141 -72
  49. data/lib/unicorn/launcher.rb +1 -1
  50. data/lib/unicorn/oob_gc.rb +6 -6
  51. data/lib/unicorn/select_waiter.rb +6 -0
  52. data/lib/unicorn/socket_helper.rb +23 -7
  53. data/lib/unicorn/stream_input.rb +5 -4
  54. data/lib/unicorn/tee_input.rb +8 -10
  55. data/lib/unicorn/tmpio.rb +8 -2
  56. data/lib/unicorn/util.rb +3 -3
  57. data/lib/unicorn/version.rb +1 -1
  58. data/lib/unicorn/worker.rb +33 -8
  59. data/lib/unicorn.rb +55 -29
  60. data/man/man1/unicorn.1 +120 -118
  61. data/man/man1/unicorn_rails.1 +106 -107
  62. data/t/GNUmakefile +3 -72
  63. data/t/README +4 -4
  64. data/t/t0011-active-unix-socket.sh +1 -1
  65. data/t/t0012-reload-empty-config.sh +2 -1
  66. data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
  67. data/t/t0301.ru +13 -0
  68. data/t/test-lib.sh +4 -3
  69. data/test/benchmark/README +14 -4
  70. data/test/benchmark/ddstream.ru +50 -0
  71. data/test/benchmark/readinput.ru +40 -0
  72. data/test/benchmark/uconnect.perl +66 -0
  73. data/test/exec/test_exec.rb +26 -24
  74. data/test/test_helper.rb +38 -30
  75. data/test/unit/test_ccc.rb +91 -0
  76. data/test/unit/test_droplet.rb +1 -1
  77. data/test/unit/test_http_parser.rb +46 -16
  78. data/test/unit/test_http_parser_ng.rb +81 -0
  79. data/test/unit/test_request.rb +10 -10
  80. data/test/unit/test_server.rb +86 -12
  81. data/test/unit/test_signals.rb +8 -8
  82. data/test/unit/test_socket_helper.rb +13 -9
  83. data/test/unit/test_upload.rb +9 -14
  84. data/test/unit/test_util.rb +31 -5
  85. data/test/unit/test_waiter.rb +34 -0
  86. data/unicorn.gemspec +21 -22
  87. metadata +21 -28
  88. data/Documentation/GNUmakefile +0 -30
  89. data/Documentation/unicorn.1.txt +0 -188
  90. data/Documentation/unicorn_rails.1.txt +0 -175
  91. data/t/hijack.ru +0 -43
  92. data/t/t0200-rack-hijack.sh +0 -30
@@ -14,6 +14,7 @@
14
14
  #include "common_field_optimization.h"
15
15
  #include "global_variables.h"
16
16
  #include "c_util.h"
17
+ #include "epollexclusive.h"
17
18
 
18
19
  void init_unicorn_httpdate(void);
19
20
 
@@ -28,6 +29,7 @@ void init_unicorn_httpdate(void);
28
29
  #define UH_FL_HASHEADER 0x100
29
30
  #define UH_FL_TO_CLEAR 0x200
30
31
  #define UH_FL_RESSTART 0x400 /* for check_client_connection */
32
+ #define UH_FL_HIJACK 0x800
31
33
 
32
34
  /* all of these flags need to be set for keepalive to be supported */
33
35
  #define UH_FL_KEEPALIVE (UH_FL_KAVERSION | UH_FL_REQEOF | UH_FL_HASHEADER)
@@ -63,19 +65,8 @@ struct http_parser {
63
65
  } len;
64
66
  };
65
67
 
66
- static ID id_set_backtrace;
67
-
68
- #ifdef HAVE_RB_HASH_CLEAR /* Ruby >= 2.0 */
69
- # define my_hash_clear(h) (void)rb_hash_clear(h)
70
- #else /* !HAVE_RB_HASH_CLEAR - Ruby <= 1.9.3 */
71
-
72
- static ID id_clear;
73
-
74
- static void my_hash_clear(VALUE h)
75
- {
76
- rb_funcall(h, id_clear, 0);
77
- }
78
- #endif /* HAVE_RB_HASH_CLEAR */
68
+ static ID id_set_backtrace, id_is_chunked_p;
69
+ static VALUE cHttpParser;
79
70
 
80
71
  static void finalize_header(struct http_parser *hp);
81
72
 
@@ -221,6 +212,19 @@ static void write_cont_value(struct http_parser *hp,
221
212
  rb_str_buf_cat(hp->cont, vptr, end + 1);
222
213
  }
223
214
 
215
+ static int is_chunked(VALUE v)
216
+ {
217
+ /* common case first */
218
+ if (STR_CSTR_CASE_EQ(v, "chunked"))
219
+ return 1;
220
+
221
+ /*
222
+ * call Ruby function in unicorn/http_request.rb to deal with unlikely
223
+ * comma-delimited case
224
+ */
225
+ return rb_funcall(cHttpParser, id_is_chunked_p, 1, v) != Qfalse;
226
+ }
227
+
224
228
  static void write_value(struct http_parser *hp,
225
229
  const char *buffer, const char *p)
226
230
  {
@@ -247,7 +251,9 @@ static void write_value(struct http_parser *hp,
247
251
  f = uncommon_field(field, flen);
248
252
  } else if (f == g_http_connection) {
249
253
  hp_keepalive_connection(hp, v);
250
- } else if (f == g_content_length) {
254
+ } else if (f == g_content_length && !HP_FL_TEST(hp, CHUNKED)) {
255
+ if (hp->len.content)
256
+ parser_raise(eHttpParserError, "Content-Length already set");
251
257
  hp->len.content = parse_length(RSTRING_PTR(v), RSTRING_LEN(v));
252
258
  if (hp->len.content < 0)
253
259
  parser_raise(eHttpParserError, "invalid Content-Length");
@@ -255,9 +261,30 @@ static void write_value(struct http_parser *hp,
255
261
  HP_FL_SET(hp, HASBODY);
256
262
  hp_invalid_if_trailer(hp);
257
263
  } else if (f == g_http_transfer_encoding) {
258
- if (STR_CSTR_CASE_EQ(v, "chunked")) {
264
+ if (is_chunked(v)) {
265
+ if (HP_FL_TEST(hp, CHUNKED))
266
+ /*
267
+ * RFC 7230 3.3.1:
268
+ * A sender MUST NOT apply chunked more than once to a message body
269
+ * (i.e., chunking an already chunked message is not allowed).
270
+ */
271
+ parser_raise(eHttpParserError, "Transfer-Encoding double chunked");
272
+
259
273
  HP_FL_SET(hp, CHUNKED);
260
274
  HP_FL_SET(hp, HASBODY);
275
+
276
+ /* RFC 7230 3.3.3, 3: favor chunked if Content-Length exists */
277
+ hp->len.content = 0;
278
+ } else if (HP_FL_TEST(hp, CHUNKED)) {
279
+ /*
280
+ * RFC 7230 3.3.3, point 3 states:
281
+ * If a Transfer-Encoding header field is present in a request and
282
+ * the chunked transfer coding is not the final encoding, the
283
+ * message body length cannot be determined reliably; the server
284
+ * MUST respond with the 400 (Bad Request) status code and then
285
+ * close the connection.
286
+ */
287
+ parser_raise(eHttpParserError, "invalid Transfer-Encoding");
261
288
  }
262
289
  hp_invalid_if_trailer(hp);
263
290
  } else if (f == g_http_trailer) {
@@ -286,23 +313,23 @@ static void write_value(struct http_parser *hp,
286
313
  /** Machine **/
287
314
 
288
315
 
289
- #line 393 "unicorn_http.rl"
316
+ #line 420 "unicorn_http.rl"
290
317
 
291
318
 
292
319
  /** Data **/
293
320
 
294
- #line 295 "unicorn_http.c"
321
+ #line 322 "unicorn_http.c"
295
322
  static const int http_parser_start = 1;
296
323
  static const int http_parser_first_final = 122;
297
324
  static const int http_parser_error = 0;
298
325
 
299
326
  static const int http_parser_en_ChunkedBody = 100;
300
- static const int http_parser_en_ChunkedBody_chunk_chunk_end = 106;
327
+ static const int http_parser_en_ChunkedBody_chunk_chunk_end = 105;
301
328
  static const int http_parser_en_Trailers = 114;
302
329
  static const int http_parser_en_main = 1;
303
330
 
304
331
 
305
- #line 397 "unicorn_http.rl"
332
+ #line 424 "unicorn_http.rl"
306
333
 
307
334
  static void http_parser_init(struct http_parser *hp)
308
335
  {
@@ -315,12 +342,12 @@ static void http_parser_init(struct http_parser *hp)
315
342
  hp->len.content = 0;
316
343
  hp->cont = Qfalse; /* zero on MRI, should be optimized away by above */
317
344
 
318
- #line 319 "unicorn_http.c"
345
+ #line 346 "unicorn_http.c"
319
346
  {
320
347
  cs = http_parser_start;
321
348
  }
322
349
 
323
- #line 409 "unicorn_http.rl"
350
+ #line 436 "unicorn_http.rl"
324
351
  hp->cs = cs;
325
352
  }
326
353
 
@@ -348,7 +375,7 @@ http_parser_execute(struct http_parser *hp, char *buffer, size_t len)
348
375
  goto skip_chunk_data_hack;
349
376
  }
350
377
 
351
- #line 352 "unicorn_http.c"
378
+ #line 379 "unicorn_http.c"
352
379
  {
353
380
  if ( p == pe )
354
381
  goto _test_eof;
@@ -383,14 +410,14 @@ st0:
383
410
  cs = 0;
384
411
  goto _out;
385
412
  tr0:
386
- #line 289 "unicorn_http.rl"
413
+ #line 316 "unicorn_http.rl"
387
414
  {MARK(mark, p); }
388
415
  goto st2;
389
416
  st2:
390
417
  if ( ++p == pe )
391
418
  goto _test_eof2;
392
419
  case 2:
393
- #line 394 "unicorn_http.c"
420
+ #line 421 "unicorn_http.c"
394
421
  switch( (*p) ) {
395
422
  case 32: goto tr3;
396
423
  case 33: goto st49;
@@ -416,14 +443,14 @@ case 2:
416
443
  goto st49;
417
444
  goto st0;
418
445
  tr3:
419
- #line 298 "unicorn_http.rl"
446
+ #line 325 "unicorn_http.rl"
420
447
  { request_method(hp, PTR_TO(mark), LEN(mark, p)); }
421
448
  goto st3;
422
449
  st3:
423
450
  if ( ++p == pe )
424
451
  goto _test_eof3;
425
452
  case 3:
426
- #line 427 "unicorn_http.c"
453
+ #line 454 "unicorn_http.c"
427
454
  switch( (*p) ) {
428
455
  case 42: goto tr5;
429
456
  case 47: goto tr6;
@@ -432,21 +459,21 @@ case 3:
432
459
  }
433
460
  goto st0;
434
461
  tr5:
435
- #line 289 "unicorn_http.rl"
462
+ #line 316 "unicorn_http.rl"
436
463
  {MARK(mark, p); }
437
464
  goto st4;
438
465
  st4:
439
466
  if ( ++p == pe )
440
467
  goto _test_eof4;
441
468
  case 4:
442
- #line 443 "unicorn_http.c"
469
+ #line 470 "unicorn_http.c"
443
470
  switch( (*p) ) {
444
471
  case 32: goto tr8;
445
472
  case 35: goto tr9;
446
473
  }
447
474
  goto st0;
448
475
  tr8:
449
- #line 303 "unicorn_http.rl"
476
+ #line 330 "unicorn_http.rl"
450
477
  {
451
478
  VALUE str;
452
479
 
@@ -463,24 +490,24 @@ tr8:
463
490
  }
464
491
  }
465
492
  goto st5;
466
- tr37:
467
- #line 289 "unicorn_http.rl"
493
+ tr42:
494
+ #line 316 "unicorn_http.rl"
468
495
  {MARK(mark, p); }
469
- #line 318 "unicorn_http.rl"
496
+ #line 345 "unicorn_http.rl"
470
497
  {
471
498
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
472
499
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
473
500
  }
474
501
  goto st5;
475
- tr40:
476
- #line 318 "unicorn_http.rl"
502
+ tr45:
503
+ #line 345 "unicorn_http.rl"
477
504
  {
478
505
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
479
506
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
480
507
  }
481
508
  goto st5;
482
- tr44:
483
- #line 328 "unicorn_http.rl"
509
+ tr49:
510
+ #line 355 "unicorn_http.rl"
484
511
  {
485
512
  VALUE val;
486
513
 
@@ -491,7 +518,7 @@ tr44:
491
518
  if (!STR_CSTR_EQ(val, "*"))
492
519
  rb_hash_aset(hp->env, g_path_info, val);
493
520
  }
494
- #line 303 "unicorn_http.rl"
521
+ #line 330 "unicorn_http.rl"
495
522
  {
496
523
  VALUE str;
497
524
 
@@ -508,15 +535,15 @@ tr44:
508
535
  }
509
536
  }
510
537
  goto st5;
511
- tr50:
512
- #line 322 "unicorn_http.rl"
538
+ tr55:
539
+ #line 349 "unicorn_http.rl"
513
540
  {MARK(start.query, p); }
514
- #line 323 "unicorn_http.rl"
541
+ #line 350 "unicorn_http.rl"
515
542
  {
516
543
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
517
544
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
518
545
  }
519
- #line 303 "unicorn_http.rl"
546
+ #line 330 "unicorn_http.rl"
520
547
  {
521
548
  VALUE str;
522
549
 
@@ -533,13 +560,13 @@ tr50:
533
560
  }
534
561
  }
535
562
  goto st5;
536
- tr54:
537
- #line 323 "unicorn_http.rl"
563
+ tr59:
564
+ #line 350 "unicorn_http.rl"
538
565
  {
539
566
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
540
567
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
541
568
  }
542
- #line 303 "unicorn_http.rl"
569
+ #line 330 "unicorn_http.rl"
543
570
  {
544
571
  VALUE str;
545
572
 
@@ -560,19 +587,19 @@ st5:
560
587
  if ( ++p == pe )
561
588
  goto _test_eof5;
562
589
  case 5:
563
- #line 564 "unicorn_http.c"
590
+ #line 591 "unicorn_http.c"
564
591
  if ( (*p) == 72 )
565
592
  goto tr10;
566
593
  goto st0;
567
594
  tr10:
568
- #line 289 "unicorn_http.rl"
595
+ #line 316 "unicorn_http.rl"
569
596
  {MARK(mark, p); }
570
597
  goto st6;
571
598
  st6:
572
599
  if ( ++p == pe )
573
600
  goto _test_eof6;
574
601
  case 6:
575
- #line 576 "unicorn_http.c"
602
+ #line 603 "unicorn_http.c"
576
603
  if ( (*p) == 84 )
577
604
  goto st7;
578
605
  goto st0;
@@ -624,112 +651,163 @@ st13:
624
651
  if ( ++p == pe )
625
652
  goto _test_eof13;
626
653
  case 13:
627
- if ( (*p) == 13 )
628
- goto tr18;
654
+ switch( (*p) ) {
655
+ case 10: goto tr18;
656
+ case 13: goto tr19;
657
+ }
629
658
  if ( 48 <= (*p) && (*p) <= 57 )
630
659
  goto st13;
631
660
  goto st0;
632
661
  tr18:
633
- #line 327 "unicorn_http.rl"
662
+ #line 354 "unicorn_http.rl"
634
663
  { http_version(hp, PTR_TO(mark), LEN(mark, p)); }
635
664
  goto st14;
636
- tr25:
637
- #line 295 "unicorn_http.rl"
665
+ tr26:
666
+ #line 322 "unicorn_http.rl"
638
667
  { MARK(mark, p); }
639
- #line 297 "unicorn_http.rl"
668
+ #line 324 "unicorn_http.rl"
640
669
  { write_cont_value(hp, buffer, p); }
641
670
  goto st14;
642
- tr27:
643
- #line 297 "unicorn_http.rl"
671
+ tr29:
672
+ #line 324 "unicorn_http.rl"
644
673
  { write_cont_value(hp, buffer, p); }
645
674
  goto st14;
646
- tr33:
647
- #line 295 "unicorn_http.rl"
675
+ tr36:
676
+ #line 322 "unicorn_http.rl"
648
677
  { MARK(mark, p); }
649
- #line 296 "unicorn_http.rl"
678
+ #line 323 "unicorn_http.rl"
650
679
  { write_value(hp, buffer, p); }
651
680
  goto st14;
652
- tr35:
653
- #line 296 "unicorn_http.rl"
681
+ tr39:
682
+ #line 323 "unicorn_http.rl"
654
683
  { write_value(hp, buffer, p); }
655
684
  goto st14;
656
685
  st14:
657
686
  if ( ++p == pe )
658
687
  goto _test_eof14;
659
688
  case 14:
660
- #line 661 "unicorn_http.c"
661
- if ( (*p) == 10 )
662
- goto st15;
663
- goto st0;
664
- st15:
665
- if ( ++p == pe )
666
- goto _test_eof15;
667
- case 15:
689
+ #line 690 "unicorn_http.c"
668
690
  switch( (*p) ) {
669
- case 9: goto st16;
691
+ case 9: goto st15;
692
+ case 10: goto tr21;
670
693
  case 13: goto st18;
671
- case 32: goto st16;
672
- case 33: goto tr22;
673
- case 124: goto tr22;
674
- case 126: goto tr22;
694
+ case 32: goto st15;
695
+ case 33: goto tr23;
696
+ case 124: goto tr23;
697
+ case 126: goto tr23;
675
698
  }
676
699
  if ( (*p) < 45 ) {
677
700
  if ( (*p) > 39 ) {
678
701
  if ( 42 <= (*p) && (*p) <= 43 )
679
- goto tr22;
702
+ goto tr23;
680
703
  } else if ( (*p) >= 35 )
681
- goto tr22;
704
+ goto tr23;
682
705
  } else if ( (*p) > 46 ) {
683
706
  if ( (*p) < 65 ) {
684
707
  if ( 48 <= (*p) && (*p) <= 57 )
685
- goto tr22;
708
+ goto tr23;
686
709
  } else if ( (*p) > 90 ) {
687
710
  if ( 94 <= (*p) && (*p) <= 122 )
688
- goto tr22;
711
+ goto tr23;
689
712
  } else
690
- goto tr22;
713
+ goto tr23;
691
714
  } else
692
- goto tr22;
715
+ goto tr23;
693
716
  goto st0;
694
- tr24:
695
- #line 295 "unicorn_http.rl"
717
+ tr25:
718
+ #line 322 "unicorn_http.rl"
696
719
  { MARK(mark, p); }
697
- goto st16;
698
- st16:
720
+ goto st15;
721
+ st15:
699
722
  if ( ++p == pe )
700
- goto _test_eof16;
701
- case 16:
702
- #line 703 "unicorn_http.c"
723
+ goto _test_eof15;
724
+ case 15:
725
+ #line 726 "unicorn_http.c"
703
726
  switch( (*p) ) {
704
- case 9: goto tr24;
705
- case 13: goto tr25;
706
- case 32: goto tr24;
727
+ case 9: goto tr25;
728
+ case 10: goto tr26;
729
+ case 13: goto tr27;
730
+ case 32: goto tr25;
707
731
  case 127: goto st0;
708
732
  }
709
733
  if ( 0 <= (*p) && (*p) <= 31 )
710
734
  goto st0;
711
- goto tr23;
712
- tr23:
713
- #line 295 "unicorn_http.rl"
735
+ goto tr24;
736
+ tr24:
737
+ #line 322 "unicorn_http.rl"
714
738
  { MARK(mark, p); }
715
- goto st17;
716
- st17:
739
+ goto st16;
740
+ st16:
717
741
  if ( ++p == pe )
718
- goto _test_eof17;
719
- case 17:
720
- #line 721 "unicorn_http.c"
742
+ goto _test_eof16;
743
+ case 16:
744
+ #line 745 "unicorn_http.c"
721
745
  switch( (*p) ) {
722
- case 13: goto tr27;
746
+ case 10: goto tr29;
747
+ case 13: goto tr30;
723
748
  case 127: goto st0;
724
749
  }
725
750
  if ( (*p) > 8 ) {
726
- if ( 10 <= (*p) && (*p) <= 31 )
751
+ if ( 11 <= (*p) && (*p) <= 31 )
727
752
  goto st0;
728
753
  } else if ( (*p) >= 0 )
729
754
  goto st0;
755
+ goto st16;
756
+ tr19:
757
+ #line 354 "unicorn_http.rl"
758
+ { http_version(hp, PTR_TO(mark), LEN(mark, p)); }
759
+ goto st17;
760
+ tr27:
761
+ #line 322 "unicorn_http.rl"
762
+ { MARK(mark, p); }
763
+ #line 324 "unicorn_http.rl"
764
+ { write_cont_value(hp, buffer, p); }
765
+ goto st17;
766
+ tr30:
767
+ #line 324 "unicorn_http.rl"
768
+ { write_cont_value(hp, buffer, p); }
769
+ goto st17;
770
+ tr37:
771
+ #line 322 "unicorn_http.rl"
772
+ { MARK(mark, p); }
773
+ #line 323 "unicorn_http.rl"
774
+ { write_value(hp, buffer, p); }
775
+ goto st17;
776
+ tr40:
777
+ #line 323 "unicorn_http.rl"
778
+ { write_value(hp, buffer, p); }
730
779
  goto st17;
731
- tr99:
732
- #line 303 "unicorn_http.rl"
780
+ st17:
781
+ if ( ++p == pe )
782
+ goto _test_eof17;
783
+ case 17:
784
+ #line 785 "unicorn_http.c"
785
+ if ( (*p) == 10 )
786
+ goto st14;
787
+ goto st0;
788
+ tr21:
789
+ #line 370 "unicorn_http.rl"
790
+ {
791
+ finalize_header(hp);
792
+
793
+ cs = http_parser_first_final;
794
+ if (HP_FL_TEST(hp, HASBODY)) {
795
+ HP_FL_SET(hp, INBODY);
796
+ if (HP_FL_TEST(hp, CHUNKED))
797
+ cs = http_parser_en_ChunkedBody;
798
+ } else {
799
+ HP_FL_SET(hp, REQEOF);
800
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
801
+ }
802
+ /*
803
+ * go back to Ruby so we can call the Rack application, we'll reenter
804
+ * the parser iff the body needs to be processed.
805
+ */
806
+ goto post_exec;
807
+ }
808
+ goto st122;
809
+ tr104:
810
+ #line 330 "unicorn_http.rl"
733
811
  {
734
812
  VALUE str;
735
813
 
@@ -745,25 +823,82 @@ tr99:
745
823
  rb_hash_aset(hp->env, g_request_path, str);
746
824
  }
747
825
  }
748
- goto st18;
749
- tr102:
750
- #line 289 "unicorn_http.rl"
826
+ #line 370 "unicorn_http.rl"
827
+ {
828
+ finalize_header(hp);
829
+
830
+ cs = http_parser_first_final;
831
+ if (HP_FL_TEST(hp, HASBODY)) {
832
+ HP_FL_SET(hp, INBODY);
833
+ if (HP_FL_TEST(hp, CHUNKED))
834
+ cs = http_parser_en_ChunkedBody;
835
+ } else {
836
+ HP_FL_SET(hp, REQEOF);
837
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
838
+ }
839
+ /*
840
+ * go back to Ruby so we can call the Rack application, we'll reenter
841
+ * the parser iff the body needs to be processed.
842
+ */
843
+ goto post_exec;
844
+ }
845
+ goto st122;
846
+ tr108:
847
+ #line 316 "unicorn_http.rl"
751
848
  {MARK(mark, p); }
752
- #line 318 "unicorn_http.rl"
849
+ #line 345 "unicorn_http.rl"
753
850
  {
754
851
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
755
852
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
756
853
  }
757
- goto st18;
758
- tr105:
759
- #line 318 "unicorn_http.rl"
854
+ #line 370 "unicorn_http.rl"
855
+ {
856
+ finalize_header(hp);
857
+
858
+ cs = http_parser_first_final;
859
+ if (HP_FL_TEST(hp, HASBODY)) {
860
+ HP_FL_SET(hp, INBODY);
861
+ if (HP_FL_TEST(hp, CHUNKED))
862
+ cs = http_parser_en_ChunkedBody;
863
+ } else {
864
+ HP_FL_SET(hp, REQEOF);
865
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
866
+ }
867
+ /*
868
+ * go back to Ruby so we can call the Rack application, we'll reenter
869
+ * the parser iff the body needs to be processed.
870
+ */
871
+ goto post_exec;
872
+ }
873
+ goto st122;
874
+ tr112:
875
+ #line 345 "unicorn_http.rl"
760
876
  {
761
877
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
762
878
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
763
879
  }
764
- goto st18;
765
- tr109:
766
- #line 328 "unicorn_http.rl"
880
+ #line 370 "unicorn_http.rl"
881
+ {
882
+ finalize_header(hp);
883
+
884
+ cs = http_parser_first_final;
885
+ if (HP_FL_TEST(hp, HASBODY)) {
886
+ HP_FL_SET(hp, INBODY);
887
+ if (HP_FL_TEST(hp, CHUNKED))
888
+ cs = http_parser_en_ChunkedBody;
889
+ } else {
890
+ HP_FL_SET(hp, REQEOF);
891
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
892
+ }
893
+ /*
894
+ * go back to Ruby so we can call the Rack application, we'll reenter
895
+ * the parser iff the body needs to be processed.
896
+ */
897
+ goto post_exec;
898
+ }
899
+ goto st122;
900
+ tr117:
901
+ #line 355 "unicorn_http.rl"
767
902
  {
768
903
  VALUE val;
769
904
 
@@ -774,7 +909,7 @@ tr109:
774
909
  if (!STR_CSTR_EQ(val, "*"))
775
910
  rb_hash_aset(hp->env, g_path_info, val);
776
911
  }
777
- #line 303 "unicorn_http.rl"
912
+ #line 330 "unicorn_http.rl"
778
913
  {
779
914
  VALUE str;
780
915
 
@@ -790,16 +925,35 @@ tr109:
790
925
  rb_hash_aset(hp->env, g_request_path, str);
791
926
  }
792
927
  }
793
- goto st18;
794
- tr115:
795
- #line 322 "unicorn_http.rl"
928
+ #line 370 "unicorn_http.rl"
929
+ {
930
+ finalize_header(hp);
931
+
932
+ cs = http_parser_first_final;
933
+ if (HP_FL_TEST(hp, HASBODY)) {
934
+ HP_FL_SET(hp, INBODY);
935
+ if (HP_FL_TEST(hp, CHUNKED))
936
+ cs = http_parser_en_ChunkedBody;
937
+ } else {
938
+ HP_FL_SET(hp, REQEOF);
939
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
940
+ }
941
+ /*
942
+ * go back to Ruby so we can call the Rack application, we'll reenter
943
+ * the parser iff the body needs to be processed.
944
+ */
945
+ goto post_exec;
946
+ }
947
+ goto st122;
948
+ tr124:
949
+ #line 349 "unicorn_http.rl"
796
950
  {MARK(start.query, p); }
797
- #line 323 "unicorn_http.rl"
951
+ #line 350 "unicorn_http.rl"
798
952
  {
799
953
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
800
954
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
801
955
  }
802
- #line 303 "unicorn_http.rl"
956
+ #line 330 "unicorn_http.rl"
803
957
  {
804
958
  VALUE str;
805
959
 
@@ -815,14 +969,33 @@ tr115:
815
969
  rb_hash_aset(hp->env, g_request_path, str);
816
970
  }
817
971
  }
818
- goto st18;
819
- tr119:
820
- #line 323 "unicorn_http.rl"
972
+ #line 370 "unicorn_http.rl"
973
+ {
974
+ finalize_header(hp);
975
+
976
+ cs = http_parser_first_final;
977
+ if (HP_FL_TEST(hp, HASBODY)) {
978
+ HP_FL_SET(hp, INBODY);
979
+ if (HP_FL_TEST(hp, CHUNKED))
980
+ cs = http_parser_en_ChunkedBody;
981
+ } else {
982
+ HP_FL_SET(hp, REQEOF);
983
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
984
+ }
985
+ /*
986
+ * go back to Ruby so we can call the Rack application, we'll reenter
987
+ * the parser iff the body needs to be processed.
988
+ */
989
+ goto post_exec;
990
+ }
991
+ goto st122;
992
+ tr129:
993
+ #line 350 "unicorn_http.rl"
821
994
  {
822
995
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
823
996
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
824
997
  }
825
- #line 303 "unicorn_http.rl"
998
+ #line 330 "unicorn_http.rl"
826
999
  {
827
1000
  VALUE str;
828
1001
 
@@ -838,17 +1011,7 @@ tr119:
838
1011
  rb_hash_aset(hp->env, g_request_path, str);
839
1012
  }
840
1013
  }
841
- goto st18;
842
- st18:
843
- if ( ++p == pe )
844
- goto _test_eof18;
845
- case 18:
846
- #line 847 "unicorn_http.c"
847
- if ( (*p) == 10 )
848
- goto tr28;
849
- goto st0;
850
- tr28:
851
- #line 343 "unicorn_http.rl"
1014
+ #line 370 "unicorn_http.rl"
852
1015
  {
853
1016
  finalize_header(hp);
854
1017
 
@@ -872,90 +1035,211 @@ st122:
872
1035
  if ( ++p == pe )
873
1036
  goto _test_eof122;
874
1037
  case 122:
875
- #line 876 "unicorn_http.c"
1038
+ #line 1039 "unicorn_http.c"
876
1039
  goto st0;
877
- tr22:
878
- #line 291 "unicorn_http.rl"
1040
+ tr105:
1041
+ #line 330 "unicorn_http.rl"
1042
+ {
1043
+ VALUE str;
1044
+
1045
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1046
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1047
+ /*
1048
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1049
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1050
+ */
1051
+ if (STR_CSTR_EQ(str, "*")) {
1052
+ str = rb_str_new(NULL, 0);
1053
+ rb_hash_aset(hp->env, g_path_info, str);
1054
+ rb_hash_aset(hp->env, g_request_path, str);
1055
+ }
1056
+ }
1057
+ goto st18;
1058
+ tr109:
1059
+ #line 316 "unicorn_http.rl"
1060
+ {MARK(mark, p); }
1061
+ #line 345 "unicorn_http.rl"
1062
+ {
1063
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
1064
+ rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
1065
+ }
1066
+ goto st18;
1067
+ tr113:
1068
+ #line 345 "unicorn_http.rl"
1069
+ {
1070
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
1071
+ rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
1072
+ }
1073
+ goto st18;
1074
+ tr118:
1075
+ #line 355 "unicorn_http.rl"
1076
+ {
1077
+ VALUE val;
1078
+
1079
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
1080
+ val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
1081
+
1082
+ /* rack says PATH_INFO must start with "/" or be empty */
1083
+ if (!STR_CSTR_EQ(val, "*"))
1084
+ rb_hash_aset(hp->env, g_path_info, val);
1085
+ }
1086
+ #line 330 "unicorn_http.rl"
1087
+ {
1088
+ VALUE str;
1089
+
1090
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1091
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1092
+ /*
1093
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1094
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1095
+ */
1096
+ if (STR_CSTR_EQ(str, "*")) {
1097
+ str = rb_str_new(NULL, 0);
1098
+ rb_hash_aset(hp->env, g_path_info, str);
1099
+ rb_hash_aset(hp->env, g_request_path, str);
1100
+ }
1101
+ }
1102
+ goto st18;
1103
+ tr125:
1104
+ #line 349 "unicorn_http.rl"
1105
+ {MARK(start.query, p); }
1106
+ #line 350 "unicorn_http.rl"
1107
+ {
1108
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1109
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1110
+ }
1111
+ #line 330 "unicorn_http.rl"
1112
+ {
1113
+ VALUE str;
1114
+
1115
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1116
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1117
+ /*
1118
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1119
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1120
+ */
1121
+ if (STR_CSTR_EQ(str, "*")) {
1122
+ str = rb_str_new(NULL, 0);
1123
+ rb_hash_aset(hp->env, g_path_info, str);
1124
+ rb_hash_aset(hp->env, g_request_path, str);
1125
+ }
1126
+ }
1127
+ goto st18;
1128
+ tr130:
1129
+ #line 350 "unicorn_http.rl"
1130
+ {
1131
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1132
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1133
+ }
1134
+ #line 330 "unicorn_http.rl"
1135
+ {
1136
+ VALUE str;
1137
+
1138
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1139
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1140
+ /*
1141
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1142
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1143
+ */
1144
+ if (STR_CSTR_EQ(str, "*")) {
1145
+ str = rb_str_new(NULL, 0);
1146
+ rb_hash_aset(hp->env, g_path_info, str);
1147
+ rb_hash_aset(hp->env, g_request_path, str);
1148
+ }
1149
+ }
1150
+ goto st18;
1151
+ st18:
1152
+ if ( ++p == pe )
1153
+ goto _test_eof18;
1154
+ case 18:
1155
+ #line 1156 "unicorn_http.c"
1156
+ if ( (*p) == 10 )
1157
+ goto tr21;
1158
+ goto st0;
1159
+ tr23:
1160
+ #line 318 "unicorn_http.rl"
879
1161
  { MARK(start.field, p); }
880
- #line 292 "unicorn_http.rl"
1162
+ #line 319 "unicorn_http.rl"
881
1163
  { snake_upcase_char(deconst(p)); }
882
1164
  goto st19;
883
- tr29:
884
- #line 292 "unicorn_http.rl"
1165
+ tr32:
1166
+ #line 319 "unicorn_http.rl"
885
1167
  { snake_upcase_char(deconst(p)); }
886
1168
  goto st19;
887
1169
  st19:
888
1170
  if ( ++p == pe )
889
1171
  goto _test_eof19;
890
1172
  case 19:
891
- #line 892 "unicorn_http.c"
1173
+ #line 1174 "unicorn_http.c"
892
1174
  switch( (*p) ) {
893
- case 33: goto tr29;
894
- case 58: goto tr30;
895
- case 124: goto tr29;
896
- case 126: goto tr29;
1175
+ case 33: goto tr32;
1176
+ case 58: goto tr33;
1177
+ case 124: goto tr32;
1178
+ case 126: goto tr32;
897
1179
  }
898
1180
  if ( (*p) < 45 ) {
899
1181
  if ( (*p) > 39 ) {
900
1182
  if ( 42 <= (*p) && (*p) <= 43 )
901
- goto tr29;
1183
+ goto tr32;
902
1184
  } else if ( (*p) >= 35 )
903
- goto tr29;
1185
+ goto tr32;
904
1186
  } else if ( (*p) > 46 ) {
905
1187
  if ( (*p) < 65 ) {
906
1188
  if ( 48 <= (*p) && (*p) <= 57 )
907
- goto tr29;
1189
+ goto tr32;
908
1190
  } else if ( (*p) > 90 ) {
909
1191
  if ( 94 <= (*p) && (*p) <= 122 )
910
- goto tr29;
1192
+ goto tr32;
911
1193
  } else
912
- goto tr29;
1194
+ goto tr32;
913
1195
  } else
914
- goto tr29;
1196
+ goto tr32;
915
1197
  goto st0;
916
- tr32:
917
- #line 295 "unicorn_http.rl"
1198
+ tr35:
1199
+ #line 322 "unicorn_http.rl"
918
1200
  { MARK(mark, p); }
919
1201
  goto st20;
920
- tr30:
921
- #line 294 "unicorn_http.rl"
1202
+ tr33:
1203
+ #line 321 "unicorn_http.rl"
922
1204
  { hp->s.field_len = LEN(start.field, p); }
923
1205
  goto st20;
924
1206
  st20:
925
1207
  if ( ++p == pe )
926
1208
  goto _test_eof20;
927
1209
  case 20:
928
- #line 929 "unicorn_http.c"
1210
+ #line 1211 "unicorn_http.c"
929
1211
  switch( (*p) ) {
930
- case 9: goto tr32;
931
- case 13: goto tr33;
932
- case 32: goto tr32;
1212
+ case 9: goto tr35;
1213
+ case 10: goto tr36;
1214
+ case 13: goto tr37;
1215
+ case 32: goto tr35;
933
1216
  case 127: goto st0;
934
1217
  }
935
1218
  if ( 0 <= (*p) && (*p) <= 31 )
936
1219
  goto st0;
937
- goto tr31;
938
- tr31:
939
- #line 295 "unicorn_http.rl"
1220
+ goto tr34;
1221
+ tr34:
1222
+ #line 322 "unicorn_http.rl"
940
1223
  { MARK(mark, p); }
941
1224
  goto st21;
942
1225
  st21:
943
1226
  if ( ++p == pe )
944
1227
  goto _test_eof21;
945
1228
  case 21:
946
- #line 947 "unicorn_http.c"
1229
+ #line 1230 "unicorn_http.c"
947
1230
  switch( (*p) ) {
948
- case 13: goto tr35;
1231
+ case 10: goto tr39;
1232
+ case 13: goto tr40;
949
1233
  case 127: goto st0;
950
1234
  }
951
1235
  if ( (*p) > 8 ) {
952
- if ( 10 <= (*p) && (*p) <= 31 )
1236
+ if ( 11 <= (*p) && (*p) <= 31 )
953
1237
  goto st0;
954
1238
  } else if ( (*p) >= 0 )
955
1239
  goto st0;
956
1240
  goto st21;
957
1241
  tr9:
958
- #line 303 "unicorn_http.rl"
1242
+ #line 330 "unicorn_http.rl"
959
1243
  {
960
1244
  VALUE str;
961
1245
 
@@ -972,8 +1256,8 @@ tr9:
972
1256
  }
973
1257
  }
974
1258
  goto st22;
975
- tr45:
976
- #line 328 "unicorn_http.rl"
1259
+ tr50:
1260
+ #line 355 "unicorn_http.rl"
977
1261
  {
978
1262
  VALUE val;
979
1263
 
@@ -984,7 +1268,7 @@ tr45:
984
1268
  if (!STR_CSTR_EQ(val, "*"))
985
1269
  rb_hash_aset(hp->env, g_path_info, val);
986
1270
  }
987
- #line 303 "unicorn_http.rl"
1271
+ #line 330 "unicorn_http.rl"
988
1272
  {
989
1273
  VALUE str;
990
1274
 
@@ -1001,15 +1285,15 @@ tr45:
1001
1285
  }
1002
1286
  }
1003
1287
  goto st22;
1004
- tr51:
1005
- #line 322 "unicorn_http.rl"
1288
+ tr56:
1289
+ #line 349 "unicorn_http.rl"
1006
1290
  {MARK(start.query, p); }
1007
- #line 323 "unicorn_http.rl"
1291
+ #line 350 "unicorn_http.rl"
1008
1292
  {
1009
1293
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1010
1294
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1011
1295
  }
1012
- #line 303 "unicorn_http.rl"
1296
+ #line 330 "unicorn_http.rl"
1013
1297
  {
1014
1298
  VALUE str;
1015
1299
 
@@ -1026,13 +1310,13 @@ tr51:
1026
1310
  }
1027
1311
  }
1028
1312
  goto st22;
1029
- tr55:
1030
- #line 323 "unicorn_http.rl"
1313
+ tr60:
1314
+ #line 350 "unicorn_http.rl"
1031
1315
  {
1032
1316
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1033
1317
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1034
1318
  }
1035
- #line 303 "unicorn_http.rl"
1319
+ #line 330 "unicorn_http.rl"
1036
1320
  {
1037
1321
  VALUE str;
1038
1322
 
@@ -1053,27 +1337,27 @@ st22:
1053
1337
  if ( ++p == pe )
1054
1338
  goto _test_eof22;
1055
1339
  case 22:
1056
- #line 1057 "unicorn_http.c"
1340
+ #line 1341 "unicorn_http.c"
1057
1341
  switch( (*p) ) {
1058
- case 32: goto tr37;
1342
+ case 32: goto tr42;
1059
1343
  case 35: goto st0;
1060
- case 37: goto tr38;
1344
+ case 37: goto tr43;
1061
1345
  case 127: goto st0;
1062
1346
  }
1063
1347
  if ( 0 <= (*p) && (*p) <= 31 )
1064
1348
  goto st0;
1065
- goto tr36;
1066
- tr36:
1067
- #line 289 "unicorn_http.rl"
1349
+ goto tr41;
1350
+ tr41:
1351
+ #line 316 "unicorn_http.rl"
1068
1352
  {MARK(mark, p); }
1069
1353
  goto st23;
1070
1354
  st23:
1071
1355
  if ( ++p == pe )
1072
1356
  goto _test_eof23;
1073
1357
  case 23:
1074
- #line 1075 "unicorn_http.c"
1358
+ #line 1359 "unicorn_http.c"
1075
1359
  switch( (*p) ) {
1076
- case 32: goto tr40;
1360
+ case 32: goto tr45;
1077
1361
  case 35: goto st0;
1078
1362
  case 37: goto st24;
1079
1363
  case 127: goto st0;
@@ -1081,15 +1365,15 @@ case 23:
1081
1365
  if ( 0 <= (*p) && (*p) <= 31 )
1082
1366
  goto st0;
1083
1367
  goto st23;
1084
- tr38:
1085
- #line 289 "unicorn_http.rl"
1368
+ tr43:
1369
+ #line 316 "unicorn_http.rl"
1086
1370
  {MARK(mark, p); }
1087
1371
  goto st24;
1088
1372
  st24:
1089
1373
  if ( ++p == pe )
1090
1374
  goto _test_eof24;
1091
1375
  case 24:
1092
- #line 1093 "unicorn_http.c"
1376
+ #line 1377 "unicorn_http.c"
1093
1377
  if ( (*p) < 65 ) {
1094
1378
  if ( 48 <= (*p) && (*p) <= 57 )
1095
1379
  goto st25;
@@ -1113,25 +1397,25 @@ case 25:
1113
1397
  goto st23;
1114
1398
  goto st0;
1115
1399
  tr6:
1116
- #line 289 "unicorn_http.rl"
1400
+ #line 316 "unicorn_http.rl"
1117
1401
  {MARK(mark, p); }
1118
1402
  goto st26;
1119
- tr71:
1120
- #line 302 "unicorn_http.rl"
1403
+ tr76:
1404
+ #line 329 "unicorn_http.rl"
1121
1405
  { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
1122
- #line 289 "unicorn_http.rl"
1406
+ #line 316 "unicorn_http.rl"
1123
1407
  {MARK(mark, p); }
1124
1408
  goto st26;
1125
1409
  st26:
1126
1410
  if ( ++p == pe )
1127
1411
  goto _test_eof26;
1128
1412
  case 26:
1129
- #line 1130 "unicorn_http.c"
1413
+ #line 1414 "unicorn_http.c"
1130
1414
  switch( (*p) ) {
1131
- case 32: goto tr44;
1132
- case 35: goto tr45;
1415
+ case 32: goto tr49;
1416
+ case 35: goto tr50;
1133
1417
  case 37: goto st27;
1134
- case 63: goto tr47;
1418
+ case 63: goto tr52;
1135
1419
  case 127: goto st0;
1136
1420
  }
1137
1421
  if ( 0 <= (*p) && (*p) <= 31 )
@@ -1163,8 +1447,8 @@ case 28:
1163
1447
  } else
1164
1448
  goto st26;
1165
1449
  goto st0;
1166
- tr47:
1167
- #line 328 "unicorn_http.rl"
1450
+ tr52:
1451
+ #line 355 "unicorn_http.rl"
1168
1452
  {
1169
1453
  VALUE val;
1170
1454
 
@@ -1180,43 +1464,43 @@ st29:
1180
1464
  if ( ++p == pe )
1181
1465
  goto _test_eof29;
1182
1466
  case 29:
1183
- #line 1184 "unicorn_http.c"
1467
+ #line 1468 "unicorn_http.c"
1184
1468
  switch( (*p) ) {
1185
- case 32: goto tr50;
1186
- case 35: goto tr51;
1187
- case 37: goto tr52;
1469
+ case 32: goto tr55;
1470
+ case 35: goto tr56;
1471
+ case 37: goto tr57;
1188
1472
  case 127: goto st0;
1189
1473
  }
1190
1474
  if ( 0 <= (*p) && (*p) <= 31 )
1191
1475
  goto st0;
1192
- goto tr49;
1193
- tr49:
1194
- #line 322 "unicorn_http.rl"
1476
+ goto tr54;
1477
+ tr54:
1478
+ #line 349 "unicorn_http.rl"
1195
1479
  {MARK(start.query, p); }
1196
1480
  goto st30;
1197
1481
  st30:
1198
1482
  if ( ++p == pe )
1199
1483
  goto _test_eof30;
1200
1484
  case 30:
1201
- #line 1202 "unicorn_http.c"
1485
+ #line 1486 "unicorn_http.c"
1202
1486
  switch( (*p) ) {
1203
- case 32: goto tr54;
1204
- case 35: goto tr55;
1487
+ case 32: goto tr59;
1488
+ case 35: goto tr60;
1205
1489
  case 37: goto st31;
1206
1490
  case 127: goto st0;
1207
1491
  }
1208
1492
  if ( 0 <= (*p) && (*p) <= 31 )
1209
1493
  goto st0;
1210
1494
  goto st30;
1211
- tr52:
1212
- #line 322 "unicorn_http.rl"
1495
+ tr57:
1496
+ #line 349 "unicorn_http.rl"
1213
1497
  {MARK(start.query, p); }
1214
1498
  goto st31;
1215
1499
  st31:
1216
1500
  if ( ++p == pe )
1217
1501
  goto _test_eof31;
1218
1502
  case 31:
1219
- #line 1220 "unicorn_http.c"
1503
+ #line 1504 "unicorn_http.c"
1220
1504
  if ( (*p) < 65 ) {
1221
1505
  if ( 48 <= (*p) && (*p) <= 57 )
1222
1506
  goto st32;
@@ -1240,66 +1524,66 @@ case 32:
1240
1524
  goto st30;
1241
1525
  goto st0;
1242
1526
  tr7:
1243
- #line 289 "unicorn_http.rl"
1527
+ #line 316 "unicorn_http.rl"
1244
1528
  {MARK(mark, p); }
1245
- #line 293 "unicorn_http.rl"
1529
+ #line 320 "unicorn_http.rl"
1246
1530
  { downcase_char(deconst(p)); }
1247
1531
  goto st33;
1248
1532
  st33:
1249
1533
  if ( ++p == pe )
1250
1534
  goto _test_eof33;
1251
1535
  case 33:
1252
- #line 1253 "unicorn_http.c"
1536
+ #line 1537 "unicorn_http.c"
1253
1537
  switch( (*p) ) {
1254
- case 84: goto tr58;
1255
- case 116: goto tr58;
1538
+ case 84: goto tr63;
1539
+ case 116: goto tr63;
1256
1540
  }
1257
1541
  goto st0;
1258
- tr58:
1259
- #line 293 "unicorn_http.rl"
1542
+ tr63:
1543
+ #line 320 "unicorn_http.rl"
1260
1544
  { downcase_char(deconst(p)); }
1261
1545
  goto st34;
1262
1546
  st34:
1263
1547
  if ( ++p == pe )
1264
1548
  goto _test_eof34;
1265
1549
  case 34:
1266
- #line 1267 "unicorn_http.c"
1550
+ #line 1551 "unicorn_http.c"
1267
1551
  switch( (*p) ) {
1268
- case 84: goto tr59;
1269
- case 116: goto tr59;
1552
+ case 84: goto tr64;
1553
+ case 116: goto tr64;
1270
1554
  }
1271
1555
  goto st0;
1272
- tr59:
1273
- #line 293 "unicorn_http.rl"
1556
+ tr64:
1557
+ #line 320 "unicorn_http.rl"
1274
1558
  { downcase_char(deconst(p)); }
1275
1559
  goto st35;
1276
1560
  st35:
1277
1561
  if ( ++p == pe )
1278
1562
  goto _test_eof35;
1279
1563
  case 35:
1280
- #line 1281 "unicorn_http.c"
1564
+ #line 1565 "unicorn_http.c"
1281
1565
  switch( (*p) ) {
1282
- case 80: goto tr60;
1283
- case 112: goto tr60;
1566
+ case 80: goto tr65;
1567
+ case 112: goto tr65;
1284
1568
  }
1285
1569
  goto st0;
1286
- tr60:
1287
- #line 293 "unicorn_http.rl"
1570
+ tr65:
1571
+ #line 320 "unicorn_http.rl"
1288
1572
  { downcase_char(deconst(p)); }
1289
1573
  goto st36;
1290
1574
  st36:
1291
1575
  if ( ++p == pe )
1292
1576
  goto _test_eof36;
1293
1577
  case 36:
1294
- #line 1295 "unicorn_http.c"
1578
+ #line 1579 "unicorn_http.c"
1295
1579
  switch( (*p) ) {
1296
- case 58: goto tr61;
1297
- case 83: goto tr62;
1298
- case 115: goto tr62;
1580
+ case 58: goto tr66;
1581
+ case 83: goto tr67;
1582
+ case 115: goto tr67;
1299
1583
  }
1300
1584
  goto st0;
1301
- tr61:
1302
- #line 299 "unicorn_http.rl"
1585
+ tr66:
1586
+ #line 326 "unicorn_http.rl"
1303
1587
  {
1304
1588
  rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
1305
1589
  }
@@ -1308,7 +1592,7 @@ st37:
1308
1592
  if ( ++p == pe )
1309
1593
  goto _test_eof37;
1310
1594
  case 37:
1311
- #line 1312 "unicorn_http.c"
1595
+ #line 1596 "unicorn_http.c"
1312
1596
  if ( (*p) == 47 )
1313
1597
  goto st38;
1314
1598
  goto st0;
@@ -1327,8 +1611,8 @@ case 39:
1327
1611
  case 37: goto st41;
1328
1612
  case 47: goto st0;
1329
1613
  case 60: goto st0;
1330
- case 91: goto tr68;
1331
- case 95: goto tr67;
1614
+ case 91: goto tr73;
1615
+ case 95: goto tr72;
1332
1616
  case 127: goto st0;
1333
1617
  }
1334
1618
  if ( (*p) < 45 ) {
@@ -1343,11 +1627,11 @@ case 39:
1343
1627
  goto st0;
1344
1628
  } else if ( (*p) > 90 ) {
1345
1629
  if ( 97 <= (*p) && (*p) <= 122 )
1346
- goto tr67;
1630
+ goto tr72;
1347
1631
  } else
1348
- goto tr67;
1632
+ goto tr72;
1349
1633
  } else
1350
- goto tr67;
1634
+ goto tr72;
1351
1635
  goto st40;
1352
1636
  st40:
1353
1637
  if ( ++p == pe )
@@ -1395,18 +1679,18 @@ case 42:
1395
1679
  } else
1396
1680
  goto st40;
1397
1681
  goto st0;
1398
- tr67:
1399
- #line 289 "unicorn_http.rl"
1682
+ tr72:
1683
+ #line 316 "unicorn_http.rl"
1400
1684
  {MARK(mark, p); }
1401
1685
  goto st43;
1402
1686
  st43:
1403
1687
  if ( ++p == pe )
1404
1688
  goto _test_eof43;
1405
1689
  case 43:
1406
- #line 1407 "unicorn_http.c"
1690
+ #line 1691 "unicorn_http.c"
1407
1691
  switch( (*p) ) {
1408
1692
  case 37: goto st41;
1409
- case 47: goto tr71;
1693
+ case 47: goto tr76;
1410
1694
  case 58: goto st44;
1411
1695
  case 60: goto st0;
1412
1696
  case 64: goto st39;
@@ -1437,7 +1721,7 @@ st44:
1437
1721
  case 44:
1438
1722
  switch( (*p) ) {
1439
1723
  case 37: goto st41;
1440
- case 47: goto tr71;
1724
+ case 47: goto tr76;
1441
1725
  case 60: goto st0;
1442
1726
  case 64: goto st39;
1443
1727
  case 127: goto st0;
@@ -1454,15 +1738,15 @@ case 44:
1454
1738
  } else
1455
1739
  goto st0;
1456
1740
  goto st40;
1457
- tr68:
1458
- #line 289 "unicorn_http.rl"
1741
+ tr73:
1742
+ #line 316 "unicorn_http.rl"
1459
1743
  {MARK(mark, p); }
1460
1744
  goto st45;
1461
1745
  st45:
1462
1746
  if ( ++p == pe )
1463
1747
  goto _test_eof45;
1464
1748
  case 45:
1465
- #line 1466 "unicorn_http.c"
1749
+ #line 1750 "unicorn_http.c"
1466
1750
  switch( (*p) ) {
1467
1751
  case 37: goto st41;
1468
1752
  case 47: goto st0;
@@ -1524,7 +1808,7 @@ st47:
1524
1808
  case 47:
1525
1809
  switch( (*p) ) {
1526
1810
  case 37: goto st41;
1527
- case 47: goto tr71;
1811
+ case 47: goto tr76;
1528
1812
  case 58: goto st44;
1529
1813
  case 60: goto st0;
1530
1814
  case 64: goto st39;
@@ -1539,17 +1823,17 @@ case 47:
1539
1823
  } else
1540
1824
  goto st0;
1541
1825
  goto st40;
1542
- tr62:
1543
- #line 293 "unicorn_http.rl"
1826
+ tr67:
1827
+ #line 320 "unicorn_http.rl"
1544
1828
  { downcase_char(deconst(p)); }
1545
1829
  goto st48;
1546
1830
  st48:
1547
1831
  if ( ++p == pe )
1548
1832
  goto _test_eof48;
1549
1833
  case 48:
1550
- #line 1551 "unicorn_http.c"
1834
+ #line 1835 "unicorn_http.c"
1551
1835
  if ( (*p) == 58 )
1552
- goto tr61;
1836
+ goto tr66;
1553
1837
  goto st0;
1554
1838
  st49:
1555
1839
  if ( ++p == pe )
@@ -2063,14 +2347,14 @@ case 67:
2063
2347
  goto tr3;
2064
2348
  goto st0;
2065
2349
  tr2:
2066
- #line 289 "unicorn_http.rl"
2350
+ #line 316 "unicorn_http.rl"
2067
2351
  {MARK(mark, p); }
2068
2352
  goto st68;
2069
2353
  st68:
2070
2354
  if ( ++p == pe )
2071
2355
  goto _test_eof68;
2072
2356
  case 68:
2073
- #line 2074 "unicorn_http.c"
2357
+ #line 2358 "unicorn_http.c"
2074
2358
  switch( (*p) ) {
2075
2359
  case 32: goto tr3;
2076
2360
  case 33: goto st49;
@@ -2130,7 +2414,7 @@ st70:
2130
2414
  goto _test_eof70;
2131
2415
  case 70:
2132
2416
  switch( (*p) ) {
2133
- case 32: goto tr95;
2417
+ case 32: goto tr100;
2134
2418
  case 33: goto st51;
2135
2419
  case 124: goto st51;
2136
2420
  case 126: goto st51;
@@ -2153,39 +2437,40 @@ case 70:
2153
2437
  } else
2154
2438
  goto st51;
2155
2439
  goto st0;
2156
- tr95:
2157
- #line 298 "unicorn_http.rl"
2440
+ tr100:
2441
+ #line 325 "unicorn_http.rl"
2158
2442
  { request_method(hp, PTR_TO(mark), LEN(mark, p)); }
2159
2443
  goto st71;
2160
2444
  st71:
2161
2445
  if ( ++p == pe )
2162
2446
  goto _test_eof71;
2163
2447
  case 71:
2164
- #line 2165 "unicorn_http.c"
2448
+ #line 2449 "unicorn_http.c"
2165
2449
  switch( (*p) ) {
2166
- case 42: goto tr96;
2167
- case 47: goto tr97;
2168
- case 72: goto tr98;
2169
- case 104: goto tr98;
2450
+ case 42: goto tr101;
2451
+ case 47: goto tr102;
2452
+ case 72: goto tr103;
2453
+ case 104: goto tr103;
2170
2454
  }
2171
2455
  goto st0;
2172
- tr96:
2173
- #line 289 "unicorn_http.rl"
2456
+ tr101:
2457
+ #line 316 "unicorn_http.rl"
2174
2458
  {MARK(mark, p); }
2175
2459
  goto st72;
2176
2460
  st72:
2177
2461
  if ( ++p == pe )
2178
2462
  goto _test_eof72;
2179
2463
  case 72:
2180
- #line 2181 "unicorn_http.c"
2464
+ #line 2465 "unicorn_http.c"
2181
2465
  switch( (*p) ) {
2182
- case 13: goto tr99;
2466
+ case 10: goto tr104;
2467
+ case 13: goto tr105;
2183
2468
  case 32: goto tr8;
2184
- case 35: goto tr100;
2469
+ case 35: goto tr106;
2185
2470
  }
2186
2471
  goto st0;
2187
- tr100:
2188
- #line 303 "unicorn_http.rl"
2472
+ tr106:
2473
+ #line 330 "unicorn_http.rl"
2189
2474
  {
2190
2475
  VALUE str;
2191
2476
 
@@ -2202,8 +2487,8 @@ tr100:
2202
2487
  }
2203
2488
  }
2204
2489
  goto st73;
2205
- tr110:
2206
- #line 328 "unicorn_http.rl"
2490
+ tr119:
2491
+ #line 355 "unicorn_http.rl"
2207
2492
  {
2208
2493
  VALUE val;
2209
2494
 
@@ -2214,7 +2499,7 @@ tr110:
2214
2499
  if (!STR_CSTR_EQ(val, "*"))
2215
2500
  rb_hash_aset(hp->env, g_path_info, val);
2216
2501
  }
2217
- #line 303 "unicorn_http.rl"
2502
+ #line 330 "unicorn_http.rl"
2218
2503
  {
2219
2504
  VALUE str;
2220
2505
 
@@ -2231,15 +2516,15 @@ tr110:
2231
2516
  }
2232
2517
  }
2233
2518
  goto st73;
2234
- tr116:
2235
- #line 322 "unicorn_http.rl"
2519
+ tr126:
2520
+ #line 349 "unicorn_http.rl"
2236
2521
  {MARK(start.query, p); }
2237
- #line 323 "unicorn_http.rl"
2522
+ #line 350 "unicorn_http.rl"
2238
2523
  {
2239
2524
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
2240
2525
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
2241
2526
  }
2242
- #line 303 "unicorn_http.rl"
2527
+ #line 330 "unicorn_http.rl"
2243
2528
  {
2244
2529
  VALUE str;
2245
2530
 
@@ -2256,13 +2541,13 @@ tr116:
2256
2541
  }
2257
2542
  }
2258
2543
  goto st73;
2259
- tr120:
2260
- #line 323 "unicorn_http.rl"
2544
+ tr131:
2545
+ #line 350 "unicorn_http.rl"
2261
2546
  {
2262
2547
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
2263
2548
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
2264
2549
  }
2265
- #line 303 "unicorn_http.rl"
2550
+ #line 330 "unicorn_http.rl"
2266
2551
  {
2267
2552
  VALUE str;
2268
2553
 
@@ -2283,29 +2568,31 @@ st73:
2283
2568
  if ( ++p == pe )
2284
2569
  goto _test_eof73;
2285
2570
  case 73:
2286
- #line 2287 "unicorn_http.c"
2571
+ #line 2572 "unicorn_http.c"
2287
2572
  switch( (*p) ) {
2288
- case 13: goto tr102;
2289
- case 32: goto tr37;
2573
+ case 10: goto tr108;
2574
+ case 13: goto tr109;
2575
+ case 32: goto tr42;
2290
2576
  case 35: goto st0;
2291
- case 37: goto tr103;
2577
+ case 37: goto tr110;
2292
2578
  case 127: goto st0;
2293
2579
  }
2294
2580
  if ( 0 <= (*p) && (*p) <= 31 )
2295
2581
  goto st0;
2296
- goto tr101;
2297
- tr101:
2298
- #line 289 "unicorn_http.rl"
2582
+ goto tr107;
2583
+ tr107:
2584
+ #line 316 "unicorn_http.rl"
2299
2585
  {MARK(mark, p); }
2300
2586
  goto st74;
2301
2587
  st74:
2302
2588
  if ( ++p == pe )
2303
2589
  goto _test_eof74;
2304
2590
  case 74:
2305
- #line 2306 "unicorn_http.c"
2591
+ #line 2592 "unicorn_http.c"
2306
2592
  switch( (*p) ) {
2307
- case 13: goto tr105;
2308
- case 32: goto tr40;
2593
+ case 10: goto tr112;
2594
+ case 13: goto tr113;
2595
+ case 32: goto tr45;
2309
2596
  case 35: goto st0;
2310
2597
  case 37: goto st75;
2311
2598
  case 127: goto st0;
@@ -2313,15 +2600,15 @@ case 74:
2313
2600
  if ( 0 <= (*p) && (*p) <= 31 )
2314
2601
  goto st0;
2315
2602
  goto st74;
2316
- tr103:
2317
- #line 289 "unicorn_http.rl"
2603
+ tr110:
2604
+ #line 316 "unicorn_http.rl"
2318
2605
  {MARK(mark, p); }
2319
2606
  goto st75;
2320
2607
  st75:
2321
2608
  if ( ++p == pe )
2322
2609
  goto _test_eof75;
2323
2610
  case 75:
2324
- #line 2325 "unicorn_http.c"
2611
+ #line 2612 "unicorn_http.c"
2325
2612
  if ( (*p) < 65 ) {
2326
2613
  if ( 48 <= (*p) && (*p) <= 57 )
2327
2614
  goto st76;
@@ -2344,27 +2631,28 @@ case 76:
2344
2631
  } else
2345
2632
  goto st74;
2346
2633
  goto st0;
2347
- tr97:
2348
- #line 289 "unicorn_http.rl"
2634
+ tr102:
2635
+ #line 316 "unicorn_http.rl"
2349
2636
  {MARK(mark, p); }
2350
2637
  goto st77;
2351
- tr136:
2352
- #line 302 "unicorn_http.rl"
2638
+ tr147:
2639
+ #line 329 "unicorn_http.rl"
2353
2640
  { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
2354
- #line 289 "unicorn_http.rl"
2641
+ #line 316 "unicorn_http.rl"
2355
2642
  {MARK(mark, p); }
2356
2643
  goto st77;
2357
2644
  st77:
2358
2645
  if ( ++p == pe )
2359
2646
  goto _test_eof77;
2360
2647
  case 77:
2361
- #line 2362 "unicorn_http.c"
2648
+ #line 2649 "unicorn_http.c"
2362
2649
  switch( (*p) ) {
2363
- case 13: goto tr109;
2364
- case 32: goto tr44;
2365
- case 35: goto tr110;
2650
+ case 10: goto tr117;
2651
+ case 13: goto tr118;
2652
+ case 32: goto tr49;
2653
+ case 35: goto tr119;
2366
2654
  case 37: goto st78;
2367
- case 63: goto tr112;
2655
+ case 63: goto tr121;
2368
2656
  case 127: goto st0;
2369
2657
  }
2370
2658
  if ( 0 <= (*p) && (*p) <= 31 )
@@ -2396,8 +2684,8 @@ case 79:
2396
2684
  } else
2397
2685
  goto st77;
2398
2686
  goto st0;
2399
- tr112:
2400
- #line 328 "unicorn_http.rl"
2687
+ tr121:
2688
+ #line 355 "unicorn_http.rl"
2401
2689
  {
2402
2690
  VALUE val;
2403
2691
 
@@ -2413,45 +2701,47 @@ st80:
2413
2701
  if ( ++p == pe )
2414
2702
  goto _test_eof80;
2415
2703
  case 80:
2416
- #line 2417 "unicorn_http.c"
2704
+ #line 2705 "unicorn_http.c"
2417
2705
  switch( (*p) ) {
2418
- case 13: goto tr115;
2419
- case 32: goto tr50;
2420
- case 35: goto tr116;
2421
- case 37: goto tr117;
2706
+ case 10: goto tr124;
2707
+ case 13: goto tr125;
2708
+ case 32: goto tr55;
2709
+ case 35: goto tr126;
2710
+ case 37: goto tr127;
2422
2711
  case 127: goto st0;
2423
2712
  }
2424
2713
  if ( 0 <= (*p) && (*p) <= 31 )
2425
2714
  goto st0;
2426
- goto tr114;
2427
- tr114:
2428
- #line 322 "unicorn_http.rl"
2715
+ goto tr123;
2716
+ tr123:
2717
+ #line 349 "unicorn_http.rl"
2429
2718
  {MARK(start.query, p); }
2430
2719
  goto st81;
2431
2720
  st81:
2432
2721
  if ( ++p == pe )
2433
2722
  goto _test_eof81;
2434
2723
  case 81:
2435
- #line 2436 "unicorn_http.c"
2724
+ #line 2725 "unicorn_http.c"
2436
2725
  switch( (*p) ) {
2437
- case 13: goto tr119;
2438
- case 32: goto tr54;
2439
- case 35: goto tr120;
2726
+ case 10: goto tr129;
2727
+ case 13: goto tr130;
2728
+ case 32: goto tr59;
2729
+ case 35: goto tr131;
2440
2730
  case 37: goto st82;
2441
2731
  case 127: goto st0;
2442
2732
  }
2443
2733
  if ( 0 <= (*p) && (*p) <= 31 )
2444
2734
  goto st0;
2445
2735
  goto st81;
2446
- tr117:
2447
- #line 322 "unicorn_http.rl"
2736
+ tr127:
2737
+ #line 349 "unicorn_http.rl"
2448
2738
  {MARK(start.query, p); }
2449
2739
  goto st82;
2450
2740
  st82:
2451
2741
  if ( ++p == pe )
2452
2742
  goto _test_eof82;
2453
2743
  case 82:
2454
- #line 2455 "unicorn_http.c"
2744
+ #line 2745 "unicorn_http.c"
2455
2745
  if ( (*p) < 65 ) {
2456
2746
  if ( 48 <= (*p) && (*p) <= 57 )
2457
2747
  goto st83;
@@ -2474,67 +2764,67 @@ case 83:
2474
2764
  } else
2475
2765
  goto st81;
2476
2766
  goto st0;
2477
- tr98:
2478
- #line 289 "unicorn_http.rl"
2767
+ tr103:
2768
+ #line 316 "unicorn_http.rl"
2479
2769
  {MARK(mark, p); }
2480
- #line 293 "unicorn_http.rl"
2770
+ #line 320 "unicorn_http.rl"
2481
2771
  { downcase_char(deconst(p)); }
2482
2772
  goto st84;
2483
2773
  st84:
2484
2774
  if ( ++p == pe )
2485
2775
  goto _test_eof84;
2486
2776
  case 84:
2487
- #line 2488 "unicorn_http.c"
2777
+ #line 2778 "unicorn_http.c"
2488
2778
  switch( (*p) ) {
2489
- case 84: goto tr123;
2490
- case 116: goto tr123;
2779
+ case 84: goto tr134;
2780
+ case 116: goto tr134;
2491
2781
  }
2492
2782
  goto st0;
2493
- tr123:
2494
- #line 293 "unicorn_http.rl"
2783
+ tr134:
2784
+ #line 320 "unicorn_http.rl"
2495
2785
  { downcase_char(deconst(p)); }
2496
2786
  goto st85;
2497
2787
  st85:
2498
2788
  if ( ++p == pe )
2499
2789
  goto _test_eof85;
2500
2790
  case 85:
2501
- #line 2502 "unicorn_http.c"
2791
+ #line 2792 "unicorn_http.c"
2502
2792
  switch( (*p) ) {
2503
- case 84: goto tr124;
2504
- case 116: goto tr124;
2793
+ case 84: goto tr135;
2794
+ case 116: goto tr135;
2505
2795
  }
2506
2796
  goto st0;
2507
- tr124:
2508
- #line 293 "unicorn_http.rl"
2797
+ tr135:
2798
+ #line 320 "unicorn_http.rl"
2509
2799
  { downcase_char(deconst(p)); }
2510
2800
  goto st86;
2511
2801
  st86:
2512
2802
  if ( ++p == pe )
2513
2803
  goto _test_eof86;
2514
2804
  case 86:
2515
- #line 2516 "unicorn_http.c"
2805
+ #line 2806 "unicorn_http.c"
2516
2806
  switch( (*p) ) {
2517
- case 80: goto tr125;
2518
- case 112: goto tr125;
2807
+ case 80: goto tr136;
2808
+ case 112: goto tr136;
2519
2809
  }
2520
2810
  goto st0;
2521
- tr125:
2522
- #line 293 "unicorn_http.rl"
2811
+ tr136:
2812
+ #line 320 "unicorn_http.rl"
2523
2813
  { downcase_char(deconst(p)); }
2524
2814
  goto st87;
2525
2815
  st87:
2526
2816
  if ( ++p == pe )
2527
2817
  goto _test_eof87;
2528
2818
  case 87:
2529
- #line 2530 "unicorn_http.c"
2819
+ #line 2820 "unicorn_http.c"
2530
2820
  switch( (*p) ) {
2531
- case 58: goto tr126;
2532
- case 83: goto tr127;
2533
- case 115: goto tr127;
2821
+ case 58: goto tr137;
2822
+ case 83: goto tr138;
2823
+ case 115: goto tr138;
2534
2824
  }
2535
2825
  goto st0;
2536
- tr126:
2537
- #line 299 "unicorn_http.rl"
2826
+ tr137:
2827
+ #line 326 "unicorn_http.rl"
2538
2828
  {
2539
2829
  rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
2540
2830
  }
@@ -2543,7 +2833,7 @@ st88:
2543
2833
  if ( ++p == pe )
2544
2834
  goto _test_eof88;
2545
2835
  case 88:
2546
- #line 2547 "unicorn_http.c"
2836
+ #line 2837 "unicorn_http.c"
2547
2837
  if ( (*p) == 47 )
2548
2838
  goto st89;
2549
2839
  goto st0;
@@ -2562,8 +2852,8 @@ case 90:
2562
2852
  case 37: goto st92;
2563
2853
  case 47: goto st0;
2564
2854
  case 60: goto st0;
2565
- case 91: goto tr133;
2566
- case 95: goto tr132;
2855
+ case 91: goto tr144;
2856
+ case 95: goto tr143;
2567
2857
  case 127: goto st0;
2568
2858
  }
2569
2859
  if ( (*p) < 45 ) {
@@ -2578,11 +2868,11 @@ case 90:
2578
2868
  goto st0;
2579
2869
  } else if ( (*p) > 90 ) {
2580
2870
  if ( 97 <= (*p) && (*p) <= 122 )
2581
- goto tr132;
2871
+ goto tr143;
2582
2872
  } else
2583
- goto tr132;
2873
+ goto tr143;
2584
2874
  } else
2585
- goto tr132;
2875
+ goto tr143;
2586
2876
  goto st91;
2587
2877
  st91:
2588
2878
  if ( ++p == pe )
@@ -2630,18 +2920,18 @@ case 93:
2630
2920
  } else
2631
2921
  goto st91;
2632
2922
  goto st0;
2633
- tr132:
2634
- #line 289 "unicorn_http.rl"
2923
+ tr143:
2924
+ #line 316 "unicorn_http.rl"
2635
2925
  {MARK(mark, p); }
2636
2926
  goto st94;
2637
2927
  st94:
2638
2928
  if ( ++p == pe )
2639
2929
  goto _test_eof94;
2640
2930
  case 94:
2641
- #line 2642 "unicorn_http.c"
2931
+ #line 2932 "unicorn_http.c"
2642
2932
  switch( (*p) ) {
2643
2933
  case 37: goto st92;
2644
- case 47: goto tr136;
2934
+ case 47: goto tr147;
2645
2935
  case 58: goto st95;
2646
2936
  case 60: goto st0;
2647
2937
  case 64: goto st90;
@@ -2672,7 +2962,7 @@ st95:
2672
2962
  case 95:
2673
2963
  switch( (*p) ) {
2674
2964
  case 37: goto st92;
2675
- case 47: goto tr136;
2965
+ case 47: goto tr147;
2676
2966
  case 60: goto st0;
2677
2967
  case 64: goto st90;
2678
2968
  case 127: goto st0;
@@ -2689,15 +2979,15 @@ case 95:
2689
2979
  } else
2690
2980
  goto st0;
2691
2981
  goto st91;
2692
- tr133:
2693
- #line 289 "unicorn_http.rl"
2982
+ tr144:
2983
+ #line 316 "unicorn_http.rl"
2694
2984
  {MARK(mark, p); }
2695
2985
  goto st96;
2696
2986
  st96:
2697
2987
  if ( ++p == pe )
2698
2988
  goto _test_eof96;
2699
2989
  case 96:
2700
- #line 2701 "unicorn_http.c"
2990
+ #line 2991 "unicorn_http.c"
2701
2991
  switch( (*p) ) {
2702
2992
  case 37: goto st92;
2703
2993
  case 47: goto st0;
@@ -2759,7 +3049,7 @@ st98:
2759
3049
  case 98:
2760
3050
  switch( (*p) ) {
2761
3051
  case 37: goto st92;
2762
- case 47: goto tr136;
3052
+ case 47: goto tr147;
2763
3053
  case 58: goto st95;
2764
3054
  case 60: goto st0;
2765
3055
  case 64: goto st90;
@@ -2774,35 +3064,35 @@ case 98:
2774
3064
  } else
2775
3065
  goto st0;
2776
3066
  goto st91;
2777
- tr127:
2778
- #line 293 "unicorn_http.rl"
3067
+ tr138:
3068
+ #line 320 "unicorn_http.rl"
2779
3069
  { downcase_char(deconst(p)); }
2780
3070
  goto st99;
2781
3071
  st99:
2782
3072
  if ( ++p == pe )
2783
3073
  goto _test_eof99;
2784
3074
  case 99:
2785
- #line 2786 "unicorn_http.c"
3075
+ #line 3076 "unicorn_http.c"
2786
3076
  if ( (*p) == 58 )
2787
- goto tr126;
3077
+ goto tr137;
2788
3078
  goto st0;
2789
3079
  st100:
2790
3080
  if ( ++p == pe )
2791
3081
  goto _test_eof100;
2792
3082
  case 100:
2793
3083
  if ( (*p) == 48 )
2794
- goto tr140;
3084
+ goto tr151;
2795
3085
  if ( (*p) < 65 ) {
2796
3086
  if ( 49 <= (*p) && (*p) <= 57 )
2797
- goto tr141;
3087
+ goto tr152;
2798
3088
  } else if ( (*p) > 70 ) {
2799
3089
  if ( 97 <= (*p) && (*p) <= 102 )
2800
- goto tr141;
3090
+ goto tr152;
2801
3091
  } else
2802
- goto tr141;
3092
+ goto tr152;
2803
3093
  goto st0;
2804
- tr140:
2805
- #line 338 "unicorn_http.rl"
3094
+ tr151:
3095
+ #line 365 "unicorn_http.rl"
2806
3096
  {
2807
3097
  hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
2808
3098
  if (hp->len.chunk < 0)
@@ -2813,30 +3103,24 @@ st101:
2813
3103
  if ( ++p == pe )
2814
3104
  goto _test_eof101;
2815
3105
  case 101:
2816
- #line 2817 "unicorn_http.c"
3106
+ #line 3107 "unicorn_http.c"
2817
3107
  switch( (*p) ) {
3108
+ case 10: goto tr153;
2818
3109
  case 13: goto st102;
2819
- case 48: goto tr140;
3110
+ case 48: goto tr151;
2820
3111
  case 59: goto st111;
2821
3112
  }
2822
3113
  if ( (*p) < 65 ) {
2823
3114
  if ( 49 <= (*p) && (*p) <= 57 )
2824
- goto tr141;
3115
+ goto tr152;
2825
3116
  } else if ( (*p) > 70 ) {
2826
3117
  if ( 97 <= (*p) && (*p) <= 102 )
2827
- goto tr141;
3118
+ goto tr152;
2828
3119
  } else
2829
- goto tr141;
2830
- goto st0;
2831
- st102:
2832
- if ( ++p == pe )
2833
- goto _test_eof102;
2834
- case 102:
2835
- if ( (*p) == 10 )
2836
- goto tr144;
3120
+ goto tr152;
2837
3121
  goto st0;
2838
- tr144:
2839
- #line 367 "unicorn_http.rl"
3122
+ tr153:
3123
+ #line 394 "unicorn_http.rl"
2840
3124
  {
2841
3125
  HP_FL_SET(hp, INTRAILER);
2842
3126
  cs = http_parser_en_Trailers;
@@ -2849,10 +3133,17 @@ st123:
2849
3133
  if ( ++p == pe )
2850
3134
  goto _test_eof123;
2851
3135
  case 123:
2852
- #line 2853 "unicorn_http.c"
3136
+ #line 3137 "unicorn_http.c"
3137
+ goto st0;
3138
+ st102:
3139
+ if ( ++p == pe )
3140
+ goto _test_eof102;
3141
+ case 102:
3142
+ if ( (*p) == 10 )
3143
+ goto tr153;
2853
3144
  goto st0;
2854
- tr141:
2855
- #line 338 "unicorn_http.rl"
3145
+ tr152:
3146
+ #line 365 "unicorn_http.rl"
2856
3147
  {
2857
3148
  hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
2858
3149
  if (hp->len.chunk < 0)
@@ -2863,34 +3154,28 @@ st103:
2863
3154
  if ( ++p == pe )
2864
3155
  goto _test_eof103;
2865
3156
  case 103:
2866
- #line 2867 "unicorn_http.c"
3157
+ #line 3158 "unicorn_http.c"
2867
3158
  switch( (*p) ) {
2868
- case 13: goto st104;
3159
+ case 10: goto st104;
3160
+ case 13: goto st107;
2869
3161
  case 59: goto st108;
2870
3162
  }
2871
3163
  if ( (*p) < 65 ) {
2872
3164
  if ( 48 <= (*p) && (*p) <= 57 )
2873
- goto tr141;
3165
+ goto tr152;
2874
3166
  } else if ( (*p) > 70 ) {
2875
3167
  if ( 97 <= (*p) && (*p) <= 102 )
2876
- goto tr141;
3168
+ goto tr152;
2877
3169
  } else
2878
- goto tr141;
3170
+ goto tr152;
2879
3171
  goto st0;
2880
3172
  st104:
2881
3173
  if ( ++p == pe )
2882
3174
  goto _test_eof104;
2883
3175
  case 104:
2884
- if ( (*p) == 10 )
2885
- goto st105;
2886
- goto st0;
2887
- st105:
2888
- if ( ++p == pe )
2889
- goto _test_eof105;
2890
- case 105:
2891
- goto tr148;
2892
- tr148:
2893
- #line 375 "unicorn_http.rl"
3176
+ goto tr159;
3177
+ tr159:
3178
+ #line 402 "unicorn_http.rl"
2894
3179
  {
2895
3180
  skip_chunk_data_hack: {
2896
3181
  size_t nr = MIN((size_t)hp->len.chunk, REMAINING);
@@ -2904,31 +3189,41 @@ tr148:
2904
3189
  goto post_exec;
2905
3190
  } else {
2906
3191
  p--;
2907
- {goto st106;}
3192
+ {goto st105;}
2908
3193
  }
2909
3194
  }}
2910
- goto st106;
3195
+ goto st105;
3196
+ st105:
3197
+ if ( ++p == pe )
3198
+ goto _test_eof105;
3199
+ case 105:
3200
+ #line 3201 "unicorn_http.c"
3201
+ switch( (*p) ) {
3202
+ case 10: goto st100;
3203
+ case 13: goto st106;
3204
+ }
3205
+ goto st0;
2911
3206
  st106:
2912
3207
  if ( ++p == pe )
2913
3208
  goto _test_eof106;
2914
3209
  case 106:
2915
- #line 2916 "unicorn_http.c"
2916
- if ( (*p) == 13 )
2917
- goto st107;
3210
+ if ( (*p) == 10 )
3211
+ goto st100;
2918
3212
  goto st0;
2919
3213
  st107:
2920
3214
  if ( ++p == pe )
2921
3215
  goto _test_eof107;
2922
3216
  case 107:
2923
3217
  if ( (*p) == 10 )
2924
- goto st100;
3218
+ goto st104;
2925
3219
  goto st0;
2926
3220
  st108:
2927
3221
  if ( ++p == pe )
2928
3222
  goto _test_eof108;
2929
3223
  case 108:
2930
3224
  switch( (*p) ) {
2931
- case 13: goto st104;
3225
+ case 10: goto st104;
3226
+ case 13: goto st107;
2932
3227
  case 32: goto st108;
2933
3228
  case 33: goto st109;
2934
3229
  case 59: goto st108;
@@ -2959,7 +3254,8 @@ st109:
2959
3254
  goto _test_eof109;
2960
3255
  case 109:
2961
3256
  switch( (*p) ) {
2962
- case 13: goto st104;
3257
+ case 10: goto st104;
3258
+ case 13: goto st107;
2963
3259
  case 33: goto st109;
2964
3260
  case 59: goto st108;
2965
3261
  case 61: goto st110;
@@ -2989,7 +3285,8 @@ st110:
2989
3285
  goto _test_eof110;
2990
3286
  case 110:
2991
3287
  switch( (*p) ) {
2992
- case 13: goto st104;
3288
+ case 10: goto st104;
3289
+ case 13: goto st107;
2993
3290
  case 33: goto st110;
2994
3291
  case 59: goto st108;
2995
3292
  case 124: goto st110;
@@ -3018,6 +3315,7 @@ st111:
3018
3315
  goto _test_eof111;
3019
3316
  case 111:
3020
3317
  switch( (*p) ) {
3318
+ case 10: goto tr153;
3021
3319
  case 13: goto st102;
3022
3320
  case 32: goto st111;
3023
3321
  case 33: goto st112;
@@ -3049,6 +3347,7 @@ st112:
3049
3347
  goto _test_eof112;
3050
3348
  case 112:
3051
3349
  switch( (*p) ) {
3350
+ case 10: goto tr153;
3052
3351
  case 13: goto st102;
3053
3352
  case 33: goto st112;
3054
3353
  case 59: goto st111;
@@ -3079,6 +3378,7 @@ st113:
3079
3378
  goto _test_eof113;
3080
3379
  case 113:
3081
3380
  switch( (*p) ) {
3381
+ case 10: goto tr153;
3082
3382
  case 13: goto st102;
3083
3383
  case 33: goto st113;
3084
3384
  case 59: goto st111;
@@ -3103,110 +3403,127 @@ case 113:
3103
3403
  } else
3104
3404
  goto st113;
3105
3405
  goto st0;
3406
+ tr172:
3407
+ #line 322 "unicorn_http.rl"
3408
+ { MARK(mark, p); }
3409
+ #line 324 "unicorn_http.rl"
3410
+ { write_cont_value(hp, buffer, p); }
3411
+ goto st114;
3412
+ tr175:
3413
+ #line 324 "unicorn_http.rl"
3414
+ { write_cont_value(hp, buffer, p); }
3415
+ goto st114;
3416
+ tr182:
3417
+ #line 322 "unicorn_http.rl"
3418
+ { MARK(mark, p); }
3419
+ #line 323 "unicorn_http.rl"
3420
+ { write_value(hp, buffer, p); }
3421
+ goto st114;
3422
+ tr185:
3423
+ #line 323 "unicorn_http.rl"
3424
+ { write_value(hp, buffer, p); }
3425
+ goto st114;
3106
3426
  st114:
3107
3427
  if ( ++p == pe )
3108
3428
  goto _test_eof114;
3109
3429
  case 114:
3430
+ #line 3431 "unicorn_http.c"
3110
3431
  switch( (*p) ) {
3111
3432
  case 9: goto st115;
3433
+ case 10: goto tr167;
3112
3434
  case 13: goto st118;
3113
3435
  case 32: goto st115;
3114
- case 33: goto tr157;
3115
- case 124: goto tr157;
3116
- case 126: goto tr157;
3436
+ case 33: goto tr169;
3437
+ case 124: goto tr169;
3438
+ case 126: goto tr169;
3117
3439
  }
3118
3440
  if ( (*p) < 45 ) {
3119
3441
  if ( (*p) > 39 ) {
3120
3442
  if ( 42 <= (*p) && (*p) <= 43 )
3121
- goto tr157;
3443
+ goto tr169;
3122
3444
  } else if ( (*p) >= 35 )
3123
- goto tr157;
3445
+ goto tr169;
3124
3446
  } else if ( (*p) > 46 ) {
3125
3447
  if ( (*p) < 65 ) {
3126
3448
  if ( 48 <= (*p) && (*p) <= 57 )
3127
- goto tr157;
3449
+ goto tr169;
3128
3450
  } else if ( (*p) > 90 ) {
3129
3451
  if ( 94 <= (*p) && (*p) <= 122 )
3130
- goto tr157;
3452
+ goto tr169;
3131
3453
  } else
3132
- goto tr157;
3454
+ goto tr169;
3133
3455
  } else
3134
- goto tr157;
3456
+ goto tr169;
3135
3457
  goto st0;
3136
- tr159:
3137
- #line 295 "unicorn_http.rl"
3458
+ tr171:
3459
+ #line 322 "unicorn_http.rl"
3138
3460
  { MARK(mark, p); }
3139
3461
  goto st115;
3140
3462
  st115:
3141
3463
  if ( ++p == pe )
3142
3464
  goto _test_eof115;
3143
3465
  case 115:
3144
- #line 3145 "unicorn_http.c"
3466
+ #line 3467 "unicorn_http.c"
3145
3467
  switch( (*p) ) {
3146
- case 9: goto tr159;
3147
- case 13: goto tr160;
3148
- case 32: goto tr159;
3468
+ case 9: goto tr171;
3469
+ case 10: goto tr172;
3470
+ case 13: goto tr173;
3471
+ case 32: goto tr171;
3149
3472
  case 127: goto st0;
3150
3473
  }
3151
3474
  if ( 0 <= (*p) && (*p) <= 31 )
3152
3475
  goto st0;
3153
- goto tr158;
3154
- tr158:
3155
- #line 295 "unicorn_http.rl"
3476
+ goto tr170;
3477
+ tr170:
3478
+ #line 322 "unicorn_http.rl"
3156
3479
  { MARK(mark, p); }
3157
3480
  goto st116;
3158
3481
  st116:
3159
3482
  if ( ++p == pe )
3160
3483
  goto _test_eof116;
3161
3484
  case 116:
3162
- #line 3163 "unicorn_http.c"
3485
+ #line 3486 "unicorn_http.c"
3163
3486
  switch( (*p) ) {
3164
- case 13: goto tr162;
3487
+ case 10: goto tr175;
3488
+ case 13: goto tr176;
3165
3489
  case 127: goto st0;
3166
3490
  }
3167
3491
  if ( (*p) > 8 ) {
3168
- if ( 10 <= (*p) && (*p) <= 31 )
3492
+ if ( 11 <= (*p) && (*p) <= 31 )
3169
3493
  goto st0;
3170
3494
  } else if ( (*p) >= 0 )
3171
3495
  goto st0;
3172
3496
  goto st116;
3173
- tr160:
3174
- #line 295 "unicorn_http.rl"
3497
+ tr173:
3498
+ #line 322 "unicorn_http.rl"
3175
3499
  { MARK(mark, p); }
3176
- #line 297 "unicorn_http.rl"
3500
+ #line 324 "unicorn_http.rl"
3177
3501
  { write_cont_value(hp, buffer, p); }
3178
3502
  goto st117;
3179
- tr162:
3180
- #line 297 "unicorn_http.rl"
3503
+ tr176:
3504
+ #line 324 "unicorn_http.rl"
3181
3505
  { write_cont_value(hp, buffer, p); }
3182
3506
  goto st117;
3183
- tr169:
3184
- #line 295 "unicorn_http.rl"
3507
+ tr183:
3508
+ #line 322 "unicorn_http.rl"
3185
3509
  { MARK(mark, p); }
3186
- #line 296 "unicorn_http.rl"
3510
+ #line 323 "unicorn_http.rl"
3187
3511
  { write_value(hp, buffer, p); }
3188
3512
  goto st117;
3189
- tr171:
3190
- #line 296 "unicorn_http.rl"
3513
+ tr186:
3514
+ #line 323 "unicorn_http.rl"
3191
3515
  { write_value(hp, buffer, p); }
3192
3516
  goto st117;
3193
3517
  st117:
3194
3518
  if ( ++p == pe )
3195
3519
  goto _test_eof117;
3196
3520
  case 117:
3197
- #line 3198 "unicorn_http.c"
3521
+ #line 3522 "unicorn_http.c"
3198
3522
  if ( (*p) == 10 )
3199
3523
  goto st114;
3200
3524
  goto st0;
3201
- st118:
3202
- if ( ++p == pe )
3203
- goto _test_eof118;
3204
- case 118:
3205
- if ( (*p) == 10 )
3206
- goto tr164;
3207
- goto st0;
3208
- tr164:
3209
- #line 362 "unicorn_http.rl"
3525
+ tr167:
3526
+ #line 389 "unicorn_http.rl"
3210
3527
  {
3211
3528
  cs = http_parser_first_final;
3212
3529
  goto post_exec;
@@ -3216,84 +3533,93 @@ st124:
3216
3533
  if ( ++p == pe )
3217
3534
  goto _test_eof124;
3218
3535
  case 124:
3219
- #line 3220 "unicorn_http.c"
3536
+ #line 3537 "unicorn_http.c"
3537
+ goto st0;
3538
+ st118:
3539
+ if ( ++p == pe )
3540
+ goto _test_eof118;
3541
+ case 118:
3542
+ if ( (*p) == 10 )
3543
+ goto tr167;
3220
3544
  goto st0;
3221
- tr157:
3222
- #line 291 "unicorn_http.rl"
3545
+ tr169:
3546
+ #line 318 "unicorn_http.rl"
3223
3547
  { MARK(start.field, p); }
3224
- #line 292 "unicorn_http.rl"
3548
+ #line 319 "unicorn_http.rl"
3225
3549
  { snake_upcase_char(deconst(p)); }
3226
3550
  goto st119;
3227
- tr165:
3228
- #line 292 "unicorn_http.rl"
3551
+ tr178:
3552
+ #line 319 "unicorn_http.rl"
3229
3553
  { snake_upcase_char(deconst(p)); }
3230
3554
  goto st119;
3231
3555
  st119:
3232
3556
  if ( ++p == pe )
3233
3557
  goto _test_eof119;
3234
3558
  case 119:
3235
- #line 3236 "unicorn_http.c"
3559
+ #line 3560 "unicorn_http.c"
3236
3560
  switch( (*p) ) {
3237
- case 33: goto tr165;
3238
- case 58: goto tr166;
3239
- case 124: goto tr165;
3240
- case 126: goto tr165;
3561
+ case 33: goto tr178;
3562
+ case 58: goto tr179;
3563
+ case 124: goto tr178;
3564
+ case 126: goto tr178;
3241
3565
  }
3242
3566
  if ( (*p) < 45 ) {
3243
3567
  if ( (*p) > 39 ) {
3244
3568
  if ( 42 <= (*p) && (*p) <= 43 )
3245
- goto tr165;
3569
+ goto tr178;
3246
3570
  } else if ( (*p) >= 35 )
3247
- goto tr165;
3571
+ goto tr178;
3248
3572
  } else if ( (*p) > 46 ) {
3249
3573
  if ( (*p) < 65 ) {
3250
3574
  if ( 48 <= (*p) && (*p) <= 57 )
3251
- goto tr165;
3575
+ goto tr178;
3252
3576
  } else if ( (*p) > 90 ) {
3253
3577
  if ( 94 <= (*p) && (*p) <= 122 )
3254
- goto tr165;
3578
+ goto tr178;
3255
3579
  } else
3256
- goto tr165;
3580
+ goto tr178;
3257
3581
  } else
3258
- goto tr165;
3582
+ goto tr178;
3259
3583
  goto st0;
3260
- tr168:
3261
- #line 295 "unicorn_http.rl"
3584
+ tr181:
3585
+ #line 322 "unicorn_http.rl"
3262
3586
  { MARK(mark, p); }
3263
3587
  goto st120;
3264
- tr166:
3265
- #line 294 "unicorn_http.rl"
3588
+ tr179:
3589
+ #line 321 "unicorn_http.rl"
3266
3590
  { hp->s.field_len = LEN(start.field, p); }
3267
3591
  goto st120;
3268
3592
  st120:
3269
3593
  if ( ++p == pe )
3270
3594
  goto _test_eof120;
3271
3595
  case 120:
3272
- #line 3273 "unicorn_http.c"
3596
+ #line 3597 "unicorn_http.c"
3273
3597
  switch( (*p) ) {
3274
- case 9: goto tr168;
3275
- case 13: goto tr169;
3276
- case 32: goto tr168;
3598
+ case 9: goto tr181;
3599
+ case 10: goto tr182;
3600
+ case 13: goto tr183;
3601
+ case 32: goto tr181;
3277
3602
  case 127: goto st0;
3278
3603
  }
3279
3604
  if ( 0 <= (*p) && (*p) <= 31 )
3280
3605
  goto st0;
3281
- goto tr167;
3282
- tr167:
3283
- #line 295 "unicorn_http.rl"
3606
+ goto tr180;
3607
+ tr180:
3608
+ #line 322 "unicorn_http.rl"
3284
3609
  { MARK(mark, p); }
3285
3610
  goto st121;
3286
3611
  st121:
3287
3612
  if ( ++p == pe )
3288
3613
  goto _test_eof121;
3289
3614
  case 121:
3290
- #line 3291 "unicorn_http.c"
3615
+ #line 3616 "unicorn_http.c"
3291
3616
  switch( (*p) ) {
3292
- case 13: goto tr171;
3617
+ case 10: goto tr185;
3618
+ case 13: goto tr186;
3293
3619
  case 127: goto st0;
3294
3620
  }
3295
3621
  if ( (*p) > 8 ) {
3296
- if ( 10 <= (*p) && (*p) <= 31 )
3622
+ if ( 11 <= (*p) && (*p) <= 31 )
3297
3623
  goto st0;
3298
3624
  } else if ( (*p) >= 0 )
3299
3625
  goto st0;
@@ -3315,8 +3641,8 @@ case 121:
3315
3641
  _test_eof15: cs = 15; goto _test_eof;
3316
3642
  _test_eof16: cs = 16; goto _test_eof;
3317
3643
  _test_eof17: cs = 17; goto _test_eof;
3318
- _test_eof18: cs = 18; goto _test_eof;
3319
3644
  _test_eof122: cs = 122; goto _test_eof;
3645
+ _test_eof18: cs = 18; goto _test_eof;
3320
3646
  _test_eof19: cs = 19; goto _test_eof;
3321
3647
  _test_eof20: cs = 20; goto _test_eof;
3322
3648
  _test_eof21: cs = 21; goto _test_eof;
@@ -3400,8 +3726,8 @@ case 121:
3400
3726
  _test_eof99: cs = 99; goto _test_eof;
3401
3727
  _test_eof100: cs = 100; goto _test_eof;
3402
3728
  _test_eof101: cs = 101; goto _test_eof;
3403
- _test_eof102: cs = 102; goto _test_eof;
3404
3729
  _test_eof123: cs = 123; goto _test_eof;
3730
+ _test_eof102: cs = 102; goto _test_eof;
3405
3731
  _test_eof103: cs = 103; goto _test_eof;
3406
3732
  _test_eof104: cs = 104; goto _test_eof;
3407
3733
  _test_eof105: cs = 105; goto _test_eof;
@@ -3417,8 +3743,8 @@ case 121:
3417
3743
  _test_eof115: cs = 115; goto _test_eof;
3418
3744
  _test_eof116: cs = 116; goto _test_eof;
3419
3745
  _test_eof117: cs = 117; goto _test_eof;
3420
- _test_eof118: cs = 118; goto _test_eof;
3421
3746
  _test_eof124: cs = 124; goto _test_eof;
3747
+ _test_eof118: cs = 118; goto _test_eof;
3422
3748
  _test_eof119: cs = 119; goto _test_eof;
3423
3749
  _test_eof120: cs = 120; goto _test_eof;
3424
3750
  _test_eof121: cs = 121; goto _test_eof;
@@ -3427,7 +3753,7 @@ case 121:
3427
3753
  _out: {}
3428
3754
  }
3429
3755
 
3430
- #line 436 "unicorn_http.rl"
3756
+ #line 463 "unicorn_http.rl"
3431
3757
  post_exec: /* "_out:" also goes here */
3432
3758
  if (hp->cs != http_parser_error)
3433
3759
  hp->cs = cs;
@@ -3437,11 +3763,31 @@ post_exec: /* "_out:" also goes here */
3437
3763
  assert(hp->offset <= len && "offset longer than length");
3438
3764
  }
3439
3765
 
3766
+ static void hp_mark(void *ptr)
3767
+ {
3768
+ struct http_parser *hp = ptr;
3769
+
3770
+ rb_gc_mark(hp->buf);
3771
+ rb_gc_mark(hp->env);
3772
+ rb_gc_mark(hp->cont);
3773
+ }
3774
+
3775
+ static size_t hp_memsize(const void *ptr)
3776
+ {
3777
+ return sizeof(struct http_parser);
3778
+ }
3779
+
3780
+ static const rb_data_type_t hp_type = {
3781
+ "unicorn_http",
3782
+ { hp_mark, RUBY_TYPED_DEFAULT_FREE, hp_memsize, /* reserved */ },
3783
+ /* parent, data, [ flags ] */
3784
+ };
3785
+
3440
3786
  static struct http_parser *data_get(VALUE self)
3441
3787
  {
3442
3788
  struct http_parser *hp;
3443
3789
 
3444
- Data_Get_Struct(self, struct http_parser, hp);
3790
+ TypedData_Get_Struct(self, struct http_parser, &hp_type, hp);
3445
3791
  assert(hp && "failed to extract http_parser struct");
3446
3792
  return hp;
3447
3793
  }
@@ -3461,7 +3807,7 @@ static void set_url_scheme(VALUE env, VALUE *server_port)
3461
3807
  * and X-Forwarded-Proto handling from this parser? We've had it
3462
3808
  * forever and nobody has said anything against it, either.
3463
3809
  * Anyways, please send comments to our public mailing list:
3464
- * unicorn-public@bogomips.org (no HTML mail, no subscription necessary)
3810
+ * unicorn-public@yhbt.net (no HTML mail, no subscription necessary)
3465
3811
  */
3466
3812
  scheme = rb_hash_aref(env, g_http_x_forwarded_ssl);
3467
3813
  if (!NIL_P(scheme) && STR_CSTR_EQ(scheme, "on")) {
@@ -3547,21 +3893,12 @@ static void finalize_header(struct http_parser *hp)
3547
3893
  rb_hash_aset(hp->env, g_query_string, rb_str_new(NULL, 0));
3548
3894
  }
3549
3895
 
3550
- static void hp_mark(void *ptr)
3551
- {
3552
- struct http_parser *hp = ptr;
3553
-
3554
- rb_gc_mark(hp->buf);
3555
- rb_gc_mark(hp->env);
3556
- rb_gc_mark(hp->cont);
3557
- }
3558
-
3559
3896
  static VALUE HttpParser_alloc(VALUE klass)
3560
3897
  {
3561
3898
  struct http_parser *hp;
3562
- return Data_Make_Struct(klass, struct http_parser, hp_mark, -1, hp);
3563
- }
3564
3899
 
3900
+ return TypedData_Make_Struct(klass, struct http_parser, &hp_type, hp);
3901
+ }
3565
3902
 
3566
3903
  /**
3567
3904
  * call-seq:
@@ -3591,8 +3928,12 @@ static VALUE HttpParser_clear(VALUE self)
3591
3928
  {
3592
3929
  struct http_parser *hp = data_get(self);
3593
3930
 
3931
+ /* we can't safely reuse .buf and .env if hijacked */
3932
+ if (HP_FL_TEST(hp, HIJACK))
3933
+ return HttpParser_init(self);
3934
+
3594
3935
  http_parser_init(hp);
3595
- my_hash_clear(hp->env);
3936
+ rb_hash_clear(hp->env);
3596
3937
 
3597
3938
  return self;
3598
3939
  }
@@ -3797,6 +4138,15 @@ static VALUE HttpParser_env(VALUE self)
3797
4138
  return data_get(self)->env;
3798
4139
  }
3799
4140
 
4141
+ static VALUE HttpParser_hijacked_bang(VALUE self)
4142
+ {
4143
+ struct http_parser *hp = data_get(self);
4144
+
4145
+ HP_FL_SET(hp, HIJACK);
4146
+
4147
+ return self;
4148
+ }
4149
+
3800
4150
  /**
3801
4151
  * call-seq:
3802
4152
  * parser.filter_body(dst, src) => nil/src
@@ -3901,7 +4251,7 @@ static VALUE HttpParser_rssget(VALUE self)
3901
4251
 
3902
4252
  void Init_unicorn_http(void)
3903
4253
  {
3904
- VALUE mUnicorn, cHttpParser;
4254
+ VALUE mUnicorn;
3905
4255
 
3906
4256
  mUnicorn = rb_define_module("Unicorn");
3907
4257
  cHttpParser = rb_define_class_under(mUnicorn, "HttpParser", rb_cObject);
@@ -3912,6 +4262,7 @@ void Init_unicorn_http(void)
3912
4262
  e414 = rb_define_class_under(mUnicorn, "RequestURITooLongError",
3913
4263
  eHttpParserError);
3914
4264
 
4265
+ id_uminus = rb_intern("-@");
3915
4266
  init_globals();
3916
4267
  rb_define_alloc_func(cHttpParser, HttpParser_alloc);
3917
4268
  rb_define_method(cHttpParser, "initialize", HttpParser_init, 0);
@@ -3928,6 +4279,7 @@ void Init_unicorn_http(void)
3928
4279
  rb_define_method(cHttpParser, "next?", HttpParser_next, 0);
3929
4280
  rb_define_method(cHttpParser, "buf", HttpParser_buf, 0);
3930
4281
  rb_define_method(cHttpParser, "env", HttpParser_env, 0);
4282
+ rb_define_method(cHttpParser, "hijacked!", HttpParser_hijacked_bang, 0);
3931
4283
  rb_define_method(cHttpParser, "response_start_sent=", HttpParser_rssset, 1);
3932
4284
  rb_define_method(cHttpParser, "response_start_sent", HttpParser_rssget, 0);
3933
4285
 
@@ -3960,5 +4312,8 @@ void Init_unicorn_http(void)
3960
4312
  #ifndef HAVE_RB_HASH_CLEAR
3961
4313
  id_clear = rb_intern("clear");
3962
4314
  #endif
4315
+ id_is_chunked_p = rb_intern("is_chunked?");
4316
+
4317
+ init_epollexclusive(mUnicorn);
3963
4318
  }
3964
4319
  #undef SET_GLOBAL