unicorn 4.9.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +5 -5
  2. data/.gitattributes +5 -0
  3. data/.manifest +14 -15
  4. data/.olddoc.yml +16 -6
  5. data/Application_Timeouts +7 -7
  6. data/CONTRIBUTORS +6 -2
  7. data/DESIGN +2 -4
  8. data/Documentation/.gitignore +1 -3
  9. data/Documentation/unicorn.1 +222 -0
  10. data/Documentation/unicorn_rails.1 +207 -0
  11. data/FAQ +17 -8
  12. data/GIT-VERSION-FILE +1 -1
  13. data/GIT-VERSION-GEN +1 -1
  14. data/GNUmakefile +121 -56
  15. data/HACKING +2 -10
  16. data/ISSUES +40 -43
  17. data/KNOWN_ISSUES +11 -11
  18. data/LATEST +16 -22
  19. data/LICENSE +2 -2
  20. data/Links +24 -25
  21. data/NEWS +771 -0
  22. data/PHILOSOPHY +0 -6
  23. data/README +46 -40
  24. data/SIGNALS +2 -2
  25. data/Sandbox +11 -10
  26. data/TODO +0 -2
  27. data/TUNING +30 -9
  28. data/archive/slrnpull.conf +1 -1
  29. data/bin/unicorn +4 -2
  30. data/bin/unicorn_rails +3 -3
  31. data/examples/big_app_gc.rb +1 -1
  32. data/examples/init.sh +36 -8
  33. data/examples/logrotate.conf +17 -2
  34. data/examples/nginx.conf +14 -14
  35. data/examples/unicorn.conf.minimal.rb +2 -2
  36. data/examples/unicorn.conf.rb +3 -6
  37. data/examples/unicorn.socket +11 -0
  38. data/examples/unicorn@.service +40 -0
  39. data/ext/unicorn_http/c_util.h +5 -13
  40. data/ext/unicorn_http/common_field_optimization.h +22 -5
  41. data/ext/unicorn_http/epollexclusive.h +124 -0
  42. data/ext/unicorn_http/ext_help.h +0 -44
  43. data/ext/unicorn_http/extconf.rb +32 -5
  44. data/ext/unicorn_http/global_variables.h +2 -2
  45. data/ext/unicorn_http/httpdate.c +3 -2
  46. data/ext/unicorn_http/unicorn_http.c +926 -638
  47. data/ext/unicorn_http/unicorn_http.rl +159 -170
  48. data/ext/unicorn_http/unicorn_http_common.rl +1 -1
  49. data/lib/unicorn/configurator.rb +110 -44
  50. data/lib/unicorn/const.rb +2 -25
  51. data/lib/unicorn/http_request.rb +110 -31
  52. data/lib/unicorn/http_response.rb +17 -31
  53. data/lib/unicorn/http_server.rb +255 -179
  54. data/lib/unicorn/launcher.rb +1 -1
  55. data/lib/unicorn/oob_gc.rb +6 -6
  56. data/lib/unicorn/select_waiter.rb +6 -0
  57. data/lib/unicorn/socket_helper.rb +58 -78
  58. data/lib/unicorn/stream_input.rb +8 -7
  59. data/lib/unicorn/tee_input.rb +8 -10
  60. data/lib/unicorn/tmpio.rb +8 -7
  61. data/lib/unicorn/util.rb +5 -4
  62. data/lib/unicorn/version.rb +1 -1
  63. data/lib/unicorn/worker.rb +36 -23
  64. data/lib/unicorn.rb +64 -46
  65. data/man/man1/unicorn.1 +123 -119
  66. data/man/man1/unicorn_rails.1 +106 -107
  67. data/t/GNUmakefile +3 -72
  68. data/t/README +4 -4
  69. data/t/t0011-active-unix-socket.sh +1 -1
  70. data/t/t0012-reload-empty-config.sh +2 -1
  71. data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
  72. data/t/t0301.ru +13 -0
  73. data/t/test-lib.sh +4 -3
  74. data/test/benchmark/README +14 -4
  75. data/test/benchmark/ddstream.ru +50 -0
  76. data/test/benchmark/readinput.ru +40 -0
  77. data/test/benchmark/uconnect.perl +66 -0
  78. data/test/exec/test_exec.rb +73 -19
  79. data/test/test_helper.rb +40 -31
  80. data/test/unit/test_ccc.rb +91 -0
  81. data/test/unit/test_droplet.rb +1 -1
  82. data/test/unit/test_http_parser.rb +46 -16
  83. data/test/unit/test_http_parser_ng.rb +97 -114
  84. data/test/unit/test_request.rb +10 -10
  85. data/test/unit/test_response.rb +28 -16
  86. data/test/unit/test_server.rb +86 -12
  87. data/test/unit/test_signals.rb +8 -8
  88. data/test/unit/test_socket_helper.rb +14 -10
  89. data/test/unit/test_upload.rb +9 -14
  90. data/test/unit/test_util.rb +31 -5
  91. data/test/unit/test_waiter.rb +34 -0
  92. data/unicorn.gemspec +27 -19
  93. metadata +28 -45
  94. data/Documentation/GNUmakefile +0 -30
  95. data/Documentation/unicorn.1.txt +0 -185
  96. data/Documentation/unicorn_rails.1.txt +0 -175
  97. data/examples/git.ru +0 -13
  98. data/lib/unicorn/app/exec_cgi.rb +0 -154
  99. data/lib/unicorn/app/inetd.rb +0 -109
  100. data/lib/unicorn/ssl_client.rb +0 -11
  101. data/lib/unicorn/ssl_configurator.rb +0 -104
  102. data/lib/unicorn/ssl_server.rb +0 -42
  103. data/t/hijack.ru +0 -42
  104. data/t/t0016-trust-x-forwarded-false.sh +0 -30
  105. data/t/t0017-trust-x-forwarded-true.sh +0 -30
  106. data/t/t0200-rack-hijack.sh +0 -27
  107. data/test/unit/test_http_parser_xftrust.rb +0 -38
  108. data/test/unit/test_sni_hostnames.rb +0 -47
@@ -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
 
@@ -27,86 +28,33 @@ void init_unicorn_httpdate(void);
27
28
  #define UH_FL_KAVERSION 0x80
28
29
  #define UH_FL_HASHEADER 0x100
29
30
  #define UH_FL_TO_CLEAR 0x200
31
+ #define UH_FL_RESSTART 0x400 /* for check_client_connection */
32
+ #define UH_FL_HIJACK 0x800
30
33
 
31
34
  /* all of these flags need to be set for keepalive to be supported */
32
35
  #define UH_FL_KEEPALIVE (UH_FL_KAVERSION | UH_FL_REQEOF | UH_FL_HASHEADER)
33
36
 
34
- /*
35
- * whether or not to trust X-Forwarded-Proto and X-Forwarded-SSL when
36
- * setting rack.url_scheme
37
- */
38
- static VALUE trust_x_forward = Qtrue;
39
-
40
- static unsigned long keepalive_requests = 100; /* same as nginx */
41
-
42
- /*
43
- * Returns the maximum number of keepalive requests a client may make
44
- * before the parser refuses to continue.
45
- */
46
- static VALUE ka_req(VALUE self)
47
- {
48
- return ULONG2NUM(keepalive_requests);
49
- }
50
-
51
- /*
52
- * Sets the maximum number of keepalive requests a client may make.
53
- * A special value of +nil+ causes this to be the maximum value
54
- * possible (this is architecture-dependent).
55
- */
56
- static VALUE set_ka_req(VALUE self, VALUE val)
57
- {
58
- keepalive_requests = NIL_P(val) ? ULONG_MAX : NUM2ULONG(val);
59
-
60
- return ka_req(self);
61
- }
62
-
63
- /*
64
- * Sets whether or not the parser will trust X-Forwarded-Proto and
65
- * X-Forwarded-SSL headers and set "rack.url_scheme" to "https" accordingly.
66
- * Rainbows!/Zbatery installations facing untrusted clients directly
67
- * should set this to +false+
68
- */
69
- static VALUE set_xftrust(VALUE self, VALUE val)
70
- {
71
- if (Qtrue == val || Qfalse == val)
72
- trust_x_forward = val;
73
- else
74
- rb_raise(rb_eTypeError, "must be true or false");
75
-
76
- return val;
77
- }
78
-
79
- /*
80
- * returns whether or not the parser will trust X-Forwarded-Proto and
81
- * X-Forwarded-SSL headers and set "rack.url_scheme" to "https" accordingly
82
- */
83
- static VALUE xftrust(VALUE self)
84
- {
85
- return trust_x_forward;
86
- }
87
-
88
- static size_t MAX_HEADER_LEN = 1024 * (80 + 32); /* same as Mongrel */
37
+ static unsigned int MAX_HEADER_LEN = 1024 * (80 + 32); /* same as Mongrel */
89
38
 
90
39
  /* this is only intended for use with Rainbows! */
91
40
  static VALUE set_maxhdrlen(VALUE self, VALUE len)
92
41
  {
93
- return SIZET2NUM(MAX_HEADER_LEN = NUM2SIZET(len));
42
+ return UINT2NUM(MAX_HEADER_LEN = NUM2UINT(len));
94
43
  }
95
44
 
96
- /* keep this small for Rainbows! since every client has one */
45
+ /* keep this small for other servers (e.g. yahns) since every client has one */
97
46
  struct http_parser {
98
47
  int cs; /* Ragel internal state */
99
48
  unsigned int flags;
100
- unsigned long nr_requests;
101
- size_t mark;
102
- size_t offset;
49
+ unsigned int mark;
50
+ unsigned int offset;
103
51
  union { /* these 2 fields don't nest */
104
- size_t field;
105
- size_t query;
52
+ unsigned int field;
53
+ unsigned int query;
106
54
  } start;
107
55
  union {
108
- size_t field_len; /* only used during header processing */
109
- size_t dest_offset; /* only used during body processing */
56
+ unsigned int field_len; /* only used during header processing */
57
+ unsigned int dest_offset; /* only used during body processing */
110
58
  } s;
111
59
  VALUE buf;
112
60
  VALUE env;
@@ -117,7 +65,8 @@ struct http_parser {
117
65
  } len;
118
66
  };
119
67
 
120
- static ID id_clear, id_set_backtrace, id_response_start_sent;
68
+ static ID id_set_backtrace, id_is_chunked_p;
69
+ static VALUE cHttpParser;
121
70
 
122
71
  static void finalize_header(struct http_parser *hp);
123
72
 
@@ -126,13 +75,25 @@ static void parser_raise(VALUE klass, const char *msg)
126
75
  VALUE exc = rb_exc_new2(klass, msg);
127
76
  VALUE bt = rb_ary_new();
128
77
 
129
- rb_funcall(exc, id_set_backtrace, 1, bt);
130
- rb_exc_raise(exc);
78
+ rb_funcall(exc, id_set_backtrace, 1, bt);
79
+ rb_exc_raise(exc);
80
+ }
81
+
82
+ static inline unsigned int ulong2uint(unsigned long n)
83
+ {
84
+ unsigned int i = (unsigned int)n;
85
+
86
+ if (sizeof(unsigned int) != sizeof(unsigned long)) {
87
+ if ((unsigned long)i != n) {
88
+ rb_raise(rb_eRangeError, "too large to be 32-bit uint: %lu", n);
89
+ }
90
+ }
91
+ return i;
131
92
  }
132
93
 
133
94
  #define REMAINING (unsigned long)(pe - p)
134
- #define LEN(AT, FPC) (FPC - buffer - hp->AT)
135
- #define MARK(M,FPC) (hp->M = (FPC) - buffer)
95
+ #define LEN(AT, FPC) (ulong2uint(FPC - buffer) - hp->AT)
96
+ #define MARK(M,FPC) (hp->M = ulong2uint((FPC) - buffer))
136
97
  #define PTR_TO(F) (buffer + hp->F)
137
98
  #define STR_NEW(M,FPC) rb_str_new(PTR_TO(M), LEN(M, FPC))
138
99
  #define STRIPPED_STR_NEW(M,FPC) stripped_str_new(PTR_TO(M), LEN(M, FPC))
@@ -251,6 +212,19 @@ static void write_cont_value(struct http_parser *hp,
251
212
  rb_str_buf_cat(hp->cont, vptr, end + 1);
252
213
  }
253
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
+
254
228
  static void write_value(struct http_parser *hp,
255
229
  const char *buffer, const char *p)
