unicorn 5.3.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 (84) hide show
  1. checksums.yaml +5 -5
  2. data/.manifest +10 -5
  3. data/.olddoc.yml +15 -7
  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 +117 -57
  13. data/HACKING +2 -9
  14. data/ISSUES +33 -32
  15. data/KNOWN_ISSUES +2 -2
  16. data/LATEST +16 -95
  17. data/LICENSE +2 -2
  18. data/Links +13 -11
  19. data/NEWS +239 -0
  20. data/README +27 -14
  21. data/SIGNALS +1 -1
  22. data/Sandbox +5 -5
  23. data/archive/slrnpull.conf +1 -1
  24. data/bin/unicorn +3 -1
  25. data/bin/unicorn_rails +2 -2
  26. data/examples/big_app_gc.rb +1 -1
  27. data/examples/logrotate.conf +3 -3
  28. data/examples/nginx.conf +4 -3
  29. data/examples/unicorn.conf.minimal.rb +2 -2
  30. data/examples/unicorn.conf.rb +2 -2
  31. data/examples/unicorn@.service +7 -0
  32. data/ext/unicorn_http/c_util.h +5 -13
  33. data/ext/unicorn_http/common_field_optimization.h +23 -6
  34. data/ext/unicorn_http/epollexclusive.h +124 -0
  35. data/ext/unicorn_http/ext_help.h +0 -24
  36. data/ext/unicorn_http/extconf.rb +32 -6
  37. data/ext/unicorn_http/global_variables.h +3 -3
  38. data/ext/unicorn_http/httpdate.c +3 -2
  39. data/ext/unicorn_http/unicorn_http.c +277 -237
  40. data/ext/unicorn_http/unicorn_http.rl +67 -27
  41. data/lib/unicorn/configurator.rb +26 -5
  42. data/lib/unicorn/http_request.rb +13 -3
  43. data/lib/unicorn/http_response.rb +3 -2
  44. data/lib/unicorn/http_server.rb +76 -51
  45. data/lib/unicorn/launcher.rb +1 -1
  46. data/lib/unicorn/oob_gc.rb +5 -5
  47. data/lib/unicorn/select_waiter.rb +6 -0
  48. data/lib/unicorn/socket_helper.rb +4 -3
  49. data/lib/unicorn/tmpio.rb +8 -2
  50. data/lib/unicorn/util.rb +3 -3
  51. data/lib/unicorn/version.rb +1 -1
  52. data/lib/unicorn/worker.rb +16 -2
  53. data/lib/unicorn.rb +25 -10
  54. data/man/man1/unicorn.1 +88 -85
  55. data/man/man1/unicorn_rails.1 +79 -81
  56. data/t/GNUmakefile +3 -72
  57. data/t/README +4 -4
  58. data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
  59. data/t/t0301.ru +13 -0
  60. data/t/test-lib.sh +2 -1
  61. data/test/benchmark/README +14 -4
  62. data/test/benchmark/ddstream.ru +50 -0
  63. data/test/benchmark/readinput.ru +40 -0
  64. data/test/benchmark/uconnect.perl +66 -0
  65. data/test/exec/test_exec.rb +20 -19
  66. data/test/test_helper.rb +38 -30
  67. data/test/unit/test_ccc.rb +5 -4
  68. data/test/unit/test_droplet.rb +1 -1
  69. data/test/unit/test_http_parser.rb +16 -0
  70. data/test/unit/test_http_parser_ng.rb +81 -0
  71. data/test/unit/test_request.rb +10 -10
  72. data/test/unit/test_server.rb +86 -12
  73. data/test/unit/test_signals.rb +8 -8
  74. data/test/unit/test_socket_helper.rb +5 -5
  75. data/test/unit/test_upload.rb +9 -14
  76. data/test/unit/test_util.rb +29 -3
  77. data/test/unit/test_waiter.rb +34 -0
  78. data/unicorn.gemspec +8 -7
  79. metadata +19 -13
  80. data/Documentation/GNUmakefile +0 -30
  81. data/Documentation/unicorn.1.txt +0 -187
  82. data/Documentation/unicorn_rails.1.txt +0 -175
  83. data/t/hijack.ru +0 -43
  84. data/t/t0200-rack-hijack.sh +0 -30
@@ -14,8 +14,9 @@
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
- void init_unicorn_httpdate(VALUE mark_ary);
19
+ void init_unicorn_httpdate(void);
19
20
 
20
21
  #define UH_FL_CHUNKED 0x1
21
22
  #define UH_FL_HASBODY 0x2
@@ -28,6 +29,7 @@ void init_unicorn_httpdate(VALUE mark_ary);
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,12 +313,12 @@ 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;
@@ -302,7 +329,7 @@ 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
 
@@ -464,23 +491,23 @@ tr8:
464
491
  }
465
492
  goto st5;
466
493
  tr42:
467
- #line 289 "unicorn_http.rl"
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
502
  tr45:
476
- #line 318 "unicorn_http.rl"
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
509
  tr49:
483
- #line 328 "unicorn_http.rl"
510
+ #line 355 "unicorn_http.rl"
484
511
  {
485
512
  VALUE val;
486
513
 
@@ -491,7 +518,7 @@ tr49:
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
 
@@ -509,14 +536,14 @@ tr49:
509
536
  }
510
537
  goto st5;
511
538
  tr55:
512
- #line 322 "unicorn_http.rl"
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
 
@@ -534,12 +561,12 @@ tr55:
534
561
  }
535
562
  goto st5;
536
563
  tr59:
537
- #line 323 "unicorn_http.rl"
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;
@@ -632,34 +659,34 @@ case 13:
632
659
  goto st13;
633
660
  goto st0;
634
661
  tr18:
635
- #line 327 "unicorn_http.rl"
662
+ #line 354 "unicorn_http.rl"
636
663
  { http_version(hp, PTR_TO(mark), LEN(mark, p)); }
637
664
  goto st14;
638
665
  tr26:
639
- #line 295 "unicorn_http.rl"
666
+ #line 322 "unicorn_http.rl"
640
667
  { MARK(mark, p); }
641
- #line 297 "unicorn_http.rl"
668
+ #line 324 "unicorn_http.rl"
642
669
  { write_cont_value(hp, buffer, p); }
643
670
  goto st14;
644
671
  tr29:
645
- #line 297 "unicorn_http.rl"
672
+ #line 324 "unicorn_http.rl"
646
673
  { write_cont_value(hp, buffer, p); }
647
674
  goto st14;
648
675
  tr36:
649
- #line 295 "unicorn_http.rl"
676
+ #line 322 "unicorn_http.rl"
650
677
  { MARK(mark, p); }
651
- #line 296 "unicorn_http.rl"
678
+ #line 323 "unicorn_http.rl"
652
679
  { write_value(hp, buffer, p); }
653
680
  goto st14;
654
681
  tr39:
655
- #line 296 "unicorn_http.rl"
682
+ #line 323 "unicorn_http.rl"
656
683
  { write_value(hp, buffer, p); }
657
684
  goto st14;
658
685
  st14:
659
686
  if ( ++p == pe )
660
687
  goto _test_eof14;
661
688
  case 14:
