unicorn 5.0.1 → 6.1.0

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