256
230
  {
@@ -277,7 +251,9 @@ static void write_value(struct http_parser *hp,
277
251
  f = uncommon_field(field, flen);
278
252
  } else if (f == g_http_connection) {
279
253
  hp_keepalive_connection(hp, v);
280
- } 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");
281
257
  hp->len.content = parse_length(RSTRING_PTR(v), RSTRING_LEN(v));
282
258
  if (hp->len.content < 0)
283
259
  parser_raise(eHttpParserError, "invalid Content-Length");
@@ -285,9 +261,30 @@ static void write_value(struct http_parser *hp,
285
261
  HP_FL_SET(hp, HASBODY);
286
262
  hp_invalid_if_trailer(hp);
287
263
  } else if (f == g_http_transfer_encoding) {
288
- 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
+
289
273
  HP_FL_SET(hp, CHUNKED);
290
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");
291
288
  }
292
289
  hp_invalid_if_trailer(hp);
293
290
  } else if (f == g_http_trailer) {
@@ -316,23 +313,23 @@ static void write_value(struct http_parser *hp,
316
313
  /** Machine **/
317
314
 
318
315
 
319
- #line 423 "unicorn_http.rl"
316
+ #line 420 "unicorn_http.rl"
320
317
 
321
318
 
322
319
  /** Data **/
323
320
 
324
- #line 325 "unicorn_http.c"
321
+ #line 322 "unicorn_http.c"
325
322
  static const int http_parser_start = 1;
326
323
  static const int http_parser_first_final = 122;
327
324
  static const int http_parser_error = 0;
328
325
 
329
326
  static const int http_parser_en_ChunkedBody = 100;
330
- static const int http_parser_en_ChunkedBody_chunk_chunk_end = 106;
327
+ static const int http_parser_en_ChunkedBody_chunk_chunk_end = 105;
331
328
  static const int http_parser_en_Trailers = 114;
332
329
  static const int http_parser_en_main = 1;
333
330
 
334
331
 
335
- #line 427 "unicorn_http.rl"
332
+ #line 424 "unicorn_http.rl"
336
333
 
337
334
  static void http_parser_init(struct http_parser *hp)
338
335
  {
@@ -345,12 +342,12 @@ static void http_parser_init(struct http_parser *hp)
345
342
  hp->len.content = 0;
346
343
  hp->cont = Qfalse; /* zero on MRI, should be optimized away by above */
347
344
 
348
- #line 349 "unicorn_http.c"
345
+ #line 346 "unicorn_http.c"
349
346
  {
350
347
  cs = http_parser_start;
351
348
  }
352
349
 
353
- #line 439 "unicorn_http.rl"
350
+ #line 436 "unicorn_http.rl"
354
351
  hp->cs = cs;
355
352
  }
356
353
 
@@ -378,7 +375,7 @@ http_parser_execute(struct http_parser *hp, char *buffer, size_t len)
378
375
  goto skip_chunk_data_hack;
379
376
  }
380
377
 
381
- #line 382 "unicorn_http.c"
378
+ #line 379 "unicorn_http.c"
382
379
  {
383
380
  if ( p == pe )
384
381
  goto _test_eof;
@@ -413,14 +410,14 @@ st0:
413
410
  cs = 0;
414
411
  goto _out;
415
412
  tr0:
416
- #line 319 "unicorn_http.rl"
413
+ #line 316 "unicorn_http.rl"
417
414
  {MARK(mark, p); }
418
415
  goto st2;
419
416
  st2:
420
417
  if ( ++p == pe )
421
418
  goto _test_eof2;
422
419
  case 2:
423
- #line 424 "unicorn_http.c"
420
+ #line 421 "unicorn_http.c"
424
421
  switch( (*p) ) {
425
422
  case 32: goto tr3;
426
423
  case 33: goto st49;
@@ -446,14 +443,14 @@ case 2:
446
443
  goto st49;
447
444
  goto st0;
448
445
  tr3:
449
- #line 328 "unicorn_http.rl"
446
+ #line 325 "unicorn_http.rl"
450
447
  { request_method(hp, PTR_TO(mark), LEN(mark, p)); }
451
448
  goto st3;
452
449
  st3:
453
450
  if ( ++p == pe )
454
451
  goto _test_eof3;
455
452
  case 3:
456
- #line 457 "unicorn_http.c"
453
+ #line 454 "unicorn_http.c"
457
454
  switch( (*p) ) {
458
455
  case 42: goto tr5;
459
456
  case 47: goto tr6;
@@ -462,21 +459,21 @@ case 3:
462
459
  }
463
460
  goto st0;
464
461
  tr5:
465
- #line 319 "unicorn_http.rl"
462
+ #line 316 "unicorn_http.rl"
466
463
  {MARK(mark, p); }
467
464
  goto st4;
468
465
  st4:
469
466
  if ( ++p == pe )
470
467
  goto _test_eof4;
471
468
  case 4:
472
- #line 473 "unicorn_http.c"
469
+ #line 470 "unicorn_http.c"
473
470
  switch( (*p) ) {
474
471
  case 32: goto tr8;
475
472
  case 35: goto tr9;
476
473
  }
477
474
  goto st0;
478
475
  tr8:
479
- #line 333 "unicorn_http.rl"
476
+ #line 330 "unicorn_http.rl"
480
477
  {
481
478
  VALUE str;
482
479
 
@@ -493,24 +490,24 @@ tr8:
493
490
  }
494
491
  }
495
492
  goto st5;
496
- tr37:
497
- #line 319 "unicorn_http.rl"
493
+ tr42:
494
+ #line 316 "unicorn_http.rl"
498
495
  {MARK(mark, p); }
499
- #line 348 "unicorn_http.rl"
496
+ #line 345 "unicorn_http.rl"
500
497
  {
501
498
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
502
499
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
503
500
  }
504
501
  goto st5;
505
- tr40:
506
- #line 348 "unicorn_http.rl"
502
+ tr45:
503
+ #line 345 "unicorn_http.rl"
507
504
  {
508
505
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
509
506
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
510
507
  }
511
508
  goto st5;
512
- tr44:
513
- #line 358 "unicorn_http.rl"
509
+ tr49:
510
+ #line 355 "unicorn_http.rl"
514
511
  {
515
512
  VALUE val;
516
513
 
@@ -521,7 +518,7 @@ tr44:
521
518
  if (!STR_CSTR_EQ(val, "*"))
522
519
  rb_hash_aset(hp->env, g_path_info, val);
523
520
  }
524
- #line 333 "unicorn_http.rl"
521
+ #line 330 "unicorn_http.rl"
525
522
  {
526
523
  VALUE str;
527
524
 
@@ -538,15 +535,15 @@ tr44:
538
535
  }
539
536
  }
540
537
  goto st5;
541
- tr50:
542
- #line 352 "unicorn_http.rl"
538
+ tr55:
539
+ #line 349 "unicorn_http.rl"
543
540
  {MARK(start.query, p); }
544
- #line 353 "unicorn_http.rl"
541
+ #line 350 "unicorn_http.rl"
545
542
  {
546
543
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
547
544
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
548
545
  }
549
- #line 333 "unicorn_http.rl"
546
+ #line 330 "unicorn_http.rl"
550
547
  {
551
548
  VALUE str;
552
549
 
@@ -563,13 +560,13 @@ tr50:
563
560
  }
564
561
  }
565
562
  goto st5;
566
- tr54:
567
- #line 353 "unicorn_http.rl"
563
+ tr59:
564
+ #line 350 "unicorn_http.rl"
568
565
  {
569
566
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
570
567
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
571
568
  }
572
- #line 333 "unicorn_http.rl"
569
+ #line 330 "unicorn_http.rl"
573
570
  {
574
571
  VALUE str;
575
572
 
@@ -590,19 +587,19 @@ st5:
590
587
  if ( ++p == pe )
591
588
  goto _test_eof5;
592
589
  case 5:
593
- #line 594 "unicorn_http.c"
590
+ #line 591 "unicorn_http.c"
594
591
  if ( (*p) == 72 )
595
592
  goto tr10;
596
593
  goto st0;
597
594
  tr10:
598
- #line 319 "unicorn_http.rl"
595
+ #line 316 "unicorn_http.rl"
599
596
  {MARK(mark, p); }
600
597
  goto st6;
601
598
  st6:
602
599
  if ( ++p == pe )
603
600
  goto _test_eof6;
604
601
  case 6:
605
- #line 606 "unicorn_http.c"
602
+ #line 603 "unicorn_http.c"
606
603
  if ( (*p) == 84 )
607
604
  goto st7;
608
605
  goto st0;
@@ -654,112 +651,163 @@ st13:
654
651
  if ( ++p == pe )
655
652
  goto _test_eof13;
656
653
  case 13:
657
- if ( (*p) == 13 )
658
- goto tr18;
654
+ switch( (*p) ) {
655
+ case 10: goto tr18;
656
+ case 13: goto tr19;
657
+ }
659
658
  if ( 48 <= (*p) && (*p) <= 57 )
660
659
  goto st13;
661
660
  goto st0;
662
661
  tr18:
663
- #line 357 "unicorn_http.rl"
662
+ #line 354 "unicorn_http.rl"
664
663
  { http_version(hp, PTR_TO(mark), LEN(mark, p)); }
665
664
  goto st14;
666
- tr25:
667
- #line 325 "unicorn_http.rl"
665
+ tr26:
666
+ #line 322 "unicorn_http.rl"
668
667
  { MARK(mark, p); }
669
- #line 327 "unicorn_http.rl"
668
+ #line 324 "unicorn_http.rl"
670
669
  { write_cont_value(hp, buffer, p); }
671
670
  goto st14;
672
- tr27:
673
- #line 327 "unicorn_http.rl"
671
+ tr29:
672
+ #line 324 "unicorn_http.rl"
674
673
  { write_cont_value(hp, buffer, p); }
675
674
  goto st14;
676
- tr33:
677
- #line 325 "unicorn_http.rl"
675
+ tr36:
676
+ #line 322 "unicorn_http.rl"
678
677
  { MARK(mark, p); }
679
- #line 326 "unicorn_http.rl"
678
+ #line 323 "unicorn_http.rl"
680
679
  { write_value(hp, buffer, p); }
681
680
  goto st14;
682
- tr35:
683
- #line 326 "unicorn_http.rl"
681
+ tr39:
682
+ #line 323 "unicorn_http.rl"
684
683
  { write_value(hp, buffer, p); }
685
684
  goto st14;
686
685
  st14:
687
686
  if ( ++p == pe )
688
687
  goto _test_eof14;
689
688
  case 14:
690
- #line 691 "unicorn_http.c"
691
- if ( (*p) == 10 )
692
- goto st15;
693
- goto st0;
694
- st15:
695
- if ( ++p == pe )
696
- goto _test_eof15;
697
- case 15:
689
+ #line 690 "unicorn_http.c"
698
690
  switch( (*p) ) {
699
- case 9: goto st16;
691
+ case 9: goto st15;
692
+ case 10: goto tr21;
700
693
  case 13: goto st18;
701
- case 32: goto st16;
702
- case 33: goto tr22;
703
- case 124: goto tr22;
704
- case 126: goto tr22;
694
+ case 32: goto st15;
695
+ case 33: goto tr23;
696
+ case 124: goto tr23;
697
+ case 126: goto tr23;
705
698
  }
706
699
  if ( (*p) < 45 ) {
707
700
  if ( (*p) > 39 ) {
708
701
  if ( 42 <= (*p) && (*p) <= 43 )
709
- goto tr22;
702
+ goto tr23;
710
703
  } else if ( (*p) >= 35 )
711
- goto tr22;
704
+ goto tr23;
712
705
  } else if ( (*p) > 46 ) {
713
706
  if ( (*p) < 65 ) {
714
707
  if ( 48 <= (*p) && (*p) <= 57 )
715
- goto tr22;
708
+ goto tr23;
716
709
  } else if ( (*p) > 90 ) {
717
710
  if ( 94 <= (*p) && (*p) <= 122 )
718
- goto tr22;
711
+ goto tr23;
719
712
  } else
720
- goto tr22;
713
+ goto tr23;
721
714
  } else
722
- goto tr22;
715
+ goto tr23;
723
716
  goto st0;
724
- tr24:
725
- #line 325 "unicorn_http.rl"
717
+ tr25:
718
+ #line 322 "unicorn_http.rl"
726
719
  { MARK(mark, p); }
727
- goto st16;
728
- st16:
720
+ goto st15;
721
+ st15:
729
722
  if ( ++p == pe )
730
- goto _test_eof16;
731
- case 16:
732
- #line 733 "unicorn_http.c"
723
+ goto _test_eof15;
724
+ case 15:
725
+ #line 726 "unicorn_http.c"
733
726
  switch( (*p) ) {
734
- case 9: goto tr24;
735
- case 13: goto tr25;
736
- case 32: goto tr24;
727
+ case 9: goto tr25;
728
+ case 10: goto tr26;
729
+ case 13: goto tr27;
730
+ case 32: goto tr25;
737
731
  case 127: goto st0;
738
732
  }
739
733
  if ( 0 <= (*p) && (*p) <= 31 )
740
734
  goto st0;
741
- goto tr23;
742
- tr23:
743
- #line 325 "unicorn_http.rl"
735
+ goto tr24;
736
+ tr24:
737
+ #line 322 "unicorn_http.rl"
744
738
  { MARK(mark, p); }
745
- goto st17;
746
- st17:
739
+ goto st16;
740
+ st16:
747
741
  if ( ++p == pe )
748
- goto _test_eof17;
749
- case 17:
750
- #line 751 "unicorn_http.c"
742
+ goto _test_eof16;
743
+ case 16:
744
+ #line 745 "unicorn_http.c"
751
745
  switch( (*p) ) {
752
- case 13: goto tr27;
746
+ case 10: goto tr29;
747
+ case 13: goto tr30;
753
748
  case 127: goto st0;
754
749
  }
755
750
  if ( (*p) > 8 ) {
756
- if ( 10 <= (*p) && (*p) <= 31 )
751
+ if ( 11 <= (*p) && (*p) <= 31 )
757
752
  goto st0;
758
753
  } else if ( (*p) >= 0 )
759
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); }
760
779
  goto st17;