662
- #line 663 "unicorn_http.c"
689
+ #line 690 "unicorn_http.c"
663
690
  switch( (*p) ) {
664
691
  case 9: goto st15;
665
692
  case 10: goto tr21;
@@ -688,14 +715,14 @@ case 14:
688
715
  goto tr23;
689
716
  goto st0;
690
717
  tr25:
691
- #line 295 "unicorn_http.rl"
718
+ #line 322 "unicorn_http.rl"
692
719
  { MARK(mark, p); }
693
720
  goto st15;
694
721
  st15:
695
722
  if ( ++p == pe )
696
723
  goto _test_eof15;
697
724
  case 15:
698
- #line 699 "unicorn_http.c"
725
+ #line 726 "unicorn_http.c"
699
726
  switch( (*p) ) {
700
727
  case 9: goto tr25;
701
728
  case 10: goto tr26;
@@ -707,14 +734,14 @@ case 15:
707
734
  goto st0;
708
735
  goto tr24;
709
736
  tr24:
710
- #line 295 "unicorn_http.rl"
737
+ #line 322 "unicorn_http.rl"
711
738
  { MARK(mark, p); }
712
739
  goto st16;
713
740
  st16:
714
741
  if ( ++p == pe )
715
742
  goto _test_eof16;
716
743
  case 16:
717
- #line 718 "unicorn_http.c"
744
+ #line 745 "unicorn_http.c"
718
745
  switch( (*p) ) {
719
746
  case 10: goto tr29;
720
747
  case 13: goto tr30;
@@ -727,39 +754,39 @@ case 16:
727
754
  goto st0;
728
755
  goto st16;
729
756
  tr19:
730
- #line 327 "unicorn_http.rl"
757
+ #line 354 "unicorn_http.rl"
731
758
  { http_version(hp, PTR_TO(mark), LEN(mark, p)); }
732
759
  goto st17;
733
760
  tr27:
734
- #line 295 "unicorn_http.rl"
761
+ #line 322 "unicorn_http.rl"
735
762
  { MARK(mark, p); }
736
- #line 297 "unicorn_http.rl"
763
+ #line 324 "unicorn_http.rl"
737
764
  { write_cont_value(hp, buffer, p); }
738
765
  goto st17;
739
766
  tr30:
740
- #line 297 "unicorn_http.rl"
767
+ #line 324 "unicorn_http.rl"
741
768
  { write_cont_value(hp, buffer, p); }
742
769
  goto st17;
743
770
  tr37:
744
- #line 295 "unicorn_http.rl"
771
+ #line 322 "unicorn_http.rl"
745
772
  { MARK(mark, p); }
746
- #line 296 "unicorn_http.rl"
773
+ #line 323 "unicorn_http.rl"
747
774
  { write_value(hp, buffer, p); }
748
775
  goto st17;
749
776
  tr40:
750
- #line 296 "unicorn_http.rl"
777
+ #line 323 "unicorn_http.rl"
751
778
  { write_value(hp, buffer, p); }
752
779
  goto st17;
753
780
  st17:
754
781
  if ( ++p == pe )
755
782
  goto _test_eof17;
756
783
  case 17:
757
- #line 758 "unicorn_http.c"
784
+ #line 785 "unicorn_http.c"
758
785
  if ( (*p) == 10 )
759
786
  goto st14;
760
787
  goto st0;
761
788
  tr21:
762
- #line 343 "unicorn_http.rl"
789
+ #line 370 "unicorn_http.rl"
763
790
  {
764
791
  finalize_header(hp);
765
792
 
@@ -780,7 +807,7 @@ tr21:
780
807
  }
781
808
  goto st122;
782
809
  tr104:
783
- #line 303 "unicorn_http.rl"
810
+ #line 330 "unicorn_http.rl"
784
811
  {
785
812
  VALUE str;
786
813
 
@@ -796,7 +823,7 @@ tr104:
796
823
  rb_hash_aset(hp->env, g_request_path, str);
797
824
  }
798
825
  }
799
- #line 343 "unicorn_http.rl"
826
+ #line 370 "unicorn_http.rl"
800
827
  {
801
828
  finalize_header(hp);
802
829
 
@@ -817,14 +844,14 @@ tr104:
817
844
  }
818
845
  goto st122;
819
846
  tr108:
820
- #line 289 "unicorn_http.rl"
847
+ #line 316 "unicorn_http.rl"
821
848
  {MARK(mark, p); }
822
- #line 318 "unicorn_http.rl"
849
+ #line 345 "unicorn_http.rl"
823
850
  {
824
851
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
825
852
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
826
853
  }
827
- #line 343 "unicorn_http.rl"
854
+ #line 370 "unicorn_http.rl"
828
855
  {
829
856
  finalize_header(hp);
830
857
 
@@ -845,12 +872,12 @@ tr108:
845
872
  }
846
873
  goto st122;
847
874
  tr112:
848
- #line 318 "unicorn_http.rl"
875
+ #line 345 "unicorn_http.rl"
849
876
  {
850
877
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
851
878
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
852
879
  }
853
- #line 343 "unicorn_http.rl"
880
+ #line 370 "unicorn_http.rl"
854
881
  {
855
882
  finalize_header(hp);
856
883
 
@@ -871,7 +898,7 @@ tr112:
871
898
  }
872
899
  goto st122;
873
900
  tr117:
874
- #line 328 "unicorn_http.rl"
901
+ #line 355 "unicorn_http.rl"
875
902
  {
876
903
  VALUE val;
877
904
 
@@ -882,7 +909,7 @@ tr117:
882
909
  if (!STR_CSTR_EQ(val, "*"))
883
910
  rb_hash_aset(hp->env, g_path_info, val);
884
911
  }
885
- #line 303 "unicorn_http.rl"
912
+ #line 330 "unicorn_http.rl"
886
913
  {
887
914
  VALUE str;
888
915
 
@@ -898,7 +925,7 @@ tr117:
898
925
  rb_hash_aset(hp->env, g_request_path, str);
899
926
  }
900
927
  }
901
- #line 343 "unicorn_http.rl"
928
+ #line 370 "unicorn_http.rl"
902
929
  {
903
930
  finalize_header(hp);
904
931
 
@@ -919,14 +946,14 @@ tr117:
919
946
  }
920
947
  goto st122;
921
948
  tr124:
922
- #line 322 "unicorn_http.rl"
949
+ #line 349 "unicorn_http.rl"
923
950
  {MARK(start.query, p); }
924
- #line 323 "unicorn_http.rl"
951
+ #line 350 "unicorn_http.rl"
925
952
  {
926
953
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
927
954
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
928
955
  }
929
- #line 303 "unicorn_http.rl"
956
+ #line 330 "unicorn_http.rl"
930
957
  {
931
958
  VALUE str;
932
959
 
@@ -942,7 +969,7 @@ tr124:
942
969
  rb_hash_aset(hp->env, g_request_path, str);
943
970
  }
944
971
  }
945
- #line 343 "unicorn_http.rl"
972
+ #line 370 "unicorn_http.rl"
946
973
  {
947
974
  finalize_header(hp);
948
975
 
@@ -963,12 +990,12 @@ tr124:
963
990
  }
964
991
  goto st122;
965
992
  tr129:
966
- #line 323 "unicorn_http.rl"
993
+ #line 350 "unicorn_http.rl"
967
994
  {
968
995
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
969
996
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
970
997
  }
971
- #line 303 "unicorn_http.rl"
998
+ #line 330 "unicorn_http.rl"
972
999
  {
973
1000
  VALUE str;
974
1001
 
@@ -984,7 +1011,7 @@ tr129:
984
1011
  rb_hash_aset(hp->env, g_request_path, str);
985
1012
  }
986
1013
  }
