unicorn 5.3.1 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
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