761
- tr99:
762
- #line 333 "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"
763
811
  {
764
812
  VALUE str;
765
813
 
@@ -775,25 +823,82 @@ tr99:
775
823
  rb_hash_aset(hp->env, g_request_path, str);
776
824
  }
777
825
  }
778
- goto st18;
779
- tr102:
780
- #line 319 "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"
781
848
  {MARK(mark, p); }
782
- #line 348 "unicorn_http.rl"
849
+ #line 345 "unicorn_http.rl"
783
850
  {
784
851
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
785
852
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
786
853
  }
787
- goto st18;
788
- tr105:
789
- #line 348 "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"
790
876
  {
791
877
  VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
792
878
  rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
793
879
  }
794
- goto st18;
795
- tr109:
796
- #line 358 "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"
797
902
  {
798
903
  VALUE val;
799
904
 
@@ -804,7 +909,7 @@ tr109:
804
909
  if (!STR_CSTR_EQ(val, "*"))
805
910
  rb_hash_aset(hp->env, g_path_info, val);
806
911
  }
807
- #line 333 "unicorn_http.rl"
912
+ #line 330 "unicorn_http.rl"
808
913
  {
809
914
  VALUE str;
810
915
 
@@ -820,16 +925,35 @@ tr109:
820
925
  rb_hash_aset(hp->env, g_request_path, str);
821
926
  }
822
927
  }
823
- goto st18;
824
- tr115:
825
- #line 352 "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"
826
950
  {MARK(start.query, p); }
827
- #line 353 "unicorn_http.rl"
951
+ #line 350 "unicorn_http.rl"
828
952
  {
829
953
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
830
954
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
831
955
  }
832
- #line 333 "unicorn_http.rl"
956
+ #line 330 "unicorn_http.rl"
833
957
  {
834
958
  VALUE str;
835
959
 
@@ -845,14 +969,33 @@ tr115:
845
969
  rb_hash_aset(hp->env, g_request_path, str);
846
970
  }
847
971
  }
848
- goto st18;
849
- tr119:
850
- #line 353 "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"
851
994
  {
852
995
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
853
996
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
854
997
  }
855
- #line 333 "unicorn_http.rl"
998
+ #line 330 "unicorn_http.rl"
856
999
  {
857
1000
  VALUE str;
858
1001
 
@@ -868,17 +1011,7 @@ tr119:
868
1011
  rb_hash_aset(hp->env, g_request_path, str);
869
1012
  }
870
1013
  }
871
- goto st18;
872
- st18:
873
- if ( ++p == pe )
874
- goto _test_eof18;
875
- case 18:
876
- #line 877 "unicorn_http.c"
877
- if ( (*p) == 10 )
878
- goto tr28;
879
- goto st0;
880
- tr28:
881
- #line 373 "unicorn_http.rl"
1014
+ #line 370 "unicorn_http.rl"
882
1015
  {
883
1016
  finalize_header(hp);
884
1017
 
@@ -902,90 +1035,211 @@ st122:
902
1035
  if ( ++p == pe )
903
1036
  goto _test_eof122;
904
1037
  case 122:
905
- #line 906 "unicorn_http.c"
1038
+ #line 1039 "unicorn_http.c"
906
1039
  goto st0;
907
- tr22:
908
- #line 321 "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"
909
1161
  { MARK(start.field, p); }
910
- #line 322 "unicorn_http.rl"
1162
+ #line 319 "unicorn_http.rl"
911
1163
  { snake_upcase_char(deconst(p)); }
912
1164
  goto st19;
913
- tr29:
914
- #line 322 "unicorn_http.rl"
1165
+ tr32:
1166
+ #line 319 "unicorn_http.rl"
915
1167
  { snake_upcase_char(deconst(p)); }
916
1168
  goto st19;
917
1169
  st19:
918
1170
  if ( ++p == pe )
919
1171
  goto _test_eof19;
920
1172
  case 19:
921
- #line 922 "unicorn_http.c"
1173
+ #line 1174 "unicorn_http.c"
922
1174
  switch( (*p) ) {
923
- case 33: goto tr29;
924
- case 58: goto tr30;
925
- case 124: goto tr29;
926
- case 126: goto tr29;
1175
+ case 33: goto tr32;
1176
+ case 58: goto tr33;
1177
+ case 124: goto tr32;
1178
+ case 126: goto tr32;
927
1179
  }
928
1180
  if ( (*p) < 45 ) {
929
1181
  if ( (*p) > 39 ) {
930
1182
  if ( 42 <= (*p) && (*p) <= 43 )
931
- goto tr29;
1183
+ goto tr32;
932
1184
  } else if ( (*p) >= 35 )
933
- goto tr29;
1185
+ goto tr32;
934
1186
  } else if ( (*p) > 46 ) {
935
1187
  if ( (*p) < 65 ) {
936
1188
  if ( 48 <= (*p) && (*p) <= 57 )
937
- goto tr29;
1189
+ goto tr32;
938
1190
  } else if ( (*p) > 90 ) {
939
1191
  if ( 94 <= (*p) && (*p) <= 122 )
940
- goto tr29;
1192
+ goto tr32;
941
1193
  } else
942
- goto tr29;
1194
+ goto tr32;
943
1195
  } else
944
- goto tr29;
1196
+ goto tr32;
945
1197
  goto st0;
946
- tr32:
947
- #line 325 "unicorn_http.rl"
1198
+ tr35:
1199
+ #line 322 "unicorn_http.rl"
948
1200
  { MARK(mark, p); }
949
1201
  goto st20;
950
- tr30:
951
- #line 324 "unicorn_http.rl"
1202
+ tr33:
1203
+ #line 321 "unicorn_http.rl"
952
1204
  { hp->s.field_len = LEN(start.field, p); }
953
1205
  goto st20;
954
1206
  st20:
955
1207
  if ( ++p == pe )
956
1208
  goto _test_eof20;
957
1209
  case 20:
958
- #line 959 "unicorn_http.c"
1210
+ #line 1211 "unicorn_http.c"
959
1211
  switch( (*p) ) {
960
- case 9: goto tr32;
961
- case 13: goto tr33;
962
- case 32: goto tr32;
1212
+ case 9: goto tr35;
1213
+ case 10: goto tr36;
1214
+ case 13: goto tr37;
1215
+ case 32: goto tr35;
963
1216
  case 127: goto st0;
964
1217
  }
965
1218
  if ( 0 <= (*p) && (*p) <= 31 )
966
1219
  goto st0;
967
- goto tr31;
968
- tr31:
969
- #line 325 "unicorn_http.rl"
1220
+ goto tr34;
1221
+ tr34:
1222
+ #line 322 "unicorn_http.rl"
970
1223
  { MARK(mark, p); }
971
1224
  goto st21;
972
1225
  st21:
973
1226
  if ( ++p == pe )
974
1227
  goto _test_eof21;
975
1228
  case 21:
976
- #line 977 "unicorn_http.c"
1229
+ #line 1230 "unicorn_http.c"
977
1230
  switch( (*p) ) {
978
- case 13: goto tr35;
1231
+ case 10: goto tr39;
1232
+ case 13: goto tr40;
979
1233
  case 127: goto st0;
980
1234
  }
981
1235
  if ( (*p) > 8 ) {
982
- if ( 10 <= (*p) && (*p) <= 31 )
1236
+ if ( 11 <= (*p) && (*p) <= 31 )
983
1237
  goto st0;
984
1238
  } else if ( (*p) >= 0 )
985
1239
  goto st0;
986
1240
  goto st21;
987
1241
  tr9:
988
- #line 333 "unicorn_http.rl"
1242
+ #line 330 "unicorn_http.rl"
989
1243
  {
990
1244
  VALUE str;
991
1245
 
@@ -1002,8 +1256,8 @@ tr9:
1002
1256
  }
1003
1257
  }
1004
1258
  goto st22;
1005
- tr45:
1006
- #line 358 "unicorn_http.rl"
1259
+ tr50:
1260
+ #line 355 "unicorn_http.rl"
1007
1261
  {
1008
1262
  VALUE val;
1009
1263
 
@@ -1014,7 +1268,7 @@ tr45:
1014
1268
  if (!STR_CSTR_EQ(val, "*"))
1015
1269
  rb_hash_aset(hp->env, g_path_info, val);
1016
1270
  }
1017
- #line 333 "unicorn_http.rl"
1271
+ #line 330 "unicorn_http.rl"
1018
1272
  {
1019
1273
  VALUE str;
1020
1274
 
@@ -1031,15 +1285,15 @@ tr45:
1031
1285
  }
1032
1286
  }
1033
1287
  goto st22;
1034
- tr51:
1035
- #line 352 "unicorn_http.rl"
1288
+ tr56:
1289
+ #line 349 "unicorn_http.rl"
1036
1290
  {MARK(start.query, p); }
1037
- #line 353 "unicorn_http.rl"
1291
+ #line 350 "unicorn_http.rl"
1038
1292
  {
1039
1293
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1040
1294
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1041
1295
  }
1042
- #line 333 "unicorn_http.rl"
1296
+ #line 330 "unicorn_http.rl"
1043
1297
  {
1044
1298
  VALUE str;
1045
1299
 
@@ -1056,13 +1310,13 @@ tr51:
1056
1310
  }
1057
1311
  }
1058
1312
  goto st22;
1059
- tr55:
1060
- #line 353 "unicorn_http.rl"
1313
+ tr60:
1314
+ #line 350 "unicorn_http.rl"
1061
1315
  {
1062
1316
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1063
1317
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1064
1318
  }