987
- #line 343 "unicorn_http.rl"
1014
+ #line 370 "unicorn_http.rl"
988
1015
  {
989
1016
  finalize_header(hp);
990
1017
 
@@ -1008,10 +1035,10 @@ st122:
1008
1035
  if ( ++p == pe )
1009
1036
  goto _test_eof122;
1010
1037
  case 122:
1011
- #line 1012 "unicorn_http.c"
1038
+ #line 1039 "unicorn_http.c"
1012
1039
  goto st0;
1013
1040
  tr105:
1014
- #line 303 "unicorn_http.rl"
1041
+ #line 330 "unicorn_http.rl"
1015
1042
  {
1016
1043
  VALUE str;
1017
1044
 
@@ -1029,23 +1056,23 @@ tr105:
1029
1056
  }
1030
1057
  goto st18;
1031
1058
  tr109:
1032
- #line 289 "unicorn_http.rl"
1059
+ #line 316 "unicorn_http.rl"
1033
1060
  {MARK(mark, p); }
1034
- #line 318 "unicorn_http.rl"
1061
+ #line 345 "unicorn_http.rl"
1035
1062
  {
1036
1063
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
1037
1064
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
1038
1065
  }
1039
1066
  goto st18;
1040
1067
  tr113:
1041
- #line 318 "unicorn_http.rl"
1068
+ #line 345 "unicorn_http.rl"
1042
1069
  {
1043
1070
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
1044
1071
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
1045
1072
  }
1046
1073
  goto st18;
1047
1074
  tr118:
1048
- #line 328 "unicorn_http.rl"
1075
+ #line 355 "unicorn_http.rl"
1049
1076
  {
1050
1077
  VALUE val;
1051
1078
 
@@ -1056,7 +1083,7 @@ tr118:
1056
1083
  if (!STR_CSTR_EQ(val, "*"))
1057
1084
  rb_hash_aset(hp->env, g_path_info, val);
1058
1085
  }
1059
- #line 303 "unicorn_http.rl"
1086
+ #line 330 "unicorn_http.rl"
1060
1087
  {
1061
1088
  VALUE str;
1062
1089
 
@@ -1074,14 +1101,14 @@ tr118:
1074
1101
  }
1075
1102
  goto st18;
1076
1103
  tr125:
1077
- #line 322 "unicorn_http.rl"
1104
+ #line 349 "unicorn_http.rl"
1078
1105
  {MARK(start.query, p); }
1079
- #line 323 "unicorn_http.rl"
1106
+ #line 350 "unicorn_http.rl"
1080
1107
  {
1081
1108
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1082
1109
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1083
1110
  }
1084
- #line 303 "unicorn_http.rl"
1111
+ #line 330 "unicorn_http.rl"
1085
1112
  {
1086
1113
  VALUE str;
1087
1114
 
@@ -1099,12 +1126,12 @@ tr125:
1099
1126
  }
1100
1127
  goto st18;
1101
1128
  tr130:
1102
- #line 323 "unicorn_http.rl"
1129
+ #line 350 "unicorn_http.rl"
1103
1130
  {
1104
1131
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1105
1132
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1106
1133
  }
1107
- #line 303 "unicorn_http.rl"
1134
+ #line 330 "unicorn_http.rl"
1108
1135
  {
1109
1136
  VALUE str;
1110
1137
 
@@ -1125,25 +1152,25 @@ st18:
1125
1152
  if ( ++p == pe )
1126
1153
  goto _test_eof18;
1127
1154
  case 18:
1128
- #line 1129 "unicorn_http.c"
1155
+ #line 1156 "unicorn_http.c"
1129
1156
  if ( (*p) == 10 )
1130
1157
  goto tr21;
1131
1158
  goto st0;
1132
1159
  tr23:
1133
- #line 291 "unicorn_http.rl"
1160
+ #line 318 "unicorn_http.rl"
1134
1161
  { MARK(start.field, p); }
1135
- #line 292 "unicorn_http.rl"
1162
+ #line 319 "unicorn_http.rl"
1136
1163
  { snake_upcase_char(deconst(p)); }
1137
1164
  goto st19;
1138
1165
  tr32:
1139
- #line 292 "unicorn_http.rl"
1166
+ #line 319 "unicorn_http.rl"
1140
1167
  { snake_upcase_char(deconst(p)); }
1141
1168
  goto st19;
1142
1169
  st19:
1143
1170
  if ( ++p == pe )
1144
1171
  goto _test_eof19;
1145
1172
  case 19:
1146
- #line 1147 "unicorn_http.c"
1173
+ #line 1174 "unicorn_http.c"
1147
1174
  switch( (*p) ) {
1148
1175
  case 33: goto tr32;
1149
1176
  case 58: goto tr33;
@@ -1169,18 +1196,18 @@ case 19:
1169
1196
  goto tr32;
1170
1197
  goto st0;
1171
1198
  tr35:
1172
- #line 295 "unicorn_http.rl"
1199
+ #line 322 "unicorn_http.rl"
1173
1200
  { MARK(mark, p); }
1174
1201
  goto st20;
1175
1202
  tr33:
1176
- #line 294 "unicorn_http.rl"
1203
+ #line 321 "unicorn_http.rl"
1177
1204
  { hp->s.field_len = LEN(start.field, p); }
1178
1205
  goto st20;
1179
1206
  st20:
1180
1207
  if ( ++p == pe )
1181
1208
  goto _test_eof20;
1182
1209
  case 20:
1183
- #line 1184 "unicorn_http.c"
1210
+ #line 1211 "unicorn_http.c"
1184
1211
  switch( (*p) ) {
1185
1212
  case 9: goto tr35;
1186
1213
  case 10: goto tr36;
@@ -1192,14 +1219,14 @@ case 20:
1192
1219
  goto st0;
1193
1220
  goto tr34;
1194
1221
  tr34:
1195
- #line 295 "unicorn_http.rl"
1222
+ #line 322 "unicorn_http.rl"
1196
1223
  { MARK(mark, p); }
1197
1224
  goto st21;
1198
1225
  st21:
1199
1226
  if ( ++p == pe )
1200
1227
  goto _test_eof21;
1201
1228
  case 21:
1202
- #line 1203 "unicorn_http.c"
1229
+ #line 1230 "unicorn_http.c"
1203
1230
  switch( (*p) ) {
1204
1231
  case 10: goto tr39;
1205
1232
  case 13: goto tr40;
@@ -1212,7 +1239,7 @@ case 21:
1212
1239
  goto st0;
1213
1240
  goto st21;
1214
1241
  tr9:
1215
- #line 303 "unicorn_http.rl"
1242
+ #line 330 "unicorn_http.rl"
1216
1243
  {
1217
1244
  VALUE str;
1218
1245
 
@@ -1230,7 +1257,7 @@ tr9:
1230
1257
  }
1231
1258
  goto st22;
1232
1259
  tr50:
1233
- #line 328 "unicorn_http.rl"
1260
+ #line 355 "unicorn_http.rl"
1234
1261
  {
1235
1262
  VALUE val;
1236
1263
 
@@ -1241,7 +1268,7 @@ tr50:
1241
1268
  if (!STR_CSTR_EQ(val, "*"))
1242
1269
  rb_hash_aset(hp->env, g_path_info, val);
1243
1270
  }
1244
- #line 303 "unicorn_http.rl"
1271
+ #line 330 "unicorn_http.rl"
1245
1272
  {
1246
1273
  VALUE str;
1247
1274
 
@@ -1259,14 +1286,14 @@ tr50:
1259
1286
  }
1260
1287
  goto st22;
1261
1288
  tr56:
1262
- #line 322 "unicorn_http.rl"
1289
+ #line 349 "unicorn_http.rl"
1263
1290
  {MARK(start.query, p); }
1264
- #line 323 "unicorn_http.rl"
1291
+ #line 350 "unicorn_http.rl"
1265
1292
  {
1266
1293
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1267
1294
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1268
1295
  }
1269
- #line 303 "unicorn_http.rl"
1296
+ #line 330 "unicorn_http.rl"
1270
1297
  {
1271
1298
  VALUE str;
1272
1299
 
@@ -1284,12 +1311,12 @@ tr56:
1284
1311
  }
1285
1312
  goto st22;
1286
1313
  tr60:
1287
- #line 323 "unicorn_http.rl"
1314
+ #line 350 "unicorn_http.rl"
1288
1315
  {
1289
1316
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1290
1317
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1291
1318
  }
1292
- #line 303 "unicorn_http.rl"
1319
+ #line 330 "unicorn_http.rl"
1293
1320
  {
1294
1321
  VALUE str;
1295
1322
 
@@ -1310,7 +1337,7 @@ st22:
1310
1337
  if ( ++p == pe )
1311
1338
  goto _test_eof22;
1312
1339
  case 22:
1313
- #line 1314 "unicorn_http.c"
1340
+ #line 1341 "unicorn_http.c"
1314
1341
  switch( (*p) ) {
1315
1342
  case 32: goto tr42;
1316
1343
  case 35: goto st0;
@@ -1321,14 +1348,14 @@ case 22:
1321
1348
  goto st0;
1322
1349
  goto tr41;
1323
1350
  tr41:
1324
- #line 289 "unicorn_http.rl"
1351
+ #line 316 "unicorn_http.rl"
1325
1352
  {MARK(mark, p); }
1326
1353
  goto st23;
1327
1354
  st23:
1328
1355
  if ( ++p == pe )
1329
1356
  goto _test_eof23;
1330
1357
  case 23:
1331
- #line 1332 "unicorn_http.c"
1358
+ #line 1359 "unicorn_http.c"
1332
1359
  switch( (*p) ) {
1333
1360
  case 32: goto tr45;
1334
1361
  case 35: goto st0;
@@ -1339,14 +1366,14 @@ case 23:
1339
1366
  goto st0;
1340
1367
  goto st23;
1341
1368
  tr43:
1342
- #line 289 "unicorn_http.rl"
1369
+ #line 316 "unicorn_http.rl"
1343
1370
  {MARK(mark, p); }
1344
1371
  goto st24;
1345
1372
  st24:
1346
1373
  if ( ++p == pe )
1347
1374
  goto _test_eof24;
1348
1375
  case 24:
1349
- #line 1350 "unicorn_http.c"
1376
+ #line 1377 "unicorn_http.c"
1350
1377
  if ( (*p) < 65 ) {
1351
1378
  if ( 48 <= (*p) && (*p) <= 57 )
1352
1379
  goto st25;
@@ -1370,20 +1397,20 @@ case 25:
1370
1397
  goto st23;
1371
1398
  goto st0;
1372
1399
  tr6:
1373
- #line 289 "unicorn_http.rl"
1400
+ #line 316 "unicorn_http.rl"
1374
1401
  {MARK(mark, p); }
1375
1402
  goto st26;
1376
1403
  tr76:
1377
- #line 302 "unicorn_http.rl"
1404
+ #line 329 "unicorn_http.rl"
1378
1405
  { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
1379
- #line 289 "unicorn_http.rl"
1406
+ #line 316 "unicorn_http.rl"
1380
1407
  {MARK(mark, p); }
1381
1408
  goto st26;
1382
1409
  st26:
1383
1410
  if ( ++p == pe )
1384
1411
  goto _test_eof26;
1385
1412
  case 26:
1386
- #line 1387 "unicorn_http.c"
1413
+ #line 1414 "unicorn_http.c"
1387
1414
  switch( (*p) ) {
1388
1415
  case 32: goto tr49;
1389
1416
  case 35: goto tr50;
@@ -1421,7 +1448,7 @@ case 28:
1421
1448
  goto st26;
1422
1449
  goto st0;
1423
1450
  tr52:
1424
- #line 328 "unicorn_http.rl"
1451
+ #line 355 "unicorn_http.rl"
1425
1452
  {
1426
1453
  VALUE val;
1427
1454
 
@@ -1437,7 +1464,7 @@ st29:
1437
1464
  if ( ++p == pe )
1438
1465
  goto _test_eof29;
1439
1466
  case 29:
1440
- #line 1441 "unicorn_http.c"
1467
+ #line 1468 "unicorn_http.c"
1441
1468
  switch( (*p) ) {
1442
1469
  case 32: goto tr55;
1443
1470
  case 35: goto tr56;
@@ -1448,14 +1475,14 @@ case 29:
1448
1475
  goto st0;
1449
1476
  goto tr54;
1450
1477
  tr54:
1451
- #line 322 "unicorn_http.rl"
1478
+ #line 349 "unicorn_http.rl"
1452
1479
  {MARK(start.query, p); }
1453
1480
  goto st30;
1454
1481
  st30:
1455
1482
  if ( ++p == pe )
1456
1483
  goto _test_eof30;
1457
1484
  case 30:
1458
- #line 1459 "unicorn_http.c"
1485
+ #line 1486 "unicorn_http.c"
1459
1486
  switch( (*p) ) {
1460
1487
  case 32: goto tr59;
1461
1488
  case 35: goto tr60;
@@ -1466,14 +1493,14 @@ case 30:
1466
1493
  goto st0;
1467
1494
  goto st30;
1468
1495
  tr57:
1469
- #line 322 "unicorn_http.rl"
1496
+ #line 349 "unicorn_http.rl"
1470
1497
  {MARK(start.query, p); }
1471
1498
  goto st31;
1472
1499
  st31:
1473
1500
  if ( ++p == pe )
1474
1501
  goto _test_eof31;
1475
1502
  case 31:
1476
- #line 1477 "unicorn_http.c"
1503
+ #line 1504 "unicorn_http.c"
1477
1504
  if ( (*p) < 65 ) {
1478
1505
  if ( 48 <= (*p) && (*p) <= 57 )
1479
1506
  goto st32;
@@ -1497,58 +1524,58 @@ case 32:
1497
1524
  goto st30;
1498
1525
  goto st0;
1499
1526
  tr7:
1500
- #line 289 "unicorn_http.rl"
1527
+ #line 316 "unicorn_http.rl"
1501
1528
  {MARK(mark, p); }
1502
- #line 293 "unicorn_http.rl"
1529
+ #line 320 "unicorn_http.rl"
1503
1530
  { downcase_char(deconst(p)); }
1504
1531
  goto st33;
1505
1532
  st33:
1506
1533
  if ( ++p == pe )
1507
1534
  goto _test_eof33;
1508
1535
  case 33:
1509
- #line 1510 "unicorn_http.c"
1536
+ #line 1537 "unicorn_http.c"
1510
1537
  switch( (*p) ) {
1511
1538
  case 84: goto tr63;
1512
1539
  case 116: goto tr63;
1513
1540
  }
1514
1541
  goto st0;
1515
1542
  tr63:
1516
- #line 293 "unicorn_http.rl"
1543
+ #line 320 "unicorn_http.rl"
1517
1544
  { downcase_char(deconst(p)); }
1518
1545
  goto st34;
1519
1546
  st34:
1520
1547
  if ( ++p == pe )
1521
1548
  goto _test_eof34;
1522
1549
  case 34:
1523
- #line 1524 "unicorn_http.c"
1550
+ #line 1551 "unicorn_http.c"
1524
1551
  switch( (*p) ) {
1525
1552
  case 84: goto tr64;
1526
1553
  case 116: goto tr64;
1527
1554
  }
1528
1555
  goto st0;
1529
1556
  tr64:
1530
- #line 293 "unicorn_http.rl"
1557
+ #line 320 "unicorn_http.rl"
1531
1558
  { downcase_char(deconst(p)); }
1532
1559
  goto st35;
1533
1560
  st35:
1534
1561
  if ( ++p == pe )
1535
1562
  goto _test_eof35;
1536
1563
  case 35:
1537
- #line 1538 "unicorn_http.c"
1564
+ #line 1565 "unicorn_http.c"
1538
1565
  switch( (*p) ) {
1539
1566
  case 80: goto tr65;
1540
1567
  case 112: goto tr65;
1541
1568
  }
1542
1569
  goto st0;
1543
1570
  tr65:
1544
- #line 293 "unicorn_http.rl"
1571
+ #line 320 "unicorn_http.rl"
1545
1572
  { downcase_char(deconst(p)); }
1546
1573
  goto st36;
1547
1574
  st36:
1548
1575
  if ( ++p == pe )
1549
1576
  goto _test_eof36;
1550
1577
  case 36:
1551
- #line 1552 "unicorn_http.c"
1578
+ #line 1579 "unicorn_http.c"
1552
1579
  switch( (*p) ) {
1553
1580
  case 58: goto tr66;
1554
1581
  case 83: goto tr67;
@@ -1556,7 +1583,7 @@ case 36:
1556
1583
  }
1557
1584
  goto st0;
1558
1585
  tr66:
1559
- #line 299 "unicorn_http.rl"
1586
+ #line 326 "unicorn_http.rl"
1560
1587
  {
1561
1588
  rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
1562
1589
  }
@@ -1565,7 +1592,7 @@ st37:
1565
1592
  if ( ++p == pe )
1566
1593
  goto _test_eof37;
1567
1594
  case 37:
1568
- #line 1569 "unicorn_http.c"
1595
+ #line 1596 "unicorn_http.c"
1569
1596
  if ( (*p) == 47 )
1570
1597
  goto st38;
1571
1598
  goto st0;
@@ -1653,14 +1680,14 @@ case 42:
1653
1680
  goto st40;
1654
1681
  goto st0;
1655
1682
  tr72:
1656
- #line 289 "unicorn_http.rl"
1683
+ #line 316 "unicorn_http.rl"
1657
1684
  {MARK(mark, p); }
1658
1685
  goto st43;
1659
1686
  st43:
1660
1687
  if ( ++p == pe )
1661
1688
  goto _test_eof43;
1662
1689
  case 43:
1663
- #line 1664 "unicorn_http.c"
1690
+ #line 1691 "unicorn_http.c"
1664
1691
  switch( (*p) ) {
1665
1692
  case 37: goto st41;
1666
1693
  case 47: goto tr76;
@@ -1712,14 +1739,14 @@ case 44:
1712
1739
  goto st0;
1713
1740
  goto st40;
1714
1741
  tr73:
1715
- #line 289 "unicorn_http.rl"
1742
+ #line 316 "unicorn_http.rl"
1716
1743
  {MARK(mark, p); }
1717
1744
  goto st45;
1718
1745
  st45:
1719
1746
  if ( ++p == pe )
1720
1747
  goto _test_eof45;
1721
1748
  case 45:
1722
- #line 1723 "unicorn_http.c"
1749
+ #line 1750 "unicorn_http.c"
1723
1750
  switch( (*p) ) {
1724
1751
  case 37: goto st41;
1725
1752
  case 47: goto st0;
@@ -1797,14 +1824,14 @@ case 47:
1797
1824
  goto st0;
1798
1825
  goto st40;
1799
1826
  tr67:
1800
- #line 293 "unicorn_http.rl"
1827
+ #line 320 "unicorn_http.rl"
1801
1828
  { downcase_char(deconst(p)); }
1802
1829
  goto st48;
1803
1830
  st48:
1804
1831
  if ( ++p == pe )
1805
1832
  goto _test_eof48;
1806
1833
  case 48:
1807
- #line 1808 "unicorn_http.c"
1834
+ #line 1835 "unicorn_http.c"
1808
1835
  if ( (*p) == 58 )
1809
1836
  goto tr66;
1810
1837
  goto st0;
@@ -2320,14 +2347,14 @@ case 67:
2320
2347
  goto tr3;
2321
2348
  goto st0;
2322
2349
  tr2:
2323
- #line 289 "unicorn_http.rl"
2350
+ #line 316 "unicorn_http.rl"
2324
2351
  {MARK(mark, p); }
2325
2352
  goto st68;
2326
2353
  st68:
2327
2354
  if ( ++p == pe )
2328
2355
  goto _test_eof68;
2329
2356
  case 68:
2330
- #line 2331 "unicorn_http.c"
2357
+ #line 2358 "unicorn_http.c"
2331
2358
  switch( (*p) ) {
2332
2359
  case 32: goto tr3;
2333
2360
  case 33: goto st49;
@@ -2411,14 +2438,14 @@ case 70:
2411
2438
  goto st51;
2412
2439
  goto st0;
2413
2440
  tr100:
2414
- #line 298 "unicorn_http.rl"
2441
+ #line 325 "unicorn_http.rl"
2415
2442
  { request_method(hp, PTR_TO(mark), LEN(mark, p)); }
2416
2443
  goto st71;
2417
2444
  st71:
2418
2445
  if ( ++p == pe )
2419
2446
  goto _test_eof71;
2420
2447
  case 71:
2421
- #line 2422 "unicorn_http.c"
2448
+ #line 2449 "unicorn_http.c"
2422
2449
  switch( (*p) ) {
2423
2450
  case 42: goto tr101;
2424
2451
  case 47: goto tr102;
@@ -2427,14 +2454,14 @@ case 71:
2427
2454
  }
2428
2455
  goto st0;
2429
2456
  tr101:
2430
- #line 289 "unicorn_http.rl"
2457
+ #line 316 "unicorn_http.rl"
2431
2458
  {MARK(mark, p); }
2432
2459
  goto st72;
2433
2460
  st72:
2434
2461
  if ( ++p == pe )
2435
2462
  goto _test_eof72;
2436
2463
  case 72:
2437
- #line 2438 "unicorn_http.c"
2464
+ #line 2465 "unicorn_http.c"
2438
2465
  switch( (*p) ) {
2439
2466
  case 10: goto tr104;
2440
2467
  case 13: goto tr105;
@@ -2443,7 +2470,7 @@ case 72:
2443
2470
  }
2444
2471
  goto st0;
2445
2472
  tr106:
2446
- #line 303 "unicorn_http.rl"
2473
+ #line 330 "unicorn_http.rl"
2447
2474
  {
2448
2475
  VALUE str;
2449
2476
 
@@ -2461,7 +2488,7 @@ tr106:
2461
2488
  }
2462
2489
  goto st73;
2463
2490
  tr119:
2464
- #line 328 "unicorn_http.rl"
2491
+ #line 355 "unicorn_http.rl"
2465
2492
  {
2466
2493
  VALUE val;
2467
2494
 
@@ -2472,7 +2499,7 @@ tr119:
2472
2499
  if (!STR_CSTR_EQ(val, "*"))
2473
2500
  rb_hash_aset(hp->env, g_path_info, val);
2474
2501
  }
2475
- #line 303 "unicorn_http.rl"
2502
+ #line 330 "unicorn_http.rl"
2476
2503
  {
2477
2504
  VALUE str;
2478
2505
 
@@ -2490,14 +2517,14 @@ tr119:
2490
2517
  }
2491
2518
  goto st73;
2492
2519
  tr126:
2493
- #line 322 "unicorn_http.rl"
2520
+ #line 349 "unicorn_http.rl"
2494
2521
  {MARK(start.query, p); }
2495
- #line 323 "unicorn_http.rl"
2522
+ #line 350 "unicorn_http.rl"
2496
2523
  {
2497
2524
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
2498
2525
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
2499
2526
  }
2500
- #line 303 "unicorn_http.rl"
2527
+ #line 330 "unicorn_http.rl"
2501
2528
  {
2502
2529
  VALUE str;
2503
2530
 
@@ -2515,12 +2542,12 @@ tr126:
2515
2542
  }
2516
2543
  goto st73;
2517
2544
  tr131:
2518
- #line 323 "unicorn_http.rl"
2545
+ #line 350 "unicorn_http.rl"
2519
2546
  {
2520
2547
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
2521
2548
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
2522
2549
  }
2523
- #line 303 "unicorn_http.rl"
2550
+ #line 330 "unicorn_http.rl"
2524
2551
  {
2525
2552
  VALUE str;
2526
2553
 
@@ -2541,7 +2568,7 @@ st73:
2541
2568
  if ( ++p == pe )
2542
2569
  goto _test_eof73;
2543
2570
  case 73:
2544
- #line 2545 "unicorn_http.c"
2571
+ #line 2572 "unicorn_http.c"
2545
2572
  switch( (*p) ) {
2546
2573
  case 10: goto tr108;
2547
2574
  case 13: goto tr109;
@@ -2554,14 +2581,14 @@ case 73:
2554
2581
  goto st0;
2555
2582
  goto tr107;
2556
2583
  tr107:
2557
- #line 289 "unicorn_http.rl"
2584
+ #line 316 "unicorn_http.rl"
2558
2585
  {MARK(mark, p); }
2559
2586
  goto st74;
2560
2587
  st74:
2561
2588
  if ( ++p == pe )
2562
2589
  goto _test_eof74;
2563
2590
  case 74:
2564
- #line 2565 "unicorn_http.c"
2591
+ #line 2592 "unicorn_http.c"
2565
2592
  switch( (*p) ) {
2566
2593
  case 10: goto tr112;
2567
2594
  case 13: goto tr113;
@@ -2574,14 +2601,14 @@ case 74:
2574
2601
  goto st0;
2575
2602
  goto st74;
2576
2603
  tr110:
2577
- #line 289 "unicorn_http.rl"
2604
+ #line 316 "unicorn_http.rl"
2578
2605
  {MARK(mark, p); }
2579
2606
  goto st75;
2580
2607
  st75:
2581
2608
  if ( ++p == pe )
2582
2609
  goto _test_eof75;
2583
2610
  case 75:
2584
- #line 2585 "unicorn_http.c"
2611
+ #line 2612 "unicorn_http.c"
2585
2612
  if ( (*p) < 65 ) {
2586
2613
  if ( 48 <= (*p) && (*p) <= 57 )
2587
2614
  goto st76;
@@ -2605,20 +2632,20 @@ case 76:
2605
2632
  goto st74;
2606
2633
  goto st0;
2607
2634
  tr102:
2608
- #line 289 "unicorn_http.rl"
2635
+ #line 316 "unicorn_http.rl"
2609
2636
  {MARK(mark, p); }
2610
2637
  goto st77;
2611
2638
  tr147:
2612
- #line 302 "unicorn_http.rl"
2639
+ #line 329 "unicorn_http.rl"
2613
2640
  { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
2614
- #line 289 "unicorn_http.rl"
2641
+ #line 316 "unicorn_http.rl"
2615
2642
  {MARK(mark, p); }
2616
2643
  goto st77;
2617
2644
  st77:
2618
2645
  if ( ++p == pe )
2619
2646
  goto _test_eof77;
2620
2647
  case 77:
2621
- #line 2622 "unicorn_http.c"
2648
+ #line 2649 "unicorn_http.c"
2622
2649
  switch( (*p) ) {
2623
2650
  case 10: goto tr117;
2624
2651
  case 13: goto tr118;
@@ -2658,7 +2685,7 @@ case 79:
2658
2685
  goto st77;
2659
2686
  goto st0;
2660
2687
  tr121:
2661
- #line 328 "unicorn_http.rl"
2688
+ #line 355 "unicorn_http.rl"
2662
2689
  {
2663
2690
  VALUE val;
2664
2691
 
@@ -2674,7 +2701,7 @@ st80:
2674
2701
  if ( ++p == pe )
2675
2702
  goto _test_eof80;
2676
2703
  case 80:
2677
- #line 2678 "unicorn_http.c"
2704
+ #line 2705 "unicorn_http.c"
2678
2705
  switch( (*p) ) {
2679
2706
  case 10: goto tr124;
2680
2707
  case 13: goto tr125;
@@ -2687,14 +2714,14 @@ case 80:
2687
2714
  goto st0;
2688
2715
  goto tr123;
2689
2716
  tr123:
2690
- #line 322 "unicorn_http.rl"
2717
+ #line 349 "unicorn_http.rl"
2691
2718
  {MARK(start.query, p); }
2692
2719
  goto st81;
2693
2720
  st81:
2694
2721
  if ( ++p == pe )
2695
2722
  goto _test_eof81;
2696
2723
  case 81:
2697
- #line 2698 "unicorn_http.c"
2724
+ #line 2725 "unicorn_http.c"
2698
2725
  switch( (*p) ) {
2699
2726
  case 10: goto tr129;
2700
2727
  case 13: goto tr130;
@@ -2707,14 +2734,14 @@ case 81:
2707
2734
  goto st0;
2708
2735
  goto st81;
2709
2736
  tr127:
2710
- #line 322 "unicorn_http.rl"
2737
+ #line 349 "unicorn_http.rl"
2711
2738
  {MARK(start.query, p); }
2712
2739
  goto st82;
2713
2740
  st82:
2714
2741
  if ( ++p == pe )
2715
2742
  goto _test_eof82;
2716
2743
  case 82:
2717
- #line 2718 "unicorn_http.c"
2744
+ #line 2745 "unicorn_http.c"
2718
2745
  if ( (*p) < 65 ) {
2719
2746
  if ( 48 <= (*p) && (*p) <= 57 )
2720
2747
  goto st83;
@@ -2738,58 +2765,58 @@ case 83:
2738
2765
  goto st81;
2739
2766
  goto st0;
2740
2767
  tr103:
2741
- #line 289 "unicorn_http.rl"
2768
+ #line 316 "unicorn_http.rl"
2742
2769
  {MARK(mark, p); }
2743
- #line 293 "unicorn_http.rl"
2770
+ #line 320 "unicorn_http.rl"
2744
2771
  { downcase_char(deconst(p)); }
2745
2772
  goto st84;
2746
2773
  st84:
2747
2774
  if ( ++p == pe )
2748
2775
  goto _test_eof84;
2749
2776
  case 84:
2750
- #line 2751 "unicorn_http.c"
2777
+ #line 2778 "unicorn_http.c"
2751
2778
  switch( (*p) ) {
2752
2779
  case 84: goto tr134;
2753
2780
  case 116: goto tr134;
2754
2781
  }
2755
2782
  goto st0;
2756
2783
  tr134:
2757
- #line 293 "unicorn_http.rl"
2784
+ #line 320 "unicorn_http.rl"
2758
2785
  { downcase_char(deconst(p)); }
2759
2786
  goto st85;
2760
2787
  st85:
2761
2788
  if ( ++p == pe )
2762
2789
  goto _test_eof85;
2763
2790
  case 85:
2764
- #line 2765 "unicorn_http.c"
2791
+ #line 2792 "unicorn_http.c"
2765
2792
  switch( (*p) ) {
2766
2793
  case 84: goto tr135;
2767
2794
  case 116: goto tr135;
2768
2795
  }
2769
2796
  goto st0;
2770
2797
  tr135:
2771
- #line 293 "unicorn_http.rl"
2798
+ #line 320 "unicorn_http.rl"
2772
2799
  { downcase_char(deconst(p)); }
2773
2800
  goto st86;
2774
2801
  st86:
2775
2802
  if ( ++p == pe )
2776
2803
  goto _test_eof86;
2777
2804
  case 86:
2778
- #line 2779 "unicorn_http.c"
2805
+ #line 2806 "unicorn_http.c"
2779
2806
  switch( (*p) ) {
2780
2807
  case 80: goto tr136;
2781
2808
  case 112: goto tr136;
2782
2809
  }
2783
2810
  goto st0;
2784
2811
  tr136:
2785
- #line 293 "unicorn_http.rl"
2812
+ #line 320 "unicorn_http.rl"
2786
2813
  { downcase_char(deconst(p)); }
2787
2814
  goto st87;
2788
2815
  st87:
2789
2816
  if ( ++p == pe )
2790
2817
  goto _test_eof87;
2791
2818
  case 87:
2792
- #line 2793 "unicorn_http.c"
2819
+ #line 2820 "unicorn_http.c"
2793
2820
  switch( (*p) ) {
2794
2821
  case 58: goto tr137;
2795
2822
  case 83: goto tr138;
@@ -2797,7 +2824,7 @@ case 87:
2797
2824
  }
2798
2825
  goto st0;
2799
2826
  tr137:
2800
- #line 299 "unicorn_http.rl"
2827
+ #line 326 "unicorn_http.rl"
2801
2828
  {
2802
2829
  rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
2803
2830
  }
@@ -2806,7 +2833,7 @@ st88:
2806
2833
  if ( ++p == pe )
2807
2834
  goto _test_eof88;
2808
2835
  case 88:
2809
- #line 2810 "unicorn_http.c"
2836
+ #line 2837 "unicorn_http.c"
2810
2837
  if ( (*p) == 47 )
2811
2838
  goto st89;
2812
2839
  goto st0;
@@ -2894,14 +2921,14 @@ case 93:
2894
2921
  goto st91;
2895
2922
  goto st0;
2896
2923
  tr143:
2897
- #line 289 "unicorn_http.rl"
2924
+ #line 316 "unicorn_http.rl"
2898
2925
  {MARK(mark, p); }
2899
2926
  goto st94;
2900
2927
  st94:
2901
2928
  if ( ++p == pe )
2902
2929
  goto _test_eof94;
2903
2930
  case 94:
2904
- #line 2905 "unicorn_http.c"
2931
+ #line 2932 "unicorn_http.c"
2905
2932
  switch( (*p) ) {
2906
2933
  case 37: goto st92;
2907
2934
  case 47: goto tr147;
@@ -2953,14 +2980,14 @@ case 95:
2953
2980
  goto st0;
2954
2981
  goto st91;
2955
2982
  tr144:
2956
- #line 289 "unicorn_http.rl"
2983
+ #line 316 "unicorn_http.rl"
2957
2984
  {MARK(mark, p); }
2958
2985
  goto st96;
2959
2986
  st96:
2960
2987
  if ( ++p == pe )
2961
2988
  goto _test_eof96;
2962
2989
  case 96:
2963
- #line 2964 "unicorn_http.c"
2990
+ #line 2991 "unicorn_http.c"
2964
2991
  switch( (*p) ) {
2965
2992
  case 37: goto st92;
2966
2993
  case 47: goto st0;
@@ -3038,14 +3065,14 @@ case 98:
3038
3065
  goto st0;
3039
3066
  goto st91;
3040
3067
  tr138:
3041
- #line 293 "unicorn_http.rl"
3068
+ #line 320 "unicorn_http.rl"
3042
3069
  { downcase_char(deconst(p)); }
3043
3070
  goto st99;
3044
3071
  st99:
3045
3072
  if ( ++p == pe )
3046
3073
  goto _test_eof99;
3047
3074
  case 99:
3048
- #line 3049 "unicorn_http.c"
3075
+ #line 3076 "unicorn_http.c"
3049
3076
  if ( (*p) == 58 )
3050
3077
  goto tr137;
3051
3078
  goto st0;
@@ -3065,7 +3092,7 @@ case 100:
3065
3092
  goto tr152;
3066
3093
  goto st0;
3067
3094
  tr151:
3068
- #line 338 "unicorn_http.rl"
3095
+ #line 365 "unicorn_http.rl"
3069
3096
  {
3070
3097
  hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
3071
3098
  if (hp->len.chunk < 0)
@@ -3076,7 +3103,7 @@ st101:
3076
3103
  if ( ++p == pe )
3077
3104
  goto _test_eof101;
3078
3105
  case 101:
3079
- #line 3080 "unicorn_http.c"
3106
+ #line 3107 "unicorn_http.c"
3080
3107
  switch( (*p) ) {
3081
3108
  case 10: goto tr153;
3082
3109
  case 13: goto st102;
@@ -3093,7 +3120,7 @@ case 101:
3093
3120
  goto tr152;
3094
3121
  goto st0;
3095
3122
  tr153:
3096
- #line 367 "unicorn_http.rl"
3123
+ #line 394 "unicorn_http.rl"
3097
3124
  {
3098
3125
  HP_FL_SET(hp, INTRAILER);
3099
3126
  cs = http_parser_en_Trailers;
@@ -3106,7 +3133,7 @@ st123:
3106
3133
  if ( ++p == pe )
3107
3134
  goto _test_eof123;
3108
3135
  case 123:
3109
- #line 3110 "unicorn_http.c"
3136
+ #line 3137 "unicorn_http.c"
3110
3137
  goto st0;
3111
3138
  st102:
3112
3139
  if ( ++p == pe )
@@ -3116,7 +3143,7 @@ case 102:
3116
3143
  goto tr153;
3117
3144
  goto st0;
3118
3145
  tr152:
3119
- #line 338 "unicorn_http.rl"
3146
+ #line 365 "unicorn_http.rl"
3120
3147
  {
3121
3148
  hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
3122
3149
  if (hp->len.chunk < 0)
@@ -3127,7 +3154,7 @@ st103:
3127
3154
  if ( ++p == pe )
3128
3155
  goto _test_eof103;
3129
3156
  case 103:
3130
- #line 3131 "unicorn_http.c"
3157
+ #line 3158 "unicorn_http.c"
3131
3158
  switch( (*p) ) {
3132
3159
  case 10: goto st104;
3133
3160
  case 13: goto st107;
@@ -3148,7 +3175,7 @@ st104:
3148
3175
  case 104:
3149
3176
  goto tr159;
3150
3177
  tr159:
3151
- #line 375 "unicorn_http.rl"
3178
+ #line 402 "unicorn_http.rl"
3152
3179
  {
3153
3180
  skip_chunk_data_hack: {
3154
3181
  size_t nr = MIN((size_t)hp->len.chunk, REMAINING);
@@ -3170,7 +3197,7 @@ st105:
3170
3197
  if ( ++p == pe )
3171
3198
  goto _test_eof105;
3172
3199
  case 105:
3173
- #line 3174 "unicorn_http.c"
3200
+ #line 3201 "unicorn_http.c"
3174
3201
  switch( (*p) ) {
3175
3202
  case 10: goto st100;
3176
3203
  case 13: goto st106;
@@ -3377,30 +3404,30 @@ case 113:
3377
3404
  goto st113;
3378
3405
  goto st0;
3379
3406
  tr172:
3380
- #line 295 "unicorn_http.rl"
3407
+ #line 322 "unicorn_http.rl"
3381
3408
  { MARK(mark, p); }
3382
- #line 297 "unicorn_http.rl"
3409
+ #line 324 "unicorn_http.rl"
3383
3410
  { write_cont_value(hp, buffer, p); }
3384
3411
  goto st114;
3385
3412
  tr175:
3386
- #line 297 "unicorn_http.rl"
3413
+ #line 324 "unicorn_http.rl"
3387
3414
  { write_cont_value(hp, buffer, p); }
3388
3415
  goto st114;
3389
3416
  tr182:
3390
- #line 295 "unicorn_http.rl"
3417
+ #line 322 "unicorn_http.rl"
3391
3418
  { MARK(mark, p); }
3392
- #line 296 "unicorn_http.rl"
3419
+ #line 323 "unicorn_http.rl"
3393
3420
  { write_value(hp, buffer, p); }
3394
3421
  goto st114;
3395
3422
  tr185:
3396
- #line 296 "unicorn_http.rl"
3423
+ #line 323 "unicorn_http.rl"
3397
3424
  { write_value(hp, buffer, p); }
3398
3425
  goto st114;
3399
3426
  st114:
3400
3427
  if ( ++p == pe )
3401
3428
  goto _test_eof114;
3402
3429
  case 114:
3403
- #line 3404 "unicorn_http.c"
3430
+ #line 3431 "unicorn_http.c"
3404
3431
  switch( (*p) ) {
3405
3432
  case 9: goto st115;
3406
3433
  case 10: goto tr167;
@@ -3429,14 +3456,14 @@ case 114:
3429
3456
  goto tr169;
3430
3457
  goto st0;
3431
3458
  tr171:
3432
- #line 295 "unicorn_http.rl"
3459
+ #line 322 "unicorn_http.rl"
3433
3460
  { MARK(mark, p); }
3434
3461
  goto st115;
3435
3462
  st115:
3436
3463
  if ( ++p == pe )
3437
3464
  goto _test_eof115;
3438
3465
  case 115:
3439
- #line 3440 "unicorn_http.c"
3466
+ #line 3467 "unicorn_http.c"
3440
3467
  switch( (*p) ) {
3441
3468
  case 9: goto tr171;
3442
3469
  case 10: goto tr172;
@@ -3448,14 +3475,14 @@ case 115:
3448
3475
  goto st0;
3449
3476
  goto tr170;
3450
3477
  tr170:
3451
- #line 295 "unicorn_http.rl"
3478
+ #line 322 "unicorn_http.rl"
3452
3479
  { MARK(mark, p); }
3453
3480
  goto st116;
3454
3481
  st116:
3455
3482
  if ( ++p == pe )
3456
3483
  goto _test_eof116;
3457
3484
  case 116:
3458
- #line 3459 "unicorn_http.c"
3485
+ #line 3486 "unicorn_http.c"
3459
3486
  switch( (*p) ) {
3460
3487
  case 10: goto tr175;
3461
3488
  case 13: goto tr176;
@@ -3468,35 +3495,35 @@ case 116:
3468
3495
  goto st0;
3469
3496
  goto st116;
3470
3497
  tr173:
3471
- #line 295 "unicorn_http.rl"
3498
+ #line 322 "unicorn_http.rl"
3472
3499
  { MARK(mark, p); }
3473
- #line 297 "unicorn_http.rl"
3500
+ #line 324 "unicorn_http.rl"
3474
3501
  { write_cont_value(hp, buffer, p); }
3475
3502
  goto st117;
3476
3503
  tr176:
3477
- #line 297 "unicorn_http.rl"
3504
+ #line 324 "unicorn_http.rl"
3478
3505
  { write_cont_value(hp, buffer, p); }
3479
3506
  goto st117;
3480
3507
  tr183:
3481
- #line 295 "unicorn_http.rl"
3508
+ #line 322 "unicorn_http.rl"
3482
3509
  { MARK(mark, p); }
3483
- #line 296 "unicorn_http.rl"
3510
+ #line 323 "unicorn_http.rl"
3484
3511
  { write_value(hp, buffer, p); }
3485
3512
  goto st117;
3486
3513
  tr186:
3487
- #line 296 "unicorn_http.rl"
3514
+ #line 323 "unicorn_http.rl"
3488
3515
  { write_value(hp, buffer, p); }
3489
3516
  goto st117;
3490
3517
  st117:
3491
3518
  if ( ++p == pe )
3492
3519
  goto _test_eof117;
3493
3520
  case 117:
3494
- #line 3495 "unicorn_http.c"
3521
+ #line 3522 "unicorn_http.c"
3495
3522
  if ( (*p) == 10 )
3496
3523
  goto st114;
3497
3524
  goto st0;
3498
3525
  tr167:
3499
- #line 362 "unicorn_http.rl"
3526
+ #line 389 "unicorn_http.rl"
3500
3527
  {
3501
3528
  cs = http_parser_first_final;
3502
3529
  goto post_exec;
@@ -3506,7 +3533,7 @@ st124:
3506
3533
  if ( ++p == pe )
3507
3534
  goto _test_eof124;
3508
3535
  case 124:
3509
- #line 3510 "unicorn_http.c"
3536
+ #line 3537 "unicorn_http.c"
3510
3537
  goto st0;
3511
3538
  st118:
3512
3539
  if ( ++p == pe )
@@ -3516,20 +3543,20 @@ case 118:
3516
3543
  goto tr167;
3517
3544
  goto st0;
3518
3545
  tr169:
3519
- #line 291 "unicorn_http.rl"
3546
+ #line 318 "unicorn_http.rl"
3520
3547
  { MARK(start.field, p); }
3521
- #line 292 "unicorn_http.rl"
3548
+ #line 319 "unicorn_http.rl"
3522
3549
  { snake_upcase_char(deconst(p)); }
3523
3550
  goto st119;
3524
3551
  tr178:
3525
- #line 292 "unicorn_http.rl"
3552
+ #line 319 "unicorn_http.rl"
3526
3553
  { snake_upcase_char(deconst(p)); }
3527
3554
  goto st119;
3528
3555
  st119:
3529
3556
  if ( ++p == pe )
3530
3557
  goto _test_eof119;
3531
3558
  case 119:
3532
- #line 3533 "unicorn_http.c"
3559
+ #line 3560 "unicorn_http.c"
3533
3560
  switch( (*p) ) {
3534
3561
  case 33: goto tr178;
3535
3562
  case 58: goto tr179;
@@ -3555,18 +3582,18 @@ case 119:
3555
3582
  goto tr178;
3556
3583
  goto st0;
3557
3584
  tr181:
3558
- #line 295 "unicorn_http.rl"
3585
+ #line 322 "unicorn_http.rl"
3559
3586
  { MARK(mark, p); }
3560
3587
  goto st120;
3561
3588
  tr179:
3562
- #line 294 "unicorn_http.rl"
3589
+ #line 321 "unicorn_http.rl"
3563
3590
  { hp->s.field_len = LEN(start.field, p); }
3564
3591
  goto st120;
3565
3592
  st120:
3566
3593
  if ( ++p == pe )
3567
3594
  goto _test_eof120;
3568
3595
  case 120:
3569
- #line 3570 "unicorn_http.c"
3596
+ #line 3597 "unicorn_http.c"
3570
3597
  switch( (*p) ) {
3571
3598
  case 9: goto tr181;
3572
3599
  case 10: goto tr182;
@@ -3578,14 +3605,14 @@ case 120:
3578
3605
  goto st0;
3579
3606
  goto tr180;
3580
3607
  tr180:
3581
- #line 295 "unicorn_http.rl"
3608
+ #line 322 "unicorn_http.rl"
3582
3609
  { MARK(mark, p); }
3583
3610
  goto st121;
3584
3611
  st121:
3585
3612
  if ( ++p == pe )
3586
3613
  goto _test_eof121;
3587
3614
  case 121:
3588
- #line 3589 "unicorn_http.c"
3615
+ #line 3616 "unicorn_http.c"
3589
3616
  switch( (*p) ) {
3590
3617
  case 10: goto tr185;
3591
3618
  case 13: goto tr186;
@@ -3726,7 +3753,7 @@ case 121:
3726
3753
  _out: {}
3727
3754
  }
3728
3755
 
3729
- #line 436 "unicorn_http.rl"
3756
+ #line 463 "unicorn_http.rl"
3730
3757
  post_exec: /* "_out:" also goes here */
3731
3758
  if (hp->cs != http_parser_error)
3732
3759
  hp->cs = cs;
@@ -3780,7 +3807,7 @@ static void set_url_scheme(VALUE env, VALUE *server_port)
3780
3807
  * and X-Forwarded-Proto handling from this parser? We've had it
3781
3808
  * forever and nobody has said anything against it, either.
3782
3809
  * Anyways, please send comments to our public mailing list:
3783
- * unicorn-public@bogomips.org (no HTML mail, no subscription necessary)
3810
+ * unicorn-public@yhbt.net (no HTML mail, no subscription necessary)
3784
3811
  */
3785
3812
  scheme = rb_hash_aref(env, g_http_x_forwarded_ssl);
3786
3813
  if (!NIL_P(scheme) && STR_CSTR_EQ(scheme, "on")) {
@@ -3901,8 +3928,12 @@ static VALUE HttpParser_clear(VALUE self)
3901
3928
  {
3902
3929
  struct http_parser *hp = data_get(self);
3903
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
+
3904
3935
  http_parser_init(hp);
3905
- my_hash_clear(hp->env);
3936
+ rb_hash_clear(hp->env);
3906
3937
 
3907
3938
  return self;
3908
3939
  }
@@ -4107,6 +4138,15 @@ static VALUE HttpParser_env(VALUE self)
4107
4138
  return data_get(self)->env;
4108
4139
  }
4109
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
+
4110
4150
  /**
4111
4151
  * call-seq:
4112
4152
  * parser.filter_body(dst, src) => nil/src
@@ -4211,11 +4251,8 @@ static VALUE HttpParser_rssget(VALUE self)
4211
4251
 
4212
4252
  void Init_unicorn_http(void)
4213
4253
  {
4214
- static VALUE mark_ary;
4215
- VALUE mUnicorn, cHttpParser;
4254
+ VALUE mUnicorn;
4216
4255
 
4217
- mark_ary = rb_ary_new();
4218
- rb_global_variable(&mark_ary);
4219
4256
  mUnicorn = rb_define_module("Unicorn");
4220
4257
  cHttpParser = rb_define_class_under(mUnicorn, "HttpParser", rb_cObject);
4221
4258
  eHttpParserError =
@@ -4225,7 +4262,8 @@ void Init_unicorn_http(void)
4225
4262
  e414 = rb_define_class_under(mUnicorn, "RequestURITooLongError",
4226
4263
  eHttpParserError);
4227
4264
 
4228
- init_globals(mark_ary);
4265
+ id_uminus = rb_intern("-@");
4266
+ init_globals();
4229
4267
  rb_define_alloc_func(cHttpParser, HttpParser_alloc);
4230
4268
  rb_define_method(cHttpParser, "initialize", HttpParser_init, 0);
4231
4269
  rb_define_method(cHttpParser, "clear", HttpParser_clear, 0);
@@ -4241,6 +4279,7 @@ void Init_unicorn_http(void)
4241
4279
  rb_define_method(cHttpParser, "next?", HttpParser_next, 0);
4242
4280
  rb_define_method(cHttpParser, "buf", HttpParser_buf, 0);
4243
4281
  rb_define_method(cHttpParser, "env", HttpParser_env, 0);
4282
+ rb_define_method(cHttpParser, "hijacked!", HttpParser_hijacked_bang, 0);
4244
4283
  rb_define_method(cHttpParser, "response_start_sent=", HttpParser_rssset, 1);
4245
4284
  rb_define_method(cHttpParser, "response_start_sent", HttpParser_rssget, 0);
4246
4285
 
@@ -4261,19 +4300,20 @@ void Init_unicorn_http(void)
4261
4300
 
4262
4301
  rb_define_singleton_method(cHttpParser, "max_header_len=", set_maxhdrlen, 1);
4263
4302
 
4264
- init_common_fields(mark_ary);
4303
+ init_common_fields();
4265
4304
  SET_GLOBAL(g_http_host, "HOST");
4266
4305
  SET_GLOBAL(g_http_trailer, "TRAILER");
4267
4306
  SET_GLOBAL(g_http_transfer_encoding, "TRANSFER_ENCODING");
4268
4307
  SET_GLOBAL(g_content_length, "CONTENT_LENGTH");
4269
4308
  SET_GLOBAL(g_http_connection, "CONNECTION");
4270
4309
  id_set_backtrace = rb_intern("set_backtrace");
4271
- init_unicorn_httpdate(mark_ary);
4272
-
4273
- OBJ_FREEZE(mark_ary);
4310
+ init_unicorn_httpdate();
4274
4311
 
4275
4312
  #ifndef HAVE_RB_HASH_CLEAR
4276
4313
  id_clear = rb_intern("clear");
4277
4314
  #endif
4315
+ id_is_chunked_p = rb_intern("is_chunked?");
4316
+
4317
+ init_epollexclusive(mUnicorn);
4278
4318
  }
4279
4319
  #undef SET_GLOBAL