1065
- #line 333 "unicorn_http.rl"
1319
+ #line 330 "unicorn_http.rl"
1066
1320
  {
1067
1321
  VALUE str;
1068
1322
 
@@ -1083,27 +1337,27 @@ st22:
1083
1337
  if ( ++p == pe )
1084
1338
  goto _test_eof22;
1085
1339
  case 22:
1086
- #line 1087 "unicorn_http.c"
1340
+ #line 1341 "unicorn_http.c"
1087
1341
  switch( (*p) ) {
1088
- case 32: goto tr37;
1342
+ case 32: goto tr42;
1089
1343
  case 35: goto st0;
1090
- case 37: goto tr38;
1344
+ case 37: goto tr43;
1091
1345
  case 127: goto st0;
1092
1346
  }
1093
1347
  if ( 0 <= (*p) && (*p) <= 31 )
1094
1348
  goto st0;
1095
- goto tr36;
1096
- tr36:
1097
- #line 319 "unicorn_http.rl"
1349
+ goto tr41;
1350
+ tr41:
1351
+ #line 316 "unicorn_http.rl"
1098
1352
  {MARK(mark, p); }
1099
1353
  goto st23;
1100
1354
  st23:
1101
1355
  if ( ++p == pe )
1102
1356
  goto _test_eof23;
1103
1357
  case 23:
1104
- #line 1105 "unicorn_http.c"
1358
+ #line 1359 "unicorn_http.c"
1105
1359
  switch( (*p) ) {
1106
- case 32: goto tr40;
1360
+ case 32: goto tr45;
1107
1361
  case 35: goto st0;
1108
1362
  case 37: goto st24;
1109
1363
  case 127: goto st0;
@@ -1111,15 +1365,15 @@ case 23:
1111
1365
  if ( 0 <= (*p) && (*p) <= 31 )
1112
1366
  goto st0;
1113
1367
  goto st23;
1114
- tr38:
1115
- #line 319 "unicorn_http.rl"
1368
+ tr43:
1369
+ #line 316 "unicorn_http.rl"
1116
1370
  {MARK(mark, p); }
1117
1371
  goto st24;
1118
1372
  st24:
1119
1373
  if ( ++p == pe )
1120
1374
  goto _test_eof24;
1121
1375
  case 24:
1122
- #line 1123 "unicorn_http.c"
1376
+ #line 1377 "unicorn_http.c"
1123
1377
  if ( (*p) < 65 ) {
1124
1378
  if ( 48 <= (*p) && (*p) <= 57 )
1125
1379
  goto st25;
@@ -1143,25 +1397,25 @@ case 25:
1143
1397
  goto st23;
1144
1398
  goto st0;
1145
1399
  tr6:
1146
- #line 319 "unicorn_http.rl"
1400
+ #line 316 "unicorn_http.rl"
1147
1401
  {MARK(mark, p); }
1148
1402
  goto st26;
1149
- tr71:
1150
- #line 332 "unicorn_http.rl"
1403
+ tr76:
1404
+ #line 329 "unicorn_http.rl"
1151
1405
  { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
1152
- #line 319 "unicorn_http.rl"
1406
+ #line 316 "unicorn_http.rl"
1153
1407
  {MARK(mark, p); }
1154
1408
  goto st26;
1155
1409
  st26:
1156
1410
  if ( ++p == pe )
1157
1411
  goto _test_eof26;
1158
1412
  case 26:
1159
- #line 1160 "unicorn_http.c"
1413
+ #line 1414 "unicorn_http.c"
1160
1414
  switch( (*p) ) {
1161
- case 32: goto tr44;
1162
- case 35: goto tr45;
1415
+ case 32: goto tr49;
1416
+ case 35: goto tr50;
1163
1417
  case 37: goto st27;
1164
- case 63: goto tr47;
1418
+ case 63: goto tr52;
1165
1419
  case 127: goto st0;
1166
1420
  }
1167
1421
  if ( 0 <= (*p) && (*p) <= 31 )
@@ -1193,8 +1447,8 @@ case 28:
1193
1447
  } else
1194
1448
  goto st26;
1195
1449
  goto st0;
1196
- tr47:
1197
- #line 358 "unicorn_http.rl"
1450
+ tr52:
1451
+ #line 355 "unicorn_http.rl"
1198
1452
  {
1199
1453
  VALUE val;
1200
1454
 
@@ -1210,43 +1464,43 @@ st29:
1210
1464
  if ( ++p == pe )
1211
1465
  goto _test_eof29;
1212
1466
  case 29:
1213
- #line 1214 "unicorn_http.c"
1467
+ #line 1468 "unicorn_http.c"
1214
1468
  switch( (*p) ) {
1215
- case 32: goto tr50;
1216
- case 35: goto tr51;
1217
- case 37: goto tr52;
1469
+ case 32: goto tr55;
1470
+ case 35: goto tr56;
1471
+ case 37: goto tr57;
1218
1472
  case 127: goto st0;
1219
1473
  }
1220
1474
  if ( 0 <= (*p) && (*p) <= 31 )
1221
1475
  goto st0;
1222
- goto tr49;
1223
- tr49:
1224
- #line 352 "unicorn_http.rl"
1476
+ goto tr54;
1477
+ tr54:
1478
+ #line 349 "unicorn_http.rl"
1225
1479
  {MARK(start.query, p); }
1226
1480
  goto st30;
1227
1481
  st30:
1228
1482
  if ( ++p == pe )
1229
1483
  goto _test_eof30;
1230
1484
  case 30:
1231
- #line 1232 "unicorn_http.c"
1485
+ #line 1486 "unicorn_http.c"
1232
1486
  switch( (*p) ) {
1233
- case 32: goto tr54;
1234
- case 35: goto tr55;
1487
+ case 32: goto tr59;
1488
+ case 35: goto tr60;
1235
1489
  case 37: goto st31;
1236
1490
  case 127: goto st0;
1237
1491
  }
1238
1492
  if ( 0 <= (*p) && (*p) <= 31 )
1239
1493
  goto st0;
1240
1494
  goto st30;
1241
- tr52:
1242
- #line 352 "unicorn_http.rl"
1495
+ tr57:
1496
+ #line 349 "unicorn_http.rl"
1243
1497
  {MARK(start.query, p); }
1244
1498
  goto st31;
1245
1499
  st31:
1246
1500
  if ( ++p == pe )
1247
1501
  goto _test_eof31;
1248
1502
  case 31:
1249
- #line 1250 "unicorn_http.c"
1503
+ #line 1504 "unicorn_http.c"
1250
1504
  if ( (*p) < 65 ) {
1251
1505
  if ( 48 <= (*p) && (*p) <= 57 )
1252
1506
  goto st32;
@@ -1270,66 +1524,66 @@ case 32:
1270
1524
  goto st30;
1271
1525
  goto st0;
1272
1526
  tr7:
1273
- #line 319 "unicorn_http.rl"
1527
+ #line 316 "unicorn_http.rl"
1274
1528
  {MARK(mark, p); }
1275
- #line 323 "unicorn_http.rl"
1529
+ #line 320 "unicorn_http.rl"
1276
1530
  { downcase_char(deconst(p)); }
1277
1531
  goto st33;
1278
1532
  st33:
1279
1533
  if ( ++p == pe )
1280
1534
  goto _test_eof33;
1281
1535
  case 33:
1282
- #line 1283 "unicorn_http.c"
1536
+ #line 1537 "unicorn_http.c"
1283
1537
  switch( (*p) ) {
1284
- case 84: goto tr58;
1285
- case 116: goto tr58;
1538
+ case 84: goto tr63;
1539
+ case 116: goto tr63;
1286
1540
  }
1287
1541
  goto st0;
1288
- tr58:
1289
- #line 323 "unicorn_http.rl"
1542
+ tr63:
1543
+ #line 320 "unicorn_http.rl"
1290
1544
  { downcase_char(deconst(p)); }
1291
1545
  goto st34;
1292
1546
  st34:
1293
1547
  if ( ++p == pe )
1294
1548
  goto _test_eof34;
1295
1549
  case 34:
1296
- #line 1297 "unicorn_http.c"
1550
+ #line 1551 "unicorn_http.c"
1297
1551
  switch( (*p) ) {
1298
- case 84: goto tr59;
1299
- case 116: goto tr59;
1552
+ case 84: goto tr64;
1553
+ case 116: goto tr64;
1300
1554
  }
1301
1555
  goto st0;
1302
- tr59:
1303
- #line 323 "unicorn_http.rl"
1556
+ tr64:
1557
+ #line 320 "unicorn_http.rl"
1304
1558
  { downcase_char(deconst(p)); }
1305
1559
  goto st35;
1306
1560
  st35:
1307
1561
  if ( ++p == pe )
1308
1562
  goto _test_eof35;
1309
1563
  case 35:
1310
- #line 1311 "unicorn_http.c"
1564
+ #line 1565 "unicorn_http.c"
1311
1565
  switch( (*p) ) {
1312
- case 80: goto tr60;
1313
- case 112: goto tr60;
1566
+ case 80: goto tr65;
1567
+ case 112: goto tr65;
1314
1568
  }
1315
1569
  goto st0;
1316
- tr60:
1317
- #line 323 "unicorn_http.rl"
1570
+ tr65:
1571
+ #line 320 "unicorn_http.rl"
1318
1572
  { downcase_char(deconst(p)); }
1319
1573
  goto st36;
1320
1574
  st36:
1321
1575
  if ( ++p == pe )
1322
1576
  goto _test_eof36;
1323
1577
  case 36:
1324
- #line 1325 "unicorn_http.c"
1578
+ #line 1579 "unicorn_http.c"
1325
1579
  switch( (*p) ) {
1326
- case 58: goto tr61;
1327
- case 83: goto tr62;
1328
- case 115: goto tr62;
1580
+ case 58: goto tr66;
1581
+ case 83: goto tr67;
1582
+ case 115: goto tr67;
1329
1583
  }
1330
1584
  goto st0;
1331
- tr61:
1332
- #line 329 "unicorn_http.rl"
1585
+ tr66:
1586
+ #line 326 "unicorn_http.rl"
1333
1587
  {
1334
1588
  rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
1335
1589
  }
@@ -1338,7 +1592,7 @@ st37:
1338
1592
  if ( ++p == pe )
1339
1593
  goto _test_eof37;
1340
1594
  case 37:
1341
- #line 1342 "unicorn_http.c"
1595
+ #line 1596 "unicorn_http.c"
1342
1596
  if ( (*p) == 47 )
1343
1597
  goto st38;
1344
1598
  goto st0;
@@ -1357,8 +1611,8 @@ case 39:
1357
1611
  case 37: goto st41;
1358
1612
  case 47: goto st0;
1359
1613
  case 60: goto st0;
1360
- case 91: goto tr68;
1361
- case 95: goto tr67;
1614
+ case 91: goto tr73;
1615
+ case 95: goto tr72;
1362
1616
  case 127: goto st0;
1363
1617
  }
1364
1618
  if ( (*p) < 45 ) {
@@ -1373,11 +1627,11 @@ case 39:
1373
1627
  goto st0;
1374
1628
  } else if ( (*p) > 90 ) {
1375
1629
  if ( 97 <= (*p) && (*p) <= 122 )
1376
- goto tr67;
1630
+ goto tr72;
1377
1631
  } else
1378
- goto tr67;
1632
+ goto tr72;
1379
1633
  } else
1380
- goto tr67;
1634
+ goto tr72;
1381
1635
  goto st40;
1382
1636
  st40:
1383
1637
  if ( ++p == pe )
@@ -1425,18 +1679,18 @@ case 42:
1425
1679
  } else
1426
1680
  goto st40;
1427
1681
  goto st0;
1428
- tr67:
1429
- #line 319 "unicorn_http.rl"
1682
+ tr72:
1683
+ #line 316 "unicorn_http.rl"
1430
1684
  {MARK(mark, p); }
1431
1685
  goto st43;
1432
1686
  st43:
1433
1687
  if ( ++p == pe )
1434
1688
  goto _test_eof43;
1435
1689
  case 43:
1436
- #line 1437 "unicorn_http.c"
1690
+ #line 1691 "unicorn_http.c"
1437
1691
  switch( (*p) ) {
1438
1692
  case 37: goto st41;
1439
- case 47: goto tr71;
1693
+ case 47: goto tr76;
1440
1694
  case 58: goto st44;
1441
1695
  case 60: goto st0;
1442
1696
  case 64: goto st39;
@@ -1467,7 +1721,7 @@ st44:
1467
1721
  case 44:
1468
1722
  switch( (*p) ) {
1469
1723
  case 37: goto st41;
1470
- case 47: goto tr71;
1724
+ case 47: goto tr76;
1471
1725
  case 60: goto st0;
1472
1726
  case 64: goto st39;
1473
1727
  case 127: goto st0;
@@ -1484,15 +1738,15 @@ case 44:
1484
1738
  } else
1485
1739
  goto st0;
1486
1740
  goto st40;
1487
- tr68:
1488
- #line 319 "unicorn_http.rl"
1741
+ tr73:
1742
+ #line 316 "unicorn_http.rl"
1489
1743
  {MARK(mark, p); }
1490
1744
  goto st45;
1491
1745
  st45:
1492
1746
  if ( ++p == pe )
1493
1747
  goto _test_eof45;
1494
1748
  case 45:
1495
- #line 1496 "unicorn_http.c"
1749
+ #line 1750 "unicorn_http.c"
1496
1750
  switch( (*p) ) {
1497
1751
  case 37: goto st41;
1498
1752
  case 47: goto st0;
@@ -1554,7 +1808,7 @@ st47:
1554
1808
  case 47:
1555
1809
  switch( (*p) ) {
1556
1810
  case 37: goto st41;
1557
- case 47: goto tr71;
1811
+ case 47: goto tr76;
1558
1812
  case 58: goto st44;
1559
1813
  case 60: goto st0;
1560
1814
  case 64: goto st39;
@@ -1569,17 +1823,17 @@ case 47:
1569
1823
  } else
1570
1824
  goto st0;
1571
1825
  goto st40;
1572
- tr62:
1573
- #line 323 "unicorn_http.rl"
1826
+ tr67:
1827
+ #line 320 "unicorn_http.rl"
1574
1828
  { downcase_char(deconst(p)); }
1575
1829
  goto st48;
1576
1830
  st48:
1577
1831
  if ( ++p == pe )
1578
1832
  goto _test_eof48;
1579
1833
  case 48:
1580
- #line 1581 "unicorn_http.c"
1834
+ #line 1835 "unicorn_http.c"
1581
1835
  if ( (*p) == 58 )
1582
- goto tr61;
1836
+ goto tr66;
1583
1837
  goto st0;
1584
1838
  st49:
1585
1839
  if ( ++p == pe )
@@ -2093,14 +2347,14 @@ case 67:
2093
2347
  goto tr3;
2094
2348
  goto st0;
2095
2349
  tr2:
2096
- #line 319 "unicorn_http.rl"
2350
+ #line 316 "unicorn_http.rl"
2097
2351
  {MARK(mark, p); }
2098
2352
  goto st68;
2099
2353
  st68:
2100
2354
  if ( ++p == pe )
2101
2355
  goto _test_eof68;
2102
2356
  case 68:
2103
- #line 2104 "unicorn_http.c"
2357
+ #line 2358 "unicorn_http.c"
2104
2358
  switch( (*p) ) {
2105
2359
  case 32: goto tr3;
2106
2360
  case 33: goto st49;
@@ -2160,7 +2414,7 @@ st70:
2160
2414
  goto _test_eof70;
2161
2415
  case 70:
2162
2416
  switch( (*p) ) {
2163
- case 32: goto tr95;
2417
+ case 32: goto tr100;
2164
2418
  case 33: goto st51;
2165
2419
  case 124: goto st51;
2166
2420
  case 126: goto st51;
@@ -2183,39 +2437,40 @@ case 70:
2183
2437
  } else
2184
2438
  goto st51;
2185
2439
  goto st0;
2186
- tr95:
2187
- #line 328 "unicorn_http.rl"
2440
+ tr100:
2441
+ #line 325 "unicorn_http.rl"
2188
2442
  { request_method(hp, PTR_TO(mark), LEN(mark, p)); }
2189
2443
  goto st71;
2190
2444
  st71:
2191
2445
  if ( ++p == pe )
2192
2446
  goto _test_eof71;
2193
2447
  case 71:
2194
- #line 2195 "unicorn_http.c"
2448
+ #line 2449 "unicorn_http.c"
2195
2449
  switch( (*p) ) {
2196
- case 42: goto tr96;
2197
- case 47: goto tr97;
2198
- case 72: goto tr98;
2199
- case 104: goto tr98;
2450
+ case 42: goto tr101;
2451
+ case 47: goto tr102;
2452
+ case 72: goto tr103;
2453
+ case 104: goto tr103;
2200
2454
  }
2201
2455
  goto st0;
2202
- tr96:
2203
- #line 319 "unicorn_http.rl"
2456
+ tr101:
2457
+ #line 316 "unicorn_http.rl"
2204
2458
  {MARK(mark, p); }
2205
2459
  goto st72;
2206
2460
  st72:
2207
2461
  if ( ++p == pe )
2208
2462
  goto _test_eof72;
2209
2463
  case 72:
2210
- #line 2211 "unicorn_http.c"
2464
+ #line 2465 "unicorn_http.c"
2211
2465
  switch( (*p) ) {
2212
- case 13: goto tr99;
2466
+ case 10: goto tr104;
2467
+ case 13: goto tr105;
2213
2468
  case 32: goto tr8;
2214
- case 35: goto tr100;
2469
+ case 35: goto tr106;
2215
2470
  }
2216
2471
  goto st0;
2217
- tr100:
2218
- #line 333 "unicorn_http.rl"
2472
+ tr106:
2473
+ #line 330 "unicorn_http.rl"
2219
2474
  {
2220
2475
  VALUE str;
2221
2476
 
@@ -2232,8 +2487,8 @@ tr100:
2232
2487
  }
2233
2488
  }
2234
2489
  goto st73;
2235
- tr110:
2236
- #line 358 "unicorn_http.rl"
2490
+ tr119:
2491
+ #line 355 "unicorn_http.rl"
2237
2492
  {
2238
2493
  VALUE val;
2239
2494
 
@@ -2244,7 +2499,7 @@ tr110:
2244
2499
  if (!STR_CSTR_EQ(val, "*"))
2245
2500
  rb_hash_aset(hp->env, g_path_info, val);
2246
2501
  }
2247
- #line 333 "unicorn_http.rl"
2502
+ #line 330 "unicorn_http.rl"
2248
2503
  {
2249
2504
  VALUE str;
2250
2505
 
@@ -2261,15 +2516,15 @@ tr110:
2261
2516
  }
2262
2517
  }
2263
2518
  goto st73;
2264
- tr116:
2265
- #line 352 "unicorn_http.rl"
2519
+ tr126:
2520
+ #line 349 "unicorn_http.rl"
2266
2521
  {MARK(start.query, p); }
2267
- #line 353 "unicorn_http.rl"
2522
+ #line 350 "unicorn_http.rl"
2268
2523
  {
2269
2524
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
2270
2525
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
2271
2526
  }
2272
- #line 333 "unicorn_http.rl"
2527
+ #line 330 "unicorn_http.rl"
2273
2528
  {
2274
2529
  VALUE str;
2275
2530
 
@@ -2286,13 +2541,13 @@ tr116:
2286
2541
  }
2287
2542
  }
2288
2543
  goto st73;
2289
- tr120:
2290
- #line 353 "unicorn_http.rl"
2544
+ tr131:
2545
+ #line 350 "unicorn_http.rl"
2291
2546
  {
2292
2547
  VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
2293
2548
  rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
2294
2549
  }
2295
- #line 333 "unicorn_http.rl"
2550
+ #line 330 "unicorn_http.rl"
2296
2551
  {
2297
2552
  VALUE str;
2298
2553
 
@@ -2313,29 +2568,31 @@ st73:
2313
2568
  if ( ++p == pe )
2314
2569
  goto _test_eof73;
2315
2570
  case 73:
2316
- #line 2317 "unicorn_http.c"
2571
+ #line 2572 "unicorn_http.c"
2317
2572
  switch( (*p) ) {
2318
- case 13: goto tr102;
2319
- case 32: goto tr37;
2573
+ case 10: goto tr108;
2574
+ case 13: goto tr109;
2575
+ case 32: goto tr42;
2320
2576
  case 35: goto st0;
2321
- case 37: goto tr103;
2577
+ case 37: goto tr110;
2322
2578
  case 127: goto st0;
2323
2579
  }
2324
2580
  if ( 0 <= (*p) && (*p) <= 31 )
2325
2581
  goto st0;
2326
- goto tr101;
2327
- tr101:
2328
- #line 319 "unicorn_http.rl"
2582
+ goto tr107;
2583
+ tr107:
2584
+ #line 316 "unicorn_http.rl"
2329
2585
  {MARK(mark, p); }
2330
2586
  goto st74;
2331
2587
  st74:
2332
2588
  if ( ++p == pe )
2333
2589
  goto _test_eof74;
2334
2590
  case 74:
2335
- #line 2336 "unicorn_http.c"
2591
+ #line 2592 "unicorn_http.c"
2336
2592
  switch( (*p) ) {
2337
- case 13: goto tr105;
2338
- case 32: goto tr40;
2593
+ case 10: goto tr112;
2594
+ case 13: goto tr113;
2595
+ case 32: goto tr45;
2339
2596
  case 35: goto st0;
2340
2597
  case 37: goto st75;
2341
2598
  case 127: goto st0;
@@ -2343,15 +2600,15 @@ case 74:
2343
2600
  if ( 0 <= (*p) && (*p) <= 31 )
2344
2601
  goto st0;
2345
2602
  goto st74;
2346
- tr103:
2347
- #line 319 "unicorn_http.rl"
2603
+ tr110:
2604
+ #line 316 "unicorn_http.rl"
2348
2605
  {MARK(mark, p); }
2349
2606
  goto st75;
2350
2607
  st75:
2351
2608
  if ( ++p == pe )
2352
2609
  goto _test_eof75;
2353
2610
  case 75:
2354
- #line 2355 "unicorn_http.c"
2611
+ #line 2612 "unicorn_http.c"
2355
2612
  if ( (*p) < 65 ) {
2356
2613
  if ( 48 <= (*p) && (*p) <= 57 )
2357
2614
  goto st76;
@@ -2374,27 +2631,28 @@ case 76:
2374
2631
  } else
2375
2632
  goto st74;
2376
2633
  goto st0;
2377
- tr97:
2378
- #line 319 "unicorn_http.rl"
2634
+ tr102:
2635
+ #line 316 "unicorn_http.rl"
2379
2636
  {MARK(mark, p); }
2380
2637
  goto st77;
2381
- tr136:
2382
- #line 332 "unicorn_http.rl"
2638
+ tr147:
2639
+ #line 329 "unicorn_http.rl"
2383
2640
  { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
2384
- #line 319 "unicorn_http.rl"
2641
+ #line 316 "unicorn_http.rl"
2385
2642
  {MARK(mark, p); }
2386
2643
  goto st77;
2387
2644
  st77:
2388
2645
  if ( ++p == pe )
2389
2646
  goto _test_eof77;
2390
2647
  case 77:
2391
- #line 2392 "unicorn_http.c"
2648
+ #line 2649 "unicorn_http.c"
2392
2649
  switch( (*p) ) {
2393
- case 13: goto tr109;
2394
- case 32: goto tr44;
2395
- case 35: goto tr110;
2650
+ case 10: goto tr117;
2651
+ case 13: goto tr118;
2652
+ case 32: goto tr49;
2653
+ case 35: goto tr119;
2396
2654
  case 37: goto st78;
2397
- case 63: goto tr112;
2655
+ case 63: goto tr121;
2398
2656
  case 127: goto st0;
2399
2657
  }
2400
2658
  if ( 0 <= (*p) && (*p) <= 31 )
@@ -2426,8 +2684,8 @@ case 79:
2426
2684
  } else
2427
2685
  goto st77;
2428
2686
  goto st0;
2429
- tr112:
2430
- #line 358 "unicorn_http.rl"
2687
+ tr121:
2688
+ #line 355 "unicorn_http.rl"
2431
2689
  {
2432
2690
  VALUE val;
2433
2691
 
@@ -2443,45 +2701,47 @@ st80:
2443
2701
  if ( ++p == pe )
2444
2702
  goto _test_eof80;
2445
2703
  case 80:
2446
- #line 2447 "unicorn_http.c"
2704
+ #line 2705 "unicorn_http.c"
2447
2705
  switch( (*p) ) {
2448
- case 13: goto tr115;
2449
- case 32: goto tr50;
2450
- case 35: goto tr116;
2451
- 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;
2452
2711
  case 127: goto st0;
2453
2712
  }
2454
2713
  if ( 0 <= (*p) && (*p) <= 31 )
2455
2714
  goto st0;
2456
- goto tr114;
2457
- tr114:
2458
- #line 352 "unicorn_http.rl"
2715
+ goto tr123;
2716
+ tr123:
2717
+ #line 349 "unicorn_http.rl"
2459
2718
  {MARK(start.query, p); }
2460
2719
  goto st81;
2461
2720
  st81:
2462
2721
  if ( ++p == pe )
2463
2722
  goto _test_eof81;
2464
2723
  case 81:
2465
- #line 2466 "unicorn_http.c"
2724
+ #line 2725 "unicorn_http.c"
2466
2725
  switch( (*p) ) {
2467
- case 13: goto tr119;
2468
- case 32: goto tr54;
2469
- case 35: goto tr120;
2726
+ case 10: goto tr129;
2727
+ case 13: goto tr130;
2728
+ case 32: goto tr59;
2729
+ case 35: goto tr131;
2470
2730
  case 37: goto st82;
2471
2731
  case 127: goto st0;
2472
2732
  }
2473
2733
  if ( 0 <= (*p) && (*p) <= 31 )
2474
2734
  goto st0;
2475
2735
  goto st81;
2476
- tr117:
2477
- #line 352 "unicorn_http.rl"
2736
+ tr127:
2737
+ #line 349 "unicorn_http.rl"
2478
2738
  {MARK(start.query, p); }
2479
2739
  goto st82;
2480
2740
  st82:
2481
2741
  if ( ++p == pe )
2482
2742
  goto _test_eof82;
2483
2743
  case 82:
2484
- #line 2485 "unicorn_http.c"
2744
+ #line 2745 "unicorn_http.c"
2485
2745
  if ( (*p) < 65 ) {
2486
2746
  if ( 48 <= (*p) && (*p) <= 57 )
2487
2747
  goto st83;
@@ -2504,67 +2764,67 @@ case 83:
2504
2764
  } else
2505
2765
  goto st81;
2506
2766
  goto st0;
2507
- tr98:
2508
- #line 319 "unicorn_http.rl"
2767
+ tr103:
2768
+ #line 316 "unicorn_http.rl"
2509
2769
  {MARK(mark, p); }
2510
- #line 323 "unicorn_http.rl"
2770
+ #line 320 "unicorn_http.rl"
2511
2771
  { downcase_char(deconst(p)); }
2512
2772
  goto st84;
2513
2773
  st84:
2514
2774
  if ( ++p == pe )
2515
2775
  goto _test_eof84;
2516
2776
  case 84:
2517
- #line 2518 "unicorn_http.c"
2777
+ #line 2778 "unicorn_http.c"
2518
2778
  switch( (*p) ) {
2519
- case 84: goto tr123;
2520
- case 116: goto tr123;
2779
+ case 84: goto tr134;
2780
+ case 116: goto tr134;
2521
2781
  }
2522
2782
  goto st0;
2523
- tr123:
2524
- #line 323 "unicorn_http.rl"
2783
+ tr134:
2784
+ #line 320 "unicorn_http.rl"
2525
2785
  { downcase_char(deconst(p)); }
2526
2786
  goto st85;
2527
2787
  st85:
2528
2788
  if ( ++p == pe )
2529
2789
  goto _test_eof85;
2530
2790
  case 85:
2531
- #line 2532 "unicorn_http.c"
2791
+ #line 2792 "unicorn_http.c"
2532
2792
  switch( (*p) ) {
2533
- case 84: goto tr124;
2534
- case 116: goto tr124;
2793
+ case 84: goto tr135;
2794
+ case 116: goto tr135;
2535
2795
  }
2536
2796
  goto st0;
2537
- tr124:
2538
- #line 323 "unicorn_http.rl"
2797
+ tr135:
2798
+ #line 320 "unicorn_http.rl"
2539
2799
  { downcase_char(deconst(p)); }
2540
2800
  goto st86;
2541
2801
  st86:
2542
2802
  if ( ++p == pe )
2543
2803
  goto _test_eof86;
2544
2804
  case 86:
2545
- #line 2546 "unicorn_http.c"
2805
+ #line 2806 "unicorn_http.c"
2546
2806
  switch( (*p) ) {
2547
- case 80: goto tr125;
2548
- case 112: goto tr125;
2807
+ case 80: goto tr136;
2808
+ case 112: goto tr136;
2549
2809
  }
2550
2810
  goto st0;
2551
- tr125:
2552
- #line 323 "unicorn_http.rl"
2811
+ tr136:
2812
+ #line 320 "unicorn_http.rl"
2553
2813
  { downcase_char(deconst(p)); }
2554
2814
  goto st87;
2555
2815
  st87:
2556
2816
  if ( ++p == pe )
2557
2817
  goto _test_eof87;
2558
2818
  case 87:
2559
- #line 2560 "unicorn_http.c"
2819
+ #line 2820 "unicorn_http.c"
2560
2820
  switch( (*p) ) {
2561
- case 58: goto tr126;
2562
- case 83: goto tr127;
2563
- case 115: goto tr127;
2821
+ case 58: goto tr137;
2822
+ case 83: goto tr138;
2823
+ case 115: goto tr138;
2564
2824
  }
2565
2825
  goto st0;
2566
- tr126:
2567
- #line 329 "unicorn_http.rl"
2826
+ tr137:
2827
+ #line 326 "unicorn_http.rl"
2568
2828
  {
2569
2829
  rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
2570
2830
  }
@@ -2573,7 +2833,7 @@ st88:
2573
2833
  if ( ++p == pe )
2574
2834
  goto _test_eof88;
2575
2835
  case 88:
2576
- #line 2577 "unicorn_http.c"
2836
+ #line 2837 "unicorn_http.c"
2577
2837
  if ( (*p) == 47 )
2578
2838
  goto st89;
2579
2839
  goto st0;
@@ -2592,8 +2852,8 @@ case 90:
2592
2852
  case 37: goto st92;
2593
2853
  case 47: goto st0;
2594
2854
  case 60: goto st0;
2595
- case 91: goto tr133;
2596
- case 95: goto tr132;
2855
+ case 91: goto tr144;
2856
+ case 95: goto tr143;
2597
2857
  case 127: goto st0;
2598
2858
  }
2599
2859
  if ( (*p) < 45 ) {
@@ -2608,11 +2868,11 @@ case 90:
2608
2868
  goto st0;
2609
2869
  } else if ( (*p) > 90 ) {
2610
2870
  if ( 97 <= (*p) && (*p) <= 122 )
2611
- goto tr132;
2871
+ goto tr143;
2612
2872
  } else
2613
- goto tr132;
2873
+ goto tr143;
2614
2874
  } else
2615
- goto tr132;
2875
+ goto tr143;
2616
2876
  goto st91;
2617
2877
  st91:
2618
2878
  if ( ++p == pe )
@@ -2660,18 +2920,18 @@ case 93:
2660
2920
  } else
2661
2921
  goto st91;
2662
2922
  goto st0;
2663
- tr132:
2664
- #line 319 "unicorn_http.rl"
2923
+ tr143:
2924
+ #line 316 "unicorn_http.rl"
2665
2925
  {MARK(mark, p); }
2666
2926
  goto st94;
2667
2927
  st94:
2668
2928
  if ( ++p == pe )
2669
2929
  goto _test_eof94;
2670
2930
  case 94:
2671
- #line 2672 "unicorn_http.c"
2931
+ #line 2932 "unicorn_http.c"
2672
2932
  switch( (*p) ) {
2673
2933
  case 37: goto st92;
2674
- case 47: goto tr136;
2934
+ case 47: goto tr147;
2675
2935
  case 58: goto st95;
2676
2936
  case 60: goto st0;
2677
2937
  case 64: goto st90;
@@ -2702,7 +2962,7 @@ st95:
2702
2962
  case 95:
2703
2963
  switch( (*p) ) {
2704
2964
  case 37: goto st92;
2705
- case 47: goto tr136;
2965
+ case 47: goto tr147;
2706
2966
  case 60: goto st0;
2707
2967
  case 64: goto st90;
2708
2968
  case 127: goto st0;
@@ -2719,15 +2979,15 @@ case 95:
2719
2979
  } else
2720
2980
  goto st0;
2721
2981
  goto st91;
2722
- tr133:
2723
- #line 319 "unicorn_http.rl"
2982
+ tr144:
2983
+ #line 316 "unicorn_http.rl"
2724
2984
  {MARK(mark, p); }
2725
2985
  goto st96;
2726
2986
  st96:
2727
2987
  if ( ++p == pe )
2728
2988
  goto _test_eof96;
2729
2989
  case 96:
2730
- #line 2731 "unicorn_http.c"
2990
+ #line 2991 "unicorn_http.c"
2731
2991
  switch( (*p) ) {
2732
2992
  case 37: goto st92;
2733
2993
  case 47: goto st0;
@@ -2789,7 +3049,7 @@ st98:
2789
3049
  case 98:
2790
3050
  switch( (*p) ) {
2791
3051
  case 37: goto st92;
2792
- case 47: goto tr136;
3052
+ case 47: goto tr147;
2793
3053
  case 58: goto st95;
2794
3054
  case 60: goto st0;
2795
3055
  case 64: goto st90;
@@ -2804,35 +3064,35 @@ case 98:
2804
3064
  } else
2805
3065
  goto st0;
2806
3066
  goto st91;
2807
- tr127:
2808
- #line 323 "unicorn_http.rl"
3067
+ tr138:
3068
+ #line 320 "unicorn_http.rl"
2809
3069
  { downcase_char(deconst(p)); }
2810
3070
  goto st99;
2811
3071
  st99:
2812
3072
  if ( ++p == pe )
2813
3073
  goto _test_eof99;
2814
3074
  case 99:
2815
- #line 2816 "unicorn_http.c"
3075
+ #line 3076 "unicorn_http.c"
2816
3076
  if ( (*p) == 58 )
2817
- goto tr126;
3077
+ goto tr137;
2818
3078
  goto st0;
2819
3079
  st100:
2820
3080
  if ( ++p == pe )
2821
3081
  goto _test_eof100;
2822
3082
  case 100:
2823
3083
  if ( (*p) == 48 )
2824
- goto tr140;
3084
+ goto tr151;
2825
3085
  if ( (*p) < 65 ) {
2826
3086
  if ( 49 <= (*p) && (*p) <= 57 )
2827
- goto tr141;
3087
+ goto tr152;
2828
3088
  } else if ( (*p) > 70 ) {
2829
3089
  if ( 97 <= (*p) && (*p) <= 102 )
2830
- goto tr141;
3090
+ goto tr152;
2831
3091
  } else
2832
- goto tr141;
3092
+ goto tr152;
2833
3093
  goto st0;
2834
- tr140:
2835
- #line 368 "unicorn_http.rl"
3094
+ tr151:
3095
+ #line 365 "unicorn_http.rl"
2836
3096
  {
2837
3097
  hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
2838
3098
  if (hp->len.chunk < 0)
@@ -2843,30 +3103,24 @@ st101:
2843
3103
  if ( ++p == pe )
2844
3104
  goto _test_eof101;
2845
3105
  case 101:
2846
- #line 2847 "unicorn_http.c"
3106
+ #line 3107 "unicorn_http.c"
2847
3107
  switch( (*p) ) {
3108
+ case 10: goto tr153;
2848
3109
  case 13: goto st102;
2849
- case 48: goto tr140;
3110
+ case 48: goto tr151;
2850
3111
  case 59: goto st111;
2851
3112
  }
2852
3113
  if ( (*p) < 65 ) {
2853
3114
  if ( 49 <= (*p) && (*p) <= 57 )
2854
- goto tr141;
3115
+ goto tr152;
2855
3116
  } else if ( (*p) > 70 ) {
2856
3117
  if ( 97 <= (*p) && (*p) <= 102 )
2857
- goto tr141;
3118
+ goto tr152;
2858
3119
  } else
2859
- goto tr141;
2860
- goto st0;
2861
- st102:
2862
- if ( ++p == pe )
2863
- goto _test_eof102;
2864
- case 102:
2865
- if ( (*p) == 10 )
2866
- goto tr144;
3120
+ goto tr152;
2867
3121
  goto st0;
2868
- tr144:
2869
- #line 397 "unicorn_http.rl"
3122
+ tr153:
3123
+ #line 394 "unicorn_http.rl"
2870
3124
  {
2871
3125
  HP_FL_SET(hp, INTRAILER);
2872
3126
  cs = http_parser_en_Trailers;
@@ -2879,10 +3133,17 @@ st123:
2879
3133
  if ( ++p == pe )
2880
3134
  goto _test_eof123;
2881
3135
  case 123:
2882
- #line 2883 "unicorn_http.c"
3136
+ #line 3137 "unicorn_http.c"
2883
3137
  goto st0;
2884
- tr141:
2885
- #line 368 "unicorn_http.rl"
3138
+ st102:
3139
+ if ( ++p == pe )
3140
+ goto _test_eof102;
3141
+ case 102:
3142
+ if ( (*p) == 10 )
3143
+ goto tr153;
3144
+ goto st0;
3145
+ tr152:
3146
+ #line 365 "unicorn_http.rl"
2886
3147
  {
2887
3148
  hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
2888
3149
  if (hp->len.chunk < 0)
@@ -2893,34 +3154,28 @@ st103:
2893
3154
  if ( ++p == pe )
2894
3155
  goto _test_eof103;
2895
3156
  case 103:
2896
- #line 2897 "unicorn_http.c"
3157
+ #line 3158 "unicorn_http.c"
2897
3158
  switch( (*p) ) {
2898
- case 13: goto st104;
3159
+ case 10: goto st104;
3160
+ case 13: goto st107;
2899
3161
  case 59: goto st108;
2900
3162
  }
2901
3163
  if ( (*p) < 65 ) {
2902
3164
  if ( 48 <= (*p) && (*p) <= 57 )
2903
- goto tr141;
3165
+ goto tr152;
2904
3166
  } else if ( (*p) > 70 ) {
2905
3167
  if ( 97 <= (*p) && (*p) <= 102 )
2906
- goto tr141;
3168
+ goto tr152;
2907
3169
  } else
2908
- goto tr141;
3170
+ goto tr152;
2909
3171
  goto st0;
2910
3172
  st104:
2911
3173
  if ( ++p == pe )
2912
3174
  goto _test_eof104;
2913
3175
  case 104:
2914
- if ( (*p) == 10 )
2915
- goto st105;
2916
- goto st0;
2917
- st105:
2918
- if ( ++p == pe )
2919
- goto _test_eof105;
2920
- case 105:
2921
- goto tr148;
2922
- tr148:
2923
- #line 405 "unicorn_http.rl"
3176
+ goto tr159;
3177
+ tr159:
3178
+ #line 402 "unicorn_http.rl"
2924
3179
  {
2925
3180
  skip_chunk_data_hack: {
2926
3181
  size_t nr = MIN((size_t)hp->len.chunk, REMAINING);
@@ -2934,31 +3189,41 @@ tr148:
2934
3189
  goto post_exec;
2935
3190
  } else {
2936
3191
  p--;
2937
- {goto st106;}
3192
+ {goto st105;}
2938
3193
  }
2939
3194
  }}
2940
- 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;
2941
3206
  st106:
2942
3207
  if ( ++p == pe )
2943
3208
  goto _test_eof106;
2944
3209
  case 106:
2945
- #line 2946 "unicorn_http.c"
2946
- if ( (*p) == 13 )
2947
- goto st107;
3210
+ if ( (*p) == 10 )
3211
+ goto st100;
2948
3212
  goto st0;
2949
3213
  st107:
2950
3214
  if ( ++p == pe )
2951
3215
  goto _test_eof107;
2952
3216
  case 107:
2953
3217
  if ( (*p) == 10 )
2954
- goto st100;
3218
+ goto st104;
2955
3219
  goto st0;
2956
3220
  st108:
2957
3221
  if ( ++p == pe )
2958
3222
  goto _test_eof108;
2959
3223
  case 108:
2960
3224
  switch( (*p) ) {
2961
- case 13: goto st104;
3225
+ case 10: goto st104;
3226
+ case 13: goto st107;
2962
3227
  case 32: goto st108;
2963
3228
  case 33: goto st109;
2964
3229
  case 59: goto st108;
@@ -2989,7 +3254,8 @@ st109:
2989
3254
  goto _test_eof109;
2990
3255
  case 109:
2991
3256
  switch( (*p) ) {
2992
- case 13: goto st104;
3257
+ case 10: goto st104;
3258
+ case 13: goto st107;
2993
3259
  case 33: goto st109;
2994
3260
  case 59: goto st108;
2995
3261
  case 61: goto st110;
@@ -3019,7 +3285,8 @@ st110:
3019
3285
  goto _test_eof110;
3020
3286
  case 110:
3021
3287
  switch( (*p) ) {
3022
- case 13: goto st104;
3288
+ case 10: goto st104;
3289
+ case 13: goto st107;
3023
3290
  case 33: goto st110;
3024
3291
  case 59: goto st108;
3025
3292
  case 124: goto st110;
@@ -3048,6 +3315,7 @@ st111:
3048
3315
  goto _test_eof111;
3049
3316
  case 111:
3050
3317
  switch( (*p) ) {
3318
+ case 10: goto tr153;
3051
3319
  case 13: goto st102;
3052
3320
  case 32: goto st111;
3053
3321
  case 33: goto st112;
@@ -3079,6 +3347,7 @@ st112:
3079
3347
  goto _test_eof112;
3080
3348
  case 112:
3081
3349
  switch( (*p) ) {
3350
+ case 10: goto tr153;
3082
3351
  case 13: goto st102;
3083
3352
  case 33: goto st112;
3084
3353
  case 59: goto st111;
@@ -3109,6 +3378,7 @@ st113:
3109
3378
  goto _test_eof113;
3110
3379
  case 113:
3111
3380
  switch( (*p) ) {
3381
+ case 10: goto tr153;
3112
3382
  case 13: goto st102;
3113
3383
  case 33: goto st113;
3114
3384
  case 59: goto st111;
@@ -3133,110 +3403,127 @@ case 113:
3133
3403
  } else
3134
3404
  goto st113;
3135
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;
3136
3426
  st114:
3137
3427
  if ( ++p == pe )
3138
3428
  goto _test_eof114;
3139
3429
  case 114:
3430
+ #line 3431 "unicorn_http.c"
3140
3431
  switch( (*p) ) {
3141
3432
  case 9: goto st115;
3433
+ case 10: goto tr167;
3142
3434
  case 13: goto st118;
3143
3435
  case 32: goto st115;
3144
- case 33: goto tr157;
3145
- case 124: goto tr157;
3146
- case 126: goto tr157;
3436
+ case 33: goto tr169;
3437
+ case 124: goto tr169;
3438
+ case 126: goto tr169;
3147
3439
  }
3148
3440
  if ( (*p) < 45 ) {
3149
3441
  if ( (*p) > 39 ) {
3150
3442
  if ( 42 <= (*p) && (*p) <= 43 )
3151
- goto tr157;
3443
+ goto tr169;
3152
3444
  } else if ( (*p) >= 35 )
3153
- goto tr157;
3445
+ goto tr169;
3154
3446
  } else if ( (*p) > 46 ) {
3155
3447
  if ( (*p) < 65 ) {
3156
3448
  if ( 48 <= (*p) && (*p) <= 57 )
3157
- goto tr157;
3449
+ goto tr169;
3158
3450
  } else if ( (*p) > 90 ) {
3159
3451
  if ( 94 <= (*p) && (*p) <= 122 )
3160
- goto tr157;
3452
+ goto tr169;
3161
3453
  } else
3162
- goto tr157;
3454
+ goto tr169;
3163
3455
  } else
3164
- goto tr157;
3456
+ goto tr169;
3165
3457
  goto st0;
3166
- tr159:
3167
- #line 325 "unicorn_http.rl"
3458
+ tr171:
3459
+ #line 322 "unicorn_http.rl"
3168
3460
  { MARK(mark, p); }
3169
3461
  goto st115;
3170
3462
  st115:
3171
3463
  if ( ++p == pe )
3172
3464
  goto _test_eof115;
3173
3465
  case 115:
3174
- #line 3175 "unicorn_http.c"
3466
+ #line 3467 "unicorn_http.c"
3175
3467
  switch( (*p) ) {
3176
- case 9: goto tr159;
3177
- case 13: goto tr160;
3178
- case 32: goto tr159;
3468
+ case 9: goto tr171;
3469
+ case 10: goto tr172;
3470
+ case 13: goto tr173;
3471
+ case 32: goto tr171;
3179
3472
  case 127: goto st0;
3180
3473
  }
3181
3474
  if ( 0 <= (*p) && (*p) <= 31 )
3182
3475
  goto st0;
3183
- goto tr158;
3184
- tr158:
3185
- #line 325 "unicorn_http.rl"
3476
+ goto tr170;
3477
+ tr170:
3478
+ #line 322 "unicorn_http.rl"
3186
3479
  { MARK(mark, p); }
3187
3480
  goto st116;
3188
3481
  st116:
3189
3482
  if ( ++p == pe )
3190
3483
  goto _test_eof116;
3191
3484
  case 116:
3192
- #line 3193 "unicorn_http.c"
3485
+ #line 3486 "unicorn_http.c"
3193
3486
  switch( (*p) ) {
3194
- case 13: goto tr162;
3487
+ case 10: goto tr175;
3488
+ case 13: goto tr176;
3195
3489
  case 127: goto st0;
3196
3490
  }
3197
3491
  if ( (*p) > 8 ) {
3198
- if ( 10 <= (*p) && (*p) <= 31 )
3492
+ if ( 11 <= (*p) && (*p) <= 31 )
3199
3493
  goto st0;
3200
3494
  } else if ( (*p) >= 0 )
3201
3495
  goto st0;
3202
3496
  goto st116;
3203
- tr160:
3204
- #line 325 "unicorn_http.rl"
3497
+ tr173:
3498
+ #line 322 "unicorn_http.rl"
3205
3499
  { MARK(mark, p); }
3206
- #line 327 "unicorn_http.rl"
3500
+ #line 324 "unicorn_http.rl"
3207
3501
  { write_cont_value(hp, buffer, p); }
3208
3502
  goto st117;
3209
- tr162:
3210
- #line 327 "unicorn_http.rl"
3503
+ tr176:
3504
+ #line 324 "unicorn_http.rl"
3211
3505
  { write_cont_value(hp, buffer, p); }
3212
3506
  goto st117;
3213
- tr169:
3214
- #line 325 "unicorn_http.rl"
3507
+ tr183:
3508
+ #line 322 "unicorn_http.rl"
3215
3509
  { MARK(mark, p); }
3216
- #line 326 "unicorn_http.rl"
3510
+ #line 323 "unicorn_http.rl"
3217
3511
  { write_value(hp, buffer, p); }
3218
3512
  goto st117;
3219
- tr171:
3220
- #line 326 "unicorn_http.rl"
3513
+ tr186:
3514
+ #line 323 "unicorn_http.rl"
3221
3515
  { write_value(hp, buffer, p); }
3222
3516
  goto st117;
3223
3517
  st117:
3224
3518
  if ( ++p == pe )
3225
3519
  goto _test_eof117;
3226
3520
  case 117:
3227
- #line 3228 "unicorn_http.c"
3521
+ #line 3522 "unicorn_http.c"
3228
3522
  if ( (*p) == 10 )
3229
3523
  goto st114;
3230
3524
  goto st0;
3231
- st118:
3232
- if ( ++p == pe )
3233
- goto _test_eof118;
3234
- case 118:
3235
- if ( (*p) == 10 )
3236
- goto tr164;
3237
- goto st0;
3238
- tr164:
3239
- #line 392 "unicorn_http.rl"
3525
+ tr167:
3526
+ #line 389 "unicorn_http.rl"
3240
3527
  {
3241
3528
  cs = http_parser_first_final;
3242
3529
  goto post_exec;
@@ -3246,84 +3533,93 @@ st124:
3246
3533
  if ( ++p == pe )
3247
3534
  goto _test_eof124;
3248
3535
  case 124:
3249
- #line 3250 "unicorn_http.c"
3536
+ #line 3537 "unicorn_http.c"
3250
3537
  goto st0;
3251
- tr157:
3252
- #line 321 "unicorn_http.rl"
3538
+ st118:
3539
+ if ( ++p == pe )
3540
+ goto _test_eof118;
3541
+ case 118:
3542
+ if ( (*p) == 10 )
3543
+ goto tr167;
3544
+ goto st0;
3545
+ tr169:
3546
+ #line 318 "unicorn_http.rl"
3253
3547
  { MARK(start.field, p); }
3254
- #line 322 "unicorn_http.rl"
3548
+ #line 319 "unicorn_http.rl"
3255
3549
  { snake_upcase_char(deconst(p)); }
3256
3550
  goto st119;
3257
- tr165:
3258
- #line 322 "unicorn_http.rl"
3551
+ tr178:
3552
+ #line 319 "unicorn_http.rl"
3259
3553
  { snake_upcase_char(deconst(p)); }
3260
3554
  goto st119;
3261
3555
  st119:
3262
3556
  if ( ++p == pe )
3263
3557
  goto _test_eof119;
3264
3558
  case 119:
3265
- #line 3266 "unicorn_http.c"
3559
+ #line 3560 "unicorn_http.c"
3266
3560
  switch( (*p) ) {
3267
- case 33: goto tr165;
3268
- case 58: goto tr166;
3269
- case 124: goto tr165;
3270
- case 126: goto tr165;
3561
+ case 33: goto tr178;
3562
+ case 58: goto tr179;
3563
+ case 124: goto tr178;
3564
+ case 126: goto tr178;
3271
3565
  }
3272
3566
  if ( (*p) < 45 ) {
3273
3567
  if ( (*p) > 39 ) {
3274
3568
  if ( 42 <= (*p) && (*p) <= 43 )
3275
- goto tr165;
3569
+ goto tr178;
3276
3570
  } else if ( (*p) >= 35 )
3277
- goto tr165;
3571
+ goto tr178;
3278
3572
  } else if ( (*p) > 46 ) {
3279
3573
  if ( (*p) < 65 ) {
3280
3574
  if ( 48 <= (*p) && (*p) <= 57 )
3281
- goto tr165;
3575
+ goto tr178;
3282
3576
  } else if ( (*p) > 90 ) {
3283
3577
  if ( 94 <= (*p) && (*p) <= 122 )
3284
- goto tr165;
3578
+ goto tr178;
3285
3579
  } else
3286
- goto tr165;
3580
+ goto tr178;
3287
3581
  } else
3288
- goto tr165;
3582
+ goto tr178;
3289
3583
  goto st0;
3290
- tr168:
3291
- #line 325 "unicorn_http.rl"
3584
+ tr181:
3585
+ #line 322 "unicorn_http.rl"
3292
3586
  { MARK(mark, p); }
3293
3587
  goto st120;
3294
- tr166:
3295
- #line 324 "unicorn_http.rl"
3588
+ tr179:
3589
+ #line 321 "unicorn_http.rl"
3296
3590
  { hp->s.field_len = LEN(start.field, p); }
3297
3591
  goto st120;
3298
3592
  st120:
3299
3593
  if ( ++p == pe )
3300
3594
  goto _test_eof120;
3301
3595
  case 120:
3302
- #line 3303 "unicorn_http.c"
3596
+ #line 3597 "unicorn_http.c"
3303
3597
  switch( (*p) ) {
3304
- case 9: goto tr168;
3305
- case 13: goto tr169;
3306
- case 32: goto tr168;
3598
+ case 9: goto tr181;
3599
+ case 10: goto tr182;
3600
+ case 13: goto tr183;
3601
+ case 32: goto tr181;
3307
3602
  case 127: goto st0;
3308
3603
  }
3309
3604
  if ( 0 <= (*p) && (*p) <= 31 )
3310
3605
  goto st0;
3311
- goto tr167;
3312
- tr167:
3313
- #line 325 "unicorn_http.rl"
3606
+ goto tr180;
3607
+ tr180:
3608
+ #line 322 "unicorn_http.rl"
3314
3609
  { MARK(mark, p); }
3315
3610
  goto st121;
3316
3611
  st121:
3317
3612
  if ( ++p == pe )
3318
3613
  goto _test_eof121;
3319
3614
  case 121:
3320
- #line 3321 "unicorn_http.c"
3615
+ #line 3616 "unicorn_http.c"
3321
3616
  switch( (*p) ) {
3322
- case 13: goto tr171;
3617
+ case 10: goto tr185;
3618
+ case 13: goto tr186;
3323
3619
  case 127: goto st0;
3324
3620
  }
3325
3621
  if ( (*p) > 8 ) {
3326
- if ( 10 <= (*p) && (*p) <= 31 )
3622
+ if ( 11 <= (*p) && (*p) <= 31 )
3327
3623
  goto st0;
3328
3624
  } else if ( (*p) >= 0 )
3329
3625
  goto st0;
@@ -3345,8 +3641,8 @@ case 121:
3345
3641
  _test_eof15: cs = 15; goto _test_eof;
3346
3642
  _test_eof16: cs = 16; goto _test_eof;
3347
3643
  _test_eof17: cs = 17; goto _test_eof;
3348
- _test_eof18: cs = 18; goto _test_eof;
3349
3644
  _test_eof122: cs = 122; goto _test_eof;
3645
+ _test_eof18: cs = 18; goto _test_eof;
3350
3646
  _test_eof19: cs = 19; goto _test_eof;
3351
3647
  _test_eof20: cs = 20; goto _test_eof;
3352
3648
  _test_eof21: cs = 21; goto _test_eof;
@@ -3430,8 +3726,8 @@ case 121:
3430
3726
  _test_eof99: cs = 99; goto _test_eof;
3431
3727
  _test_eof100: cs = 100; goto _test_eof;
3432
3728
  _test_eof101: cs = 101; goto _test_eof;
3433
- _test_eof102: cs = 102; goto _test_eof;
3434
3729
  _test_eof123: cs = 123; goto _test_eof;
3730
+ _test_eof102: cs = 102; goto _test_eof;
3435
3731
  _test_eof103: cs = 103; goto _test_eof;
3436
3732
  _test_eof104: cs = 104; goto _test_eof;
3437
3733
  _test_eof105: cs = 105; goto _test_eof;
@@ -3447,8 +3743,8 @@ case 121:
3447
3743
  _test_eof115: cs = 115; goto _test_eof;
3448
3744
  _test_eof116: cs = 116; goto _test_eof;
3449
3745
  _test_eof117: cs = 117; goto _test_eof;
3450
- _test_eof118: cs = 118; goto _test_eof;
3451
3746
  _test_eof124: cs = 124; goto _test_eof;
3747
+ _test_eof118: cs = 118; goto _test_eof;
3452
3748
  _test_eof119: cs = 119; goto _test_eof;
3453
3749
  _test_eof120: cs = 120; goto _test_eof;
3454
3750
  _test_eof121: cs = 121; goto _test_eof;
@@ -3457,21 +3753,41 @@ case 121:
3457
3753
  _out: {}
3458
3754
  }
3459
3755
 
3460
- #line 466 "unicorn_http.rl"
3756
+ #line 463 "unicorn_http.rl"
3461
3757
  post_exec: /* "_out:" also goes here */
3462
3758
  if (hp->cs != http_parser_error)
3463
3759
  hp->cs = cs;
3464
- hp->offset = p - buffer;
3760
+ hp->offset = ulong2uint(p - buffer);
3465
3761
 
3466
3762
  assert(p <= pe && "buffer overflow after parsing execute");
3467
3763
  assert(hp->offset <= len && "offset longer than length");
3468
3764
  }
3469
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
+
3470
3786
  static struct http_parser *data_get(VALUE self)
3471
3787
  {
3472
3788
  struct http_parser *hp;
3473
3789
 
3474
- Data_Get_Struct(self, struct http_parser, hp);
3790
+ TypedData_Get_Struct(self, struct http_parser, &hp_type, hp);
3475
3791
  assert(hp && "failed to extract http_parser struct");
3476
3792
  return hp;
3477
3793
  }
@@ -3486,26 +3802,29 @@ static void set_url_scheme(VALUE env, VALUE *server_port)
3486
3802
  VALUE scheme = rb_hash_aref(env, g_rack_url_scheme);
3487
3803
 
3488
3804
  if (NIL_P(scheme)) {
3489
- if (trust_x_forward == Qfalse) {
3490
- scheme = g_http;
3805
+ /*
3806
+ * would anybody be horribly opposed to removing the X-Forwarded-SSL
3807
+ * and X-Forwarded-Proto handling from this parser? We've had it
3808
+ * forever and nobody has said anything against it, either.
3809
+ * Anyways, please send comments to our public mailing list:
3810
+ * unicorn-public@yhbt.net (no HTML mail, no subscription necessary)
3811
+ */
3812
+ scheme = rb_hash_aref(env, g_http_x_forwarded_ssl);
3813
+ if (!NIL_P(scheme) && STR_CSTR_EQ(scheme, "on")) {
3814
+ *server_port = g_port_443;
3815
+ scheme = g_https;
3491
3816
  } else {
3492
- scheme = rb_hash_aref(env, g_http_x_forwarded_ssl);
3493
- if (!NIL_P(scheme) && STR_CSTR_EQ(scheme, "on")) {
3494
- *server_port = g_port_443;
3495
- scheme = g_https;
3817
+ scheme = rb_hash_aref(env, g_http_x_forwarded_proto);
3818
+ if (NIL_P(scheme)) {
3819
+ scheme = g_http;
3496
3820
  } else {
3497
- scheme = rb_hash_aref(env, g_http_x_forwarded_proto);
3498
- if (NIL_P(scheme)) {
3499
- scheme = g_http;
3821
+ long len = RSTRING_LEN(scheme);
3822
+ if (len >= 5 && !memcmp(RSTRING_PTR(scheme), "https", 5)) {
3823
+ if (len != 5)
3824
+ scheme = g_https;
3825
+ *server_port = g_port_443;
3500
3826
  } else {
3501
- long len = RSTRING_LEN(scheme);
3502
- if (len >= 5 && !memcmp(RSTRING_PTR(scheme), "https", 5)) {
3503
- if (len != 5)
3504
- scheme = g_https;
3505
- *server_port = g_port_443;
3506
- } else {
3507
- scheme = g_http;
3508
- }
3827
+ scheme = g_http;
3509
3828
  }
3510
3829
  }
3511
3830
  }
@@ -3574,21 +3893,12 @@ static void finalize_header(struct http_parser *hp)
3574
3893
  rb_hash_aset(hp->env, g_query_string, rb_str_new(NULL, 0));
3575
3894
  }
3576
3895
 
3577
- static void hp_mark(void *ptr)
3578
- {
3579
- struct http_parser *hp = ptr;
3580
-
3581
- rb_gc_mark(hp->buf);
3582
- rb_gc_mark(hp->env);
3583
- rb_gc_mark(hp->cont);
3584
- }
3585
-
3586
3896
  static VALUE HttpParser_alloc(VALUE klass)
3587
3897
  {
3588
3898
  struct http_parser *hp;
3589
- return Data_Make_Struct(klass, struct http_parser, hp_mark, -1, hp);
3590
- }
3591
3899
 
3900
+ return TypedData_Make_Struct(klass, struct http_parser, &hp_type, hp);
3901
+ }
3592
3902
 
3593
3903
  /**
3594
3904
  * call-seq:
@@ -3603,7 +3913,6 @@ static VALUE HttpParser_init(VALUE self)
3603
3913
  http_parser_init(hp);
3604
3914
  hp->buf = rb_str_new(NULL, 0);
3605
3915
  hp->env = rb_hash_new();
3606
- hp->nr_requests = keepalive_requests;
3607
3916
 
3608
3917
  return self;
3609
3918
  }
@@ -3619,62 +3928,16 @@ static VALUE HttpParser_clear(VALUE self)
3619
3928
  {
3620
3929
  struct http_parser *hp = data_get(self);
3621
3930
 
3622
- http_parser_init(hp);
3623
- rb_funcall(hp->env, id_clear, 0);
3624
- rb_ivar_set(self, id_response_start_sent, Qfalse);
3625
-
3626
- return self;
3627
- }
3628
-
3629
- /**
3630
- * call-seq:
3631
- * parser.dechunk! => parser
3632
- *
3633
- * Resets the parser to a state suitable for dechunking response bodies
3634
- *
3635
- */
3636
- static VALUE HttpParser_dechunk_bang(VALUE self)
3637
- {
3638
- struct http_parser *hp = data_get(self);
3931
+ /* we can't safely reuse .buf and .env if hijacked */
3932
+ if (HP_FL_TEST(hp, HIJACK))
3933
+ return HttpParser_init(self);
3639
3934
 
3640
3935
  http_parser_init(hp);
3641
-
3642
- /*
3643
- * we don't care about trailers in dechunk-only mode,
3644
- * but if we did we'd set UH_FL_HASTRAILER and clear hp->env
3645
- */
3646
- if (0) {
3647
- rb_funcall(hp->env, id_clear, 0);
3648
- hp->flags = UH_FL_HASTRAILER;
3649
- }
3650
-
3651
- hp->flags |= UH_FL_HASBODY | UH_FL_INBODY | UH_FL_CHUNKED;
3652
- hp->cs = http_parser_en_ChunkedBody;
3936
+ rb_hash_clear(hp->env);
3653
3937
 
3654
3938
  return self;
3655
3939
  }
3656
3940
 
3657
- /**
3658
- * call-seq:
3659
- * parser.reset => nil
3660
- *
3661
- * Resets the parser to it's initial state so that you can reuse it
3662
- * rather than making new ones.
3663
- *
3664
- * This method is deprecated and to be removed in Unicorn 4.x
3665
- */
3666
- static VALUE HttpParser_reset(VALUE self)
3667
- {
3668
- static int warned;
3669
-
3670
- if (!warned) {
3671
- rb_warn("Unicorn::HttpParser#reset is deprecated; "
3672
- "use Unicorn::HttpParser#clear instead");
3673
- }
3674
- HttpParser_clear(self);
3675
- return Qnil;
3676
- }
3677
-
3678
3941
  static void advance_str(VALUE str, off_t nr)
3679
3942
  {
3680
3943
  long len = RSTRING_LEN(str);
@@ -3837,15 +4100,13 @@ static VALUE HttpParser_keepalive(VALUE self)
3837
4100
  * parser.next? => true or false
3838
4101
  *
3839
4102
  * Exactly like HttpParser#keepalive?, except it will reset the internal
3840
- * parser state on next parse if it returns true. It will also respect
3841
- * the maximum *keepalive_requests* value and return false if that is
3842
- * reached.
4103
+ * parser state on next parse if it returns true.
3843
4104
  */
3844
4105
  static VALUE HttpParser_next(VALUE self)
3845
4106
  {
3846
4107
  struct http_parser *hp = data_get(self);
3847
4108
 
3848
- if ((HP_FL_ALL(hp, KEEPALIVE)) && (hp->nr_requests-- != 0)) {
4109
+ if (HP_FL_ALL(hp, KEEPALIVE)) {
3849
4110
  HP_FL_SET(hp, TO_CLEAR);
3850
4111
  return Qtrue;
3851
4112
  }
@@ -3877,6 +4138,15 @@ static VALUE HttpParser_env(VALUE self)
3877
4138
  return data_get(self)->env;
3878
4139
  }
3879
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
+
3880
4150
  /**
3881
4151
  * call-seq:
3882
4152
  * parser.filter_body(dst, src) => nil/src
@@ -3955,6 +4225,25 @@ static VALUE HttpParser_filter_body(VALUE self, VALUE dst, VALUE src)
3955
4225
  return src;
3956
4226
  }
3957
4227
 
4228
+ static VALUE HttpParser_rssset(VALUE self, VALUE boolean)
4229
+ {
4230
+ struct http_parser *hp = data_get(self);
4231
+
4232
+ if (RTEST(boolean))
4233
+ HP_FL_SET(hp, RESSTART);
4234
+ else
4235
+ HP_FL_UNSET(hp, RESSTART);
4236
+
4237
+ return boolean; /* ignored by Ruby anyways */
4238
+ }
4239
+
4240
+ static VALUE HttpParser_rssget(VALUE self)
4241
+ {
4242
+ struct http_parser *hp = data_get(self);
4243
+
4244
+ return HP_FL_TEST(hp, RESSTART) ? Qtrue : Qfalse;
4245
+ }
4246
+
3958
4247
  #define SET_GLOBAL(var,str) do { \
3959
4248
  var = find_common_field(str, sizeof(str) - 1); \
3960
4249
  assert(!NIL_P(var) && "missed global field"); \
@@ -3962,9 +4251,9 @@ static VALUE HttpParser_filter_body(VALUE self, VALUE dst, VALUE src)
3962
4251
 
3963
4252
  void Init_unicorn_http(void)
3964
4253
  {
3965
- VALUE mUnicorn, cHttpParser;
4254
+ VALUE mUnicorn;
3966
4255
 
3967
- mUnicorn = rb_const_get(rb_cObject, rb_intern("Unicorn"));
4256
+ mUnicorn = rb_define_module("Unicorn");
3968
4257
  cHttpParser = rb_define_class_under(mUnicorn, "HttpParser", rb_cObject);
3969
4258
  eHttpParserError =
3970
4259
  rb_define_class_under(mUnicorn, "HttpParserError", rb_eIOError);
@@ -3973,12 +4262,11 @@ void Init_unicorn_http(void)
3973
4262
  e414 = rb_define_class_under(mUnicorn, "RequestURITooLongError",
3974
4263
  eHttpParserError);
3975
4264
 
4265
+ id_uminus = rb_intern("-@");
3976
4266
  init_globals();
3977
4267
  rb_define_alloc_func(cHttpParser, HttpParser_alloc);
3978
4268
  rb_define_method(cHttpParser, "initialize", HttpParser_init, 0);
3979
4269
  rb_define_method(cHttpParser, "clear", HttpParser_clear, 0);
3980
- rb_define_method(cHttpParser, "reset", HttpParser_reset, 0);
3981
- rb_define_method(cHttpParser, "dechunk!", HttpParser_dechunk_bang, 0);
3982
4270
  rb_define_method(cHttpParser, "parse", HttpParser_parse, 0);
3983
4271
  rb_define_method(cHttpParser, "add_parse", HttpParser_add_parse, 1);
3984
4272
  rb_define_method(cHttpParser, "headers", HttpParser_headers, 2);
@@ -3991,6 +4279,9 @@ void Init_unicorn_http(void)
3991
4279
  rb_define_method(cHttpParser, "next?", HttpParser_next, 0);
3992
4280
  rb_define_method(cHttpParser, "buf", HttpParser_buf, 0);
3993
4281
  rb_define_method(cHttpParser, "env", HttpParser_env, 0);
4282
+ rb_define_method(cHttpParser, "hijacked!", HttpParser_hijacked_bang, 0);
4283
+ rb_define_method(cHttpParser, "response_start_sent=", HttpParser_rssset, 1);
4284
+ rb_define_method(cHttpParser, "response_start_sent", HttpParser_rssget, 0);
3994
4285
 
3995
4286
  /*
3996
4287
  * The maximum size a single chunk when using chunked transfer encoding.
@@ -4007,14 +4298,6 @@ void Init_unicorn_http(void)
4007
4298
  */
4008
4299
  rb_define_const(cHttpParser, "LENGTH_MAX", OFFT2NUM(UH_OFF_T_MAX));
4009
4300
 
4010
- /* default value for keepalive_requests */
4011
- rb_define_const(cHttpParser, "KEEPALIVE_REQUESTS_DEFAULT",
4012
- ULONG2NUM(keepalive_requests));
4013
-
4014
- rb_define_singleton_method(cHttpParser, "keepalive_requests", ka_req, 0);
4015
- rb_define_singleton_method(cHttpParser, "keepalive_requests=", set_ka_req, 1);
4016
- rb_define_singleton_method(cHttpParser, "trust_x_forwarded=", set_xftrust, 1);
4017
- rb_define_singleton_method(cHttpParser, "trust_x_forwarded?", xftrust, 0);
4018
4301
  rb_define_singleton_method(cHttpParser, "max_header_len=", set_maxhdrlen, 1);
4019
4302
 
4020
4303
  init_common_fields();
@@ -4023,9 +4306,14 @@ void Init_unicorn_http(void)
4023
4306
  SET_GLOBAL(g_http_transfer_encoding, "TRANSFER_ENCODING");
4024
4307
  SET_GLOBAL(g_content_length, "CONTENT_LENGTH");
4025
4308
  SET_GLOBAL(g_http_connection, "CONNECTION");
4026
- id_clear = rb_intern("clear");
4027
4309
  id_set_backtrace = rb_intern("set_backtrace");
4028
- id_response_start_sent = rb_intern("@response_start_sent");
4029
4310
  init_unicorn_httpdate();
4311
+
4312
+ #ifndef HAVE_RB_HASH_CLEAR
4313
+ id_clear = rb_intern("clear");
4314
+ #endif
4315
+ id_is_chunked_p = rb_intern("is_chunked?");
4316
+
4317
+ init_epollexclusive(mUnicorn);
4030
4318
  }
4031
4319
  #undef SET_GLOBAL