unicorn 3.6.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +1 -0
- data/.manifest +13 -0
- data/ChangeLog +783 -1
- data/DESIGN +0 -8
- data/Documentation/GNUmakefile +1 -1
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +2 -2
- data/HACKING +11 -0
- data/KNOWN_ISSUES +2 -2
- data/LATEST +24 -24
- data/Links +53 -0
- data/NEWS +66 -0
- data/PHILOSOPHY +49 -49
- data/Sandbox +13 -4
- data/TODO +0 -2
- data/TUNING +31 -9
- data/bin/unicorn +2 -1
- data/bin/unicorn_rails +2 -1
- data/examples/big_app_gc.rb +2 -33
- data/examples/nginx.conf +17 -4
- data/ext/unicorn_http/ext_help.h +16 -0
- data/ext/unicorn_http/extconf.rb +1 -0
- data/ext/unicorn_http/global_variables.h +9 -3
- data/ext/unicorn_http/unicorn_http.c +357 -259
- data/ext/unicorn_http/unicorn_http.rl +148 -50
- data/lib/unicorn/configurator.rb +36 -8
- data/lib/unicorn/const.rb +5 -3
- data/lib/unicorn/http_request.rb +1 -3
- data/lib/unicorn/http_server.rb +82 -95
- data/lib/unicorn/oob_gc.rb +61 -50
- data/lib/unicorn/socket_helper.rb +23 -8
- data/lib/unicorn/worker.rb +45 -4
- data/lib/unicorn.rb +8 -6
- data/script/isolate_for_tests +4 -2
- data/t/broken-app.ru +12 -0
- data/t/heartbeat-timeout.ru +12 -0
- data/t/oob_gc.ru +21 -0
- data/t/oob_gc_path.ru +21 -0
- data/t/t0001-reload-bad-config.sh +1 -0
- data/t/t0002-parser-error.sh +64 -1
- data/t/t0004-heartbeat-timeout.sh +69 -0
- data/t/t0009-broken-app.sh +56 -0
- data/t/t0019-max_header_len.sh +49 -0
- data/t/t0020-at_exit-handler.sh +49 -0
- data/t/t9001-oob_gc.sh +47 -0
- data/t/t9002-oob_gc-path.sh +75 -0
- data/test/benchmark/stack.ru +8 -0
- data/test/unit/test_droplet.rb +28 -0
- data/test/unit/test_http_parser.rb +60 -4
- data/test/unit/test_http_parser_ng.rb +54 -0
- data/test/unit/test_response.rb +1 -1
- data/test/unit/test_server.rb +1 -1
- data/test/unit/test_signals.rb +1 -1
- data/test/unit/test_socket_helper.rb +8 -0
- data/test/unit/test_upload.rb +1 -1
- data/unicorn.gemspec +3 -2
- metadata +44 -16
@@ -84,6 +84,14 @@ static VALUE xftrust(VALUE self)
|
|
84
84
|
return trust_x_forward;
|
85
85
|
}
|
86
86
|
|
87
|
+
static size_t MAX_HEADER_LEN = 1024 * (80 + 32); /* same as Mongrel */
|
88
|
+
|
89
|
+
/* this is only intended for use with Rainbows! */
|
90
|
+
static VALUE set_maxhdrlen(VALUE self, VALUE len)
|
91
|
+
{
|
92
|
+
return SIZET2NUM(MAX_HEADER_LEN = NUM2SIZET(len));
|
93
|
+
}
|
94
|
+
|
87
95
|
/* keep this small for Rainbows! since every client has one */
|
88
96
|
struct http_parser {
|
89
97
|
int cs; /* Ragel internal state */
|
@@ -108,17 +116,17 @@ struct http_parser {
|
|
108
116
|
} len;
|
109
117
|
};
|
110
118
|
|
111
|
-
static ID id_clear;
|
119
|
+
static ID id_clear, id_set_backtrace;
|
112
120
|
|
113
121
|
static void finalize_header(struct http_parser *hp);
|
114
122
|
|
115
|
-
static void
|
123
|
+
static void parser_raise(VALUE klass, const char *msg)
|
116
124
|
{
|
117
|
-
VALUE exc = rb_exc_new2(
|
125
|
+
VALUE exc = rb_exc_new2(klass, msg);
|
118
126
|
VALUE bt = rb_ary_new();
|
119
127
|
|
120
|
-
|
121
|
-
|
128
|
+
rb_funcall(exc, id_set_backtrace, 1, bt);
|
129
|
+
rb_exc_raise(exc);
|
122
130
|
}
|
123
131
|
|
124
132
|
#define REMAINING (unsigned long)(pe - p)
|
@@ -126,12 +134,27 @@ static void parser_error(const char *msg)
|
|
126
134
|
#define MARK(M,FPC) (hp->M = (FPC) - buffer)
|
127
135
|
#define PTR_TO(F) (buffer + hp->F)
|
128
136
|
#define STR_NEW(M,FPC) rb_str_new(PTR_TO(M), LEN(M, FPC))
|
137
|
+
#define STRIPPED_STR_NEW(M,FPC) stripped_str_new(PTR_TO(M), LEN(M, FPC))
|
129
138
|
|
130
139
|
#define HP_FL_TEST(hp,fl) ((hp)->flags & (UH_FL_##fl))
|
131
140
|
#define HP_FL_SET(hp,fl) ((hp)->flags |= (UH_FL_##fl))
|
132
141
|
#define HP_FL_UNSET(hp,fl) ((hp)->flags &= ~(UH_FL_##fl))
|
133
142
|
#define HP_FL_ALL(hp,fl) (HP_FL_TEST(hp, fl) == (UH_FL_##fl))
|
134
143
|
|
144
|
+
static int is_lws(char c)
|
145
|
+
{
|
146
|
+
return (c == ' ' || c == '\t');
|
147
|
+
}
|
148
|
+
|
149
|
+
static VALUE stripped_str_new(const char *str, long len)
|
150
|
+
{
|
151
|
+
long end;
|
152
|
+
|
153
|
+
for (end = len - 1; end >= 0 && is_lws(str[end]); end--);
|
154
|
+
|
155
|
+
return rb_str_new(str, end + 1);
|
156
|
+
}
|
157
|
+
|
135
158
|
/*
|
136
159
|
* handles values of the "Connection:" header, keepalive is implied
|
137
160
|
* for HTTP/1.1 but needs to be explicitly enabled with HTTP/1.0
|
@@ -188,35 +211,43 @@ http_version(struct http_parser *hp, const char *ptr, size_t len)
|
|
188
211
|
static inline void hp_invalid_if_trailer(struct http_parser *hp)
|
189
212
|
{
|
190
213
|
if (HP_FL_TEST(hp, INTRAILER))
|
191
|
-
|
214
|
+
parser_raise(eHttpParserError, "invalid Trailer");
|
192
215
|
}
|
193
216
|
|
194
217
|
static void write_cont_value(struct http_parser *hp,
|
195
218
|
char *buffer, const char *p)
|
196
219
|
{
|
197
220
|
char *vptr;
|
221
|
+
long end;
|
222
|
+
long len = LEN(mark, p);
|
223
|
+
long cont_len;
|
198
224
|
|
199
225
|
if (hp->cont == Qfalse)
|
200
|
-
|
226
|
+
parser_raise(eHttpParserError, "invalid continuation line");
|
201
227
|
if (NIL_P(hp->cont))
|
202
228
|
return; /* we're ignoring this header (probably Host:) */
|
203
229
|
|
204
230
|
assert(TYPE(hp->cont) == T_STRING && "continuation line is not a string");
|
205
231
|
assert(hp->mark > 0 && "impossible continuation line offset");
|
206
232
|
|
207
|
-
if (
|
233
|
+
if (len == 0)
|
208
234
|
return;
|
209
235
|
|
210
|
-
|
236
|
+
cont_len = RSTRING_LEN(hp->cont);
|
237
|
+
if (cont_len > 0) {
|
211
238
|
--hp->mark;
|
212
|
-
|
239
|
+
len = LEN(mark, p);
|
240
|
+
}
|
213
241
|
vptr = PTR_TO(mark);
|
214
242
|
|
215
|
-
|
243
|
+
/* normalize tab to space */
|
244
|
+
if (cont_len > 0) {
|
216
245
|
assert((' ' == *vptr || '\t' == *vptr) && "invalid leading white space");
|
217
246
|
*vptr = ' ';
|
218
247
|
}
|
219
|
-
|
248
|
+
|
249
|
+
for (end = len - 1; end >= 0 && is_lws(vptr[end]); end--);
|
250
|
+
rb_str_buf_cat(hp->cont, vptr, end + 1);
|
220
251
|
}
|
221
252
|
|
222
253
|
static void write_value(struct http_parser *hp,
|
@@ -227,7 +258,7 @@ static void write_value(struct http_parser *hp,
|
|
227
258
|
VALUE e;
|
228
259
|
|
229
260
|
VALIDATE_MAX_LENGTH(LEN(mark, p), FIELD_VALUE);
|
230
|
-
v = LEN(mark, p) == 0 ? rb_str_buf_new(128) :
|
261
|
+
v = LEN(mark, p) == 0 ? rb_str_buf_new(128) : STRIPPED_STR_NEW(mark, p);
|
231
262
|
if (NIL_P(f)) {
|
232
263
|
const char *field = PTR_TO(start.field);
|
233
264
|
size_t flen = hp->s.field_len;
|
@@ -248,7 +279,7 @@ static void write_value(struct http_parser *hp,
|
|
248
279
|
} else if (f == g_content_length) {
|
249
280
|
hp->len.content = parse_length(RSTRING_PTR(v), RSTRING_LEN(v));
|
250
281
|
if (hp->len.content < 0)
|
251
|
-
|
282
|
+
parser_raise(eHttpParserError, "invalid Content-Length");
|
252
283
|
if (hp->len.content != 0)
|
253
284
|
HP_FL_SET(hp, HASBODY);
|
254
285
|
hp_invalid_if_trailer(hp);
|
@@ -284,12 +315,12 @@ static void write_value(struct http_parser *hp,
|
|
284
315
|
/** Machine **/
|
285
316
|
|
286
317
|
|
287
|
-
#line
|
318
|
+
#line 422 "unicorn_http.rl"
|
288
319
|
|
289
320
|
|
290
321
|
/** Data **/
|
291
322
|
|
292
|
-
#line
|
323
|
+
#line 324 "unicorn_http.c"
|
293
324
|
static const int http_parser_start = 1;
|
294
325
|
static const int http_parser_first_final = 122;
|
295
326
|
static const int http_parser_error = 0;
|
@@ -300,7 +331,7 @@ static const int http_parser_en_Trailers = 114;
|
|
300
331
|
static const int http_parser_en_main = 1;
|
301
332
|
|
302
333
|
|
303
|
-
#line
|
334
|
+
#line 426 "unicorn_http.rl"
|
304
335
|
|
305
336
|
static void http_parser_init(struct http_parser *hp)
|
306
337
|
{
|
@@ -313,12 +344,12 @@ static void http_parser_init(struct http_parser *hp)
|
|
313
344
|
hp->len.content = 0;
|
314
345
|
hp->cont = Qfalse; /* zero on MRI, should be optimized away by above */
|
315
346
|
|
316
|
-
#line
|
347
|
+
#line 348 "unicorn_http.c"
|
317
348
|
{
|
318
349
|
cs = http_parser_start;
|
319
350
|
}
|
320
351
|
|
321
|
-
#line
|
352
|
+
#line 438 "unicorn_http.rl"
|
322
353
|
hp->cs = cs;
|
323
354
|
}
|
324
355
|
|
@@ -346,7 +377,7 @@ http_parser_execute(struct http_parser *hp, char *buffer, size_t len)
|
|
346
377
|
goto skip_chunk_data_hack;
|
347
378
|
}
|
348
379
|
|
349
|
-
#line
|
380
|
+
#line 381 "unicorn_http.c"
|
350
381
|
{
|
351
382
|
if ( p == pe )
|
352
383
|
goto _test_eof;
|
@@ -381,14 +412,14 @@ st0:
|
|
381
412
|
cs = 0;
|
382
413
|
goto _out;
|
383
414
|
tr0:
|
384
|
-
#line
|
415
|
+
#line 318 "unicorn_http.rl"
|
385
416
|
{MARK(mark, p); }
|
386
417
|
goto st2;
|
387
418
|
st2:
|
388
419
|
if ( ++p == pe )
|
389
420
|
goto _test_eof2;
|
390
421
|
case 2:
|
391
|
-
#line
|
422
|
+
#line 423 "unicorn_http.c"
|
392
423
|
switch( (*p) ) {
|
393
424
|
case 32: goto tr3;
|
394
425
|
case 33: goto st49;
|
@@ -414,14 +445,14 @@ case 2:
|
|
414
445
|
goto st49;
|
415
446
|
goto st0;
|
416
447
|
tr3:
|
417
|
-
#line
|
448
|
+
#line 327 "unicorn_http.rl"
|
418
449
|
{ request_method(hp, PTR_TO(mark), LEN(mark, p)); }
|
419
450
|
goto st3;
|
420
451
|
st3:
|
421
452
|
if ( ++p == pe )
|
422
453
|
goto _test_eof3;
|
423
454
|
case 3:
|
424
|
-
#line
|
455
|
+
#line 456 "unicorn_http.c"
|
425
456
|
switch( (*p) ) {
|
426
457
|
case 42: goto tr5;
|
427
458
|
case 47: goto tr6;
|
@@ -430,25 +461,25 @@ case 3:
|
|
430
461
|
}
|
431
462
|
goto st0;
|
432
463
|
tr5:
|
433
|
-
#line
|
464
|
+
#line 318 "unicorn_http.rl"
|
434
465
|
{MARK(mark, p); }
|
435
466
|
goto st4;
|
436
467
|
st4:
|
437
468
|
if ( ++p == pe )
|
438
469
|
goto _test_eof4;
|
439
470
|
case 4:
|
440
|
-
#line
|
471
|
+
#line 472 "unicorn_http.c"
|
441
472
|
switch( (*p) ) {
|
442
473
|
case 32: goto tr8;
|
443
474
|
case 35: goto tr9;
|
444
475
|
}
|
445
476
|
goto st0;
|
446
477
|
tr8:
|
447
|
-
#line
|
478
|
+
#line 332 "unicorn_http.rl"
|
448
479
|
{
|
449
480
|
VALUE str;
|
450
481
|
|
451
|
-
|
482
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
452
483
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
453
484
|
/*
|
454
485
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -462,38 +493,38 @@ tr8:
|
|
462
493
|
}
|
463
494
|
goto st5;
|
464
495
|
tr37:
|
465
|
-
#line
|
496
|
+
#line 318 "unicorn_http.rl"
|
466
497
|
{MARK(mark, p); }
|
467
|
-
#line
|
498
|
+
#line 347 "unicorn_http.rl"
|
468
499
|
{
|
469
|
-
|
500
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
|
470
501
|
rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
|
471
502
|
}
|
472
503
|
goto st5;
|
473
504
|
tr40:
|
474
|
-
#line
|
505
|
+
#line 347 "unicorn_http.rl"
|
475
506
|
{
|
476
|
-
|
507
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
|
477
508
|
rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
|
478
509
|
}
|
479
510
|
goto st5;
|
480
511
|
tr44:
|
481
|
-
#line
|
512
|
+
#line 357 "unicorn_http.rl"
|
482
513
|
{
|
483
514
|
VALUE val;
|
484
515
|
|
485
|
-
|
516
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
|
486
517
|
val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
|
487
518
|
|
488
519
|
/* rack says PATH_INFO must start with "/" or be empty */
|
489
520
|
if (!STR_CSTR_EQ(val, "*"))
|
490
521
|
rb_hash_aset(hp->env, g_path_info, val);
|
491
522
|
}
|
492
|
-
#line
|
523
|
+
#line 332 "unicorn_http.rl"
|
493
524
|
{
|
494
525
|
VALUE str;
|
495
526
|
|
496
|
-
|
527
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
497
528
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
498
529
|
/*
|
499
530
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -507,18 +538,18 @@ tr44:
|
|
507
538
|
}
|
508
539
|
goto st5;
|
509
540
|
tr50:
|
510
|
-
#line
|
541
|
+
#line 351 "unicorn_http.rl"
|
511
542
|
{MARK(start.query, p); }
|
512
|
-
#line
|
543
|
+
#line 352 "unicorn_http.rl"
|
513
544
|
{
|
514
|
-
|
545
|
+
VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
|
515
546
|
rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
|
516
547
|
}
|
517
|
-
#line
|
548
|
+
#line 332 "unicorn_http.rl"
|
518
549
|
{
|
519
550
|
VALUE str;
|
520
551
|
|
521
|
-
|
552
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
522
553
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
523
554
|
/*
|
524
555
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -532,16 +563,16 @@ tr50:
|
|
532
563
|
}
|
533
564
|
goto st5;
|
534
565
|
tr54:
|
535
|
-
#line
|
566
|
+
#line 352 "unicorn_http.rl"
|
536
567
|
{
|
537
|
-
|
568
|
+
VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
|
538
569
|
rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
|
539
570
|
}
|
540
|
-
#line
|
571
|
+
#line 332 "unicorn_http.rl"
|
541
572
|
{
|
542
573
|
VALUE str;
|
543
574
|
|
544
|
-
|
575
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
545
576
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
546
577
|
/*
|
547
578
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -558,19 +589,19 @@ st5:
|
|
558
589
|
if ( ++p == pe )
|
559
590
|
goto _test_eof5;
|
560
591
|
case 5:
|
561
|
-
#line
|
592
|
+
#line 593 "unicorn_http.c"
|
562
593
|
if ( (*p) == 72 )
|
563
594
|
goto tr10;
|
564
595
|
goto st0;
|
565
596
|
tr10:
|
566
|
-
#line
|
597
|
+
#line 318 "unicorn_http.rl"
|
567
598
|
{MARK(mark, p); }
|
568
599
|
goto st6;
|
569
600
|
st6:
|
570
601
|
if ( ++p == pe )
|
571
602
|
goto _test_eof6;
|
572
603
|
case 6:
|
573
|
-
#line
|
604
|
+
#line 605 "unicorn_http.c"
|
574
605
|
if ( (*p) == 84 )
|
575
606
|
goto st7;
|
576
607
|
goto st0;
|
@@ -628,34 +659,34 @@ case 13:
|
|
628
659
|
goto st13;
|
629
660
|
goto st0;
|
630
661
|
tr18:
|
631
|
-
#line
|
662
|
+
#line 356 "unicorn_http.rl"
|
632
663
|
{ http_version(hp, PTR_TO(mark), LEN(mark, p)); }
|
633
664
|
goto st14;
|
634
665
|
tr25:
|
635
|
-
#line
|
666
|
+
#line 324 "unicorn_http.rl"
|
636
667
|
{ MARK(mark, p); }
|
637
|
-
#line
|
668
|
+
#line 326 "unicorn_http.rl"
|
638
669
|
{ write_cont_value(hp, buffer, p); }
|
639
670
|
goto st14;
|
640
671
|
tr27:
|
641
|
-
#line
|
672
|
+
#line 326 "unicorn_http.rl"
|
642
673
|
{ write_cont_value(hp, buffer, p); }
|
643
674
|
goto st14;
|
644
675
|
tr33:
|
645
|
-
#line
|
676
|
+
#line 324 "unicorn_http.rl"
|
646
677
|
{ MARK(mark, p); }
|
647
|
-
#line
|
678
|
+
#line 325 "unicorn_http.rl"
|
648
679
|
{ write_value(hp, buffer, p); }
|
649
680
|
goto st14;
|
650
681
|
tr35:
|
651
|
-
#line
|
682
|
+
#line 325 "unicorn_http.rl"
|
652
683
|
{ write_value(hp, buffer, p); }
|
653
684
|
goto st14;
|
654
685
|
st14:
|
655
686
|
if ( ++p == pe )
|
656
687
|
goto _test_eof14;
|
657
688
|
case 14:
|
658
|
-
#line
|
689
|
+
#line 690 "unicorn_http.c"
|
659
690
|
if ( (*p) == 10 )
|
660
691
|
goto st15;
|
661
692
|
goto st0;
|
@@ -690,14 +721,14 @@ case 15:
|
|
690
721
|
goto tr22;
|
691
722
|
goto st0;
|
692
723
|
tr24:
|
693
|
-
#line
|
724
|
+
#line 324 "unicorn_http.rl"
|
694
725
|
{ MARK(mark, p); }
|
695
726
|
goto st16;
|
696
727
|
st16:
|
697
728
|
if ( ++p == pe )
|
698
729
|
goto _test_eof16;
|
699
730
|
case 16:
|
700
|
-
#line
|
731
|
+
#line 732 "unicorn_http.c"
|
701
732
|
switch( (*p) ) {
|
702
733
|
case 9: goto tr24;
|
703
734
|
case 13: goto tr25;
|
@@ -705,23 +736,23 @@ case 16:
|
|
705
736
|
}
|
706
737
|
goto tr23;
|
707
738
|
tr23:
|
708
|
-
#line
|
739
|
+
#line 324 "unicorn_http.rl"
|
709
740
|
{ MARK(mark, p); }
|
710
741
|
goto st17;
|
711
742
|
st17:
|
712
743
|
if ( ++p == pe )
|
713
744
|
goto _test_eof17;
|
714
745
|
case 17:
|
715
|
-
#line
|
746
|
+
#line 747 "unicorn_http.c"
|
716
747
|
if ( (*p) == 13 )
|
717
748
|
goto tr27;
|
718
749
|
goto st17;
|
719
750
|
tr99:
|
720
|
-
#line
|
751
|
+
#line 332 "unicorn_http.rl"
|
721
752
|
{
|
722
753
|
VALUE str;
|
723
754
|
|
724
|
-
|
755
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
725
756
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
726
757
|
/*
|
727
758
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -735,38 +766,38 @@ tr99:
|
|
735
766
|
}
|
736
767
|
goto st18;
|
737
768
|
tr102:
|
738
|
-
#line
|
769
|
+
#line 318 "unicorn_http.rl"
|
739
770
|
{MARK(mark, p); }
|
740
|
-
#line
|
771
|
+
#line 347 "unicorn_http.rl"
|
741
772
|
{
|
742
|
-
|
773
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
|
743
774
|
rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
|
744
775
|
}
|
745
776
|
goto st18;
|
746
777
|
tr105:
|
747
|
-
#line
|
778
|
+
#line 347 "unicorn_http.rl"
|
748
779
|
{
|
749
|
-
|
780
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
|
750
781
|
rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
|
751
782
|
}
|
752
783
|
goto st18;
|
753
784
|
tr109:
|
754
|
-
#line
|
785
|
+
#line 357 "unicorn_http.rl"
|
755
786
|
{
|
756
787
|
VALUE val;
|
757
788
|
|
758
|
-
|
789
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
|
759
790
|
val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
|
760
791
|
|
761
792
|
/* rack says PATH_INFO must start with "/" or be empty */
|
762
793
|
if (!STR_CSTR_EQ(val, "*"))
|
763
794
|
rb_hash_aset(hp->env, g_path_info, val);
|
764
795
|
}
|
765
|
-
#line
|
796
|
+
#line 332 "unicorn_http.rl"
|
766
797
|
{
|
767
798
|
VALUE str;
|
768
799
|
|
769
|
-
|
800
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
770
801
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
771
802
|
/*
|
772
803
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -780,18 +811,18 @@ tr109:
|
|
780
811
|
}
|
781
812
|
goto st18;
|
782
813
|
tr115:
|
783
|
-
#line
|
814
|
+
#line 351 "unicorn_http.rl"
|
784
815
|
{MARK(start.query, p); }
|
785
|
-
#line
|
816
|
+
#line 352 "unicorn_http.rl"
|
786
817
|
{
|
787
|
-
|
818
|
+
VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
|
788
819
|
rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
|
789
820
|
}
|
790
|
-
#line
|
821
|
+
#line 332 "unicorn_http.rl"
|
791
822
|
{
|
792
823
|
VALUE str;
|
793
824
|
|
794
|
-
|
825
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
795
826
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
796
827
|
/*
|
797
828
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -805,16 +836,16 @@ tr115:
|
|
805
836
|
}
|
806
837
|
goto st18;
|
807
838
|
tr119:
|
808
|
-
#line
|
839
|
+
#line 352 "unicorn_http.rl"
|
809
840
|
{
|
810
|
-
|
841
|
+
VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
|
811
842
|
rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
|
812
843
|
}
|
813
|
-
#line
|
844
|
+
#line 332 "unicorn_http.rl"
|
814
845
|
{
|
815
846
|
VALUE str;
|
816
847
|
|
817
|
-
|
848
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
818
849
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
819
850
|
/*
|
820
851
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -831,12 +862,12 @@ st18:
|
|
831
862
|
if ( ++p == pe )
|
832
863
|
goto _test_eof18;
|
833
864
|
case 18:
|
834
|
-
#line
|
865
|
+
#line 866 "unicorn_http.c"
|
835
866
|
if ( (*p) == 10 )
|
836
867
|
goto tr28;
|
837
868
|
goto st0;
|
838
869
|
tr28:
|
839
|
-
#line
|
870
|
+
#line 372 "unicorn_http.rl"
|
840
871
|
{
|
841
872
|
finalize_header(hp);
|
842
873
|
|
@@ -860,23 +891,23 @@ st122:
|
|
860
891
|
if ( ++p == pe )
|
861
892
|
goto _test_eof122;
|
862
893
|
case 122:
|
863
|
-
#line
|
894
|
+
#line 895 "unicorn_http.c"
|
864
895
|
goto st0;
|
865
896
|
tr22:
|
866
|
-
#line
|
897
|
+
#line 320 "unicorn_http.rl"
|
867
898
|
{ MARK(start.field, p); }
|
868
|
-
#line
|
899
|
+
#line 321 "unicorn_http.rl"
|
869
900
|
{ snake_upcase_char(deconst(p)); }
|
870
901
|
goto st19;
|
871
902
|
tr29:
|
872
|
-
#line
|
903
|
+
#line 321 "unicorn_http.rl"
|
873
904
|
{ snake_upcase_char(deconst(p)); }
|
874
905
|
goto st19;
|
875
906
|
st19:
|
876
907
|
if ( ++p == pe )
|
877
908
|
goto _test_eof19;
|
878
909
|
case 19:
|
879
|
-
#line
|
910
|
+
#line 911 "unicorn_http.c"
|
880
911
|
switch( (*p) ) {
|
881
912
|
case 33: goto tr29;
|
882
913
|
case 58: goto tr30;
|
@@ -902,18 +933,18 @@ case 19:
|
|
902
933
|
goto tr29;
|
903
934
|
goto st0;
|
904
935
|
tr32:
|
905
|
-
#line
|
936
|
+
#line 324 "unicorn_http.rl"
|
906
937
|
{ MARK(mark, p); }
|
907
938
|
goto st20;
|
908
939
|
tr30:
|
909
|
-
#line
|
940
|
+
#line 323 "unicorn_http.rl"
|
910
941
|
{ hp->s.field_len = LEN(start.field, p); }
|
911
942
|
goto st20;
|
912
943
|
st20:
|
913
944
|
if ( ++p == pe )
|
914
945
|
goto _test_eof20;
|
915
946
|
case 20:
|
916
|
-
#line
|
947
|
+
#line 948 "unicorn_http.c"
|
917
948
|
switch( (*p) ) {
|
918
949
|
case 9: goto tr32;
|
919
950
|
case 13: goto tr33;
|
@@ -921,23 +952,23 @@ case 20:
|
|
921
952
|
}
|
922
953
|
goto tr31;
|
923
954
|
tr31:
|
924
|
-
#line
|
955
|
+
#line 324 "unicorn_http.rl"
|
925
956
|
{ MARK(mark, p); }
|
926
957
|
goto st21;
|
927
958
|
st21:
|
928
959
|
if ( ++p == pe )
|
929
960
|
goto _test_eof21;
|
930
961
|
case 21:
|
931
|
-
#line
|
962
|
+
#line 963 "unicorn_http.c"
|
932
963
|
if ( (*p) == 13 )
|
933
964
|
goto tr35;
|
934
965
|
goto st21;
|
935
966
|
tr9:
|
936
|
-
#line
|
967
|
+
#line 332 "unicorn_http.rl"
|
937
968
|
{
|
938
969
|
VALUE str;
|
939
970
|
|
940
|
-
|
971
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
941
972
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
942
973
|
/*
|
943
974
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -951,22 +982,22 @@ tr9:
|
|
951
982
|
}
|
952
983
|
goto st22;
|
953
984
|
tr45:
|
954
|
-
#line
|
985
|
+
#line 357 "unicorn_http.rl"
|
955
986
|
{
|
956
987
|
VALUE val;
|
957
988
|
|
958
|
-
|
989
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
|
959
990
|
val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
|
960
991
|
|
961
992
|
/* rack says PATH_INFO must start with "/" or be empty */
|
962
993
|
if (!STR_CSTR_EQ(val, "*"))
|
963
994
|
rb_hash_aset(hp->env, g_path_info, val);
|
964
995
|
}
|
965
|
-
#line
|
996
|
+
#line 332 "unicorn_http.rl"
|
966
997
|
{
|
967
998
|
VALUE str;
|
968
999
|
|
969
|
-
|
1000
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
970
1001
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
971
1002
|
/*
|
972
1003
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -980,18 +1011,18 @@ tr45:
|
|
980
1011
|
}
|
981
1012
|
goto st22;
|
982
1013
|
tr51:
|
983
|
-
#line
|
1014
|
+
#line 351 "unicorn_http.rl"
|
984
1015
|
{MARK(start.query, p); }
|
985
|
-
#line
|
1016
|
+
#line 352 "unicorn_http.rl"
|
986
1017
|
{
|
987
|
-
|
1018
|
+
VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
|
988
1019
|
rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
|
989
1020
|
}
|
990
|
-
#line
|
1021
|
+
#line 332 "unicorn_http.rl"
|
991
1022
|
{
|
992
1023
|
VALUE str;
|
993
1024
|
|
994
|
-
|
1025
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
995
1026
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
996
1027
|
/*
|
997
1028
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -1005,16 +1036,16 @@ tr51:
|
|
1005
1036
|
}
|
1006
1037
|
goto st22;
|
1007
1038
|
tr55:
|
1008
|
-
#line
|
1039
|
+
#line 352 "unicorn_http.rl"
|
1009
1040
|
{
|
1010
|
-
|
1041
|
+
VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
|
1011
1042
|
rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
|
1012
1043
|
}
|
1013
|
-
#line
|
1044
|
+
#line 332 "unicorn_http.rl"
|
1014
1045
|
{
|
1015
1046
|
VALUE str;
|
1016
1047
|
|
1017
|
-
|
1048
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
1018
1049
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
1019
1050
|
/*
|
1020
1051
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -1031,7 +1062,7 @@ st22:
|
|
1031
1062
|
if ( ++p == pe )
|
1032
1063
|
goto _test_eof22;
|
1033
1064
|
case 22:
|
1034
|
-
#line
|
1065
|
+
#line 1066 "unicorn_http.c"
|
1035
1066
|
switch( (*p) ) {
|
1036
1067
|
case 32: goto tr37;
|
1037
1068
|
case 35: goto st0;
|
@@ -1042,14 +1073,14 @@ case 22:
|
|
1042
1073
|
goto st0;
|
1043
1074
|
goto tr36;
|
1044
1075
|
tr36:
|
1045
|
-
#line
|
1076
|
+
#line 318 "unicorn_http.rl"
|
1046
1077
|
{MARK(mark, p); }
|
1047
1078
|
goto st23;
|
1048
1079
|
st23:
|
1049
1080
|
if ( ++p == pe )
|
1050
1081
|
goto _test_eof23;
|
1051
1082
|
case 23:
|
1052
|
-
#line
|
1083
|
+
#line 1084 "unicorn_http.c"
|
1053
1084
|
switch( (*p) ) {
|
1054
1085
|
case 32: goto tr40;
|
1055
1086
|
case 35: goto st0;
|
@@ -1060,14 +1091,14 @@ case 23:
|
|
1060
1091
|
goto st0;
|
1061
1092
|
goto st23;
|
1062
1093
|
tr38:
|
1063
|
-
#line
|
1094
|
+
#line 318 "unicorn_http.rl"
|
1064
1095
|
{MARK(mark, p); }
|
1065
1096
|
goto st24;
|
1066
1097
|
st24:
|
1067
1098
|
if ( ++p == pe )
|
1068
1099
|
goto _test_eof24;
|
1069
1100
|
case 24:
|
1070
|
-
#line
|
1101
|
+
#line 1102 "unicorn_http.c"
|
1071
1102
|
if ( (*p) < 65 ) {
|
1072
1103
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1073
1104
|
goto st25;
|
@@ -1091,20 +1122,20 @@ case 25:
|
|
1091
1122
|
goto st23;
|
1092
1123
|
goto st0;
|
1093
1124
|
tr6:
|
1094
|
-
#line
|
1125
|
+
#line 318 "unicorn_http.rl"
|
1095
1126
|
{MARK(mark, p); }
|
1096
1127
|
goto st26;
|
1097
1128
|
tr71:
|
1098
|
-
#line
|
1129
|
+
#line 331 "unicorn_http.rl"
|
1099
1130
|
{ rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
|
1100
|
-
#line
|
1131
|
+
#line 318 "unicorn_http.rl"
|
1101
1132
|
{MARK(mark, p); }
|
1102
1133
|
goto st26;
|
1103
1134
|
st26:
|
1104
1135
|
if ( ++p == pe )
|
1105
1136
|
goto _test_eof26;
|
1106
1137
|
case 26:
|
1107
|
-
#line
|
1138
|
+
#line 1139 "unicorn_http.c"
|
1108
1139
|
switch( (*p) ) {
|
1109
1140
|
case 32: goto tr44;
|
1110
1141
|
case 35: goto tr45;
|
@@ -1142,11 +1173,11 @@ case 28:
|
|
1142
1173
|
goto st26;
|
1143
1174
|
goto st0;
|
1144
1175
|
tr47:
|
1145
|
-
#line
|
1176
|
+
#line 357 "unicorn_http.rl"
|
1146
1177
|
{
|
1147
1178
|
VALUE val;
|
1148
1179
|
|
1149
|
-
|
1180
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
|
1150
1181
|
val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
|
1151
1182
|
|
1152
1183
|
/* rack says PATH_INFO must start with "/" or be empty */
|
@@ -1158,7 +1189,7 @@ st29:
|
|
1158
1189
|
if ( ++p == pe )
|
1159
1190
|
goto _test_eof29;
|
1160
1191
|
case 29:
|
1161
|
-
#line
|
1192
|
+
#line 1193 "unicorn_http.c"
|
1162
1193
|
switch( (*p) ) {
|
1163
1194
|
case 32: goto tr50;
|
1164
1195
|
case 35: goto tr51;
|
@@ -1169,14 +1200,14 @@ case 29:
|
|
1169
1200
|
goto st0;
|
1170
1201
|
goto tr49;
|
1171
1202
|
tr49:
|
1172
|
-
#line
|
1203
|
+
#line 351 "unicorn_http.rl"
|
1173
1204
|
{MARK(start.query, p); }
|
1174
1205
|
goto st30;
|
1175
1206
|
st30:
|
1176
1207
|
if ( ++p == pe )
|
1177
1208
|
goto _test_eof30;
|
1178
1209
|
case 30:
|
1179
|
-
#line
|
1210
|
+
#line 1211 "unicorn_http.c"
|
1180
1211
|
switch( (*p) ) {
|
1181
1212
|
case 32: goto tr54;
|
1182
1213
|
case 35: goto tr55;
|
@@ -1187,14 +1218,14 @@ case 30:
|
|
1187
1218
|
goto st0;
|
1188
1219
|
goto st30;
|
1189
1220
|
tr52:
|
1190
|
-
#line
|
1221
|
+
#line 351 "unicorn_http.rl"
|
1191
1222
|
{MARK(start.query, p); }
|
1192
1223
|
goto st31;
|
1193
1224
|
st31:
|
1194
1225
|
if ( ++p == pe )
|
1195
1226
|
goto _test_eof31;
|
1196
1227
|
case 31:
|
1197
|
-
#line
|
1228
|
+
#line 1229 "unicorn_http.c"
|
1198
1229
|
if ( (*p) < 65 ) {
|
1199
1230
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1200
1231
|
goto st32;
|
@@ -1218,58 +1249,58 @@ case 32:
|
|
1218
1249
|
goto st30;
|
1219
1250
|
goto st0;
|
1220
1251
|
tr7:
|
1221
|
-
#line
|
1252
|
+
#line 318 "unicorn_http.rl"
|
1222
1253
|
{MARK(mark, p); }
|
1223
|
-
#line
|
1254
|
+
#line 322 "unicorn_http.rl"
|
1224
1255
|
{ downcase_char(deconst(p)); }
|
1225
1256
|
goto st33;
|
1226
1257
|
st33:
|
1227
1258
|
if ( ++p == pe )
|
1228
1259
|
goto _test_eof33;
|
1229
1260
|
case 33:
|
1230
|
-
#line
|
1261
|
+
#line 1262 "unicorn_http.c"
|
1231
1262
|
switch( (*p) ) {
|
1232
1263
|
case 84: goto tr58;
|
1233
1264
|
case 116: goto tr58;
|
1234
1265
|
}
|
1235
1266
|
goto st0;
|
1236
1267
|
tr58:
|
1237
|
-
#line
|
1268
|
+
#line 322 "unicorn_http.rl"
|
1238
1269
|
{ downcase_char(deconst(p)); }
|
1239
1270
|
goto st34;
|
1240
1271
|
st34:
|
1241
1272
|
if ( ++p == pe )
|
1242
1273
|
goto _test_eof34;
|
1243
1274
|
case 34:
|
1244
|
-
#line
|
1275
|
+
#line 1276 "unicorn_http.c"
|
1245
1276
|
switch( (*p) ) {
|
1246
1277
|
case 84: goto tr59;
|
1247
1278
|
case 116: goto tr59;
|
1248
1279
|
}
|
1249
1280
|
goto st0;
|
1250
1281
|
tr59:
|
1251
|
-
#line
|
1282
|
+
#line 322 "unicorn_http.rl"
|
1252
1283
|
{ downcase_char(deconst(p)); }
|
1253
1284
|
goto st35;
|
1254
1285
|
st35:
|
1255
1286
|
if ( ++p == pe )
|
1256
1287
|
goto _test_eof35;
|
1257
1288
|
case 35:
|
1258
|
-
#line
|
1289
|
+
#line 1290 "unicorn_http.c"
|
1259
1290
|
switch( (*p) ) {
|
1260
1291
|
case 80: goto tr60;
|
1261
1292
|
case 112: goto tr60;
|
1262
1293
|
}
|
1263
1294
|
goto st0;
|
1264
1295
|
tr60:
|
1265
|
-
#line
|
1296
|
+
#line 322 "unicorn_http.rl"
|
1266
1297
|
{ downcase_char(deconst(p)); }
|
1267
1298
|
goto st36;
|
1268
1299
|
st36:
|
1269
1300
|
if ( ++p == pe )
|
1270
1301
|
goto _test_eof36;
|
1271
1302
|
case 36:
|
1272
|
-
#line
|
1303
|
+
#line 1304 "unicorn_http.c"
|
1273
1304
|
switch( (*p) ) {
|
1274
1305
|
case 58: goto tr61;
|
1275
1306
|
case 83: goto tr62;
|
@@ -1277,7 +1308,7 @@ case 36:
|
|
1277
1308
|
}
|
1278
1309
|
goto st0;
|
1279
1310
|
tr61:
|
1280
|
-
#line
|
1311
|
+
#line 328 "unicorn_http.rl"
|
1281
1312
|
{
|
1282
1313
|
rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
|
1283
1314
|
}
|
@@ -1286,7 +1317,7 @@ st37:
|
|
1286
1317
|
if ( ++p == pe )
|
1287
1318
|
goto _test_eof37;
|
1288
1319
|
case 37:
|
1289
|
-
#line
|
1320
|
+
#line 1321 "unicorn_http.c"
|
1290
1321
|
if ( (*p) == 47 )
|
1291
1322
|
goto st38;
|
1292
1323
|
goto st0;
|
@@ -1374,14 +1405,14 @@ case 42:
|
|
1374
1405
|
goto st40;
|
1375
1406
|
goto st0;
|
1376
1407
|
tr67:
|
1377
|
-
#line
|
1408
|
+
#line 318 "unicorn_http.rl"
|
1378
1409
|
{MARK(mark, p); }
|
1379
1410
|
goto st43;
|
1380
1411
|
st43:
|
1381
1412
|
if ( ++p == pe )
|
1382
1413
|
goto _test_eof43;
|
1383
1414
|
case 43:
|
1384
|
-
#line
|
1415
|
+
#line 1416 "unicorn_http.c"
|
1385
1416
|
switch( (*p) ) {
|
1386
1417
|
case 37: goto st41;
|
1387
1418
|
case 47: goto tr71;
|
@@ -1433,14 +1464,14 @@ case 44:
|
|
1433
1464
|
goto st0;
|
1434
1465
|
goto st40;
|
1435
1466
|
tr68:
|
1436
|
-
#line
|
1467
|
+
#line 318 "unicorn_http.rl"
|
1437
1468
|
{MARK(mark, p); }
|
1438
1469
|
goto st45;
|
1439
1470
|
st45:
|
1440
1471
|
if ( ++p == pe )
|
1441
1472
|
goto _test_eof45;
|
1442
1473
|
case 45:
|
1443
|
-
#line
|
1474
|
+
#line 1475 "unicorn_http.c"
|
1444
1475
|
switch( (*p) ) {
|
1445
1476
|
case 37: goto st41;
|
1446
1477
|
case 47: goto st0;
|
@@ -1518,14 +1549,14 @@ case 47:
|
|
1518
1549
|
goto st0;
|
1519
1550
|
goto st40;
|
1520
1551
|
tr62:
|
1521
|
-
#line
|
1552
|
+
#line 322 "unicorn_http.rl"
|
1522
1553
|
{ downcase_char(deconst(p)); }
|
1523
1554
|
goto st48;
|
1524
1555
|
st48:
|
1525
1556
|
if ( ++p == pe )
|
1526
1557
|
goto _test_eof48;
|
1527
1558
|
case 48:
|
1528
|
-
#line
|
1559
|
+
#line 1560 "unicorn_http.c"
|
1529
1560
|
if ( (*p) == 58 )
|
1530
1561
|
goto tr61;
|
1531
1562
|
goto st0;
|
@@ -2041,14 +2072,14 @@ case 67:
|
|
2041
2072
|
goto tr3;
|
2042
2073
|
goto st0;
|
2043
2074
|
tr2:
|
2044
|
-
#line
|
2075
|
+
#line 318 "unicorn_http.rl"
|
2045
2076
|
{MARK(mark, p); }
|
2046
2077
|
goto st68;
|
2047
2078
|
st68:
|
2048
2079
|
if ( ++p == pe )
|
2049
2080
|
goto _test_eof68;
|
2050
2081
|
case 68:
|
2051
|
-
#line
|
2082
|
+
#line 2083 "unicorn_http.c"
|
2052
2083
|
switch( (*p) ) {
|
2053
2084
|
case 32: goto tr3;
|
2054
2085
|
case 33: goto st49;
|
@@ -2132,14 +2163,14 @@ case 70:
|
|
2132
2163
|
goto st51;
|
2133
2164
|
goto st0;
|
2134
2165
|
tr95:
|
2135
|
-
#line
|
2166
|
+
#line 327 "unicorn_http.rl"
|
2136
2167
|
{ request_method(hp, PTR_TO(mark), LEN(mark, p)); }
|
2137
2168
|
goto st71;
|
2138
2169
|
st71:
|
2139
2170
|
if ( ++p == pe )
|
2140
2171
|
goto _test_eof71;
|
2141
2172
|
case 71:
|
2142
|
-
#line
|
2173
|
+
#line 2174 "unicorn_http.c"
|
2143
2174
|
switch( (*p) ) {
|
2144
2175
|
case 42: goto tr96;
|
2145
2176
|
case 47: goto tr97;
|
@@ -2148,14 +2179,14 @@ case 71:
|
|
2148
2179
|
}
|
2149
2180
|
goto st0;
|
2150
2181
|
tr96:
|
2151
|
-
#line
|
2182
|
+
#line 318 "unicorn_http.rl"
|
2152
2183
|
{MARK(mark, p); }
|
2153
2184
|
goto st72;
|
2154
2185
|
st72:
|
2155
2186
|
if ( ++p == pe )
|
2156
2187
|
goto _test_eof72;
|
2157
2188
|
case 72:
|
2158
|
-
#line
|
2189
|
+
#line 2190 "unicorn_http.c"
|
2159
2190
|
switch( (*p) ) {
|
2160
2191
|
case 13: goto tr99;
|
2161
2192
|
case 32: goto tr8;
|
@@ -2163,11 +2194,11 @@ case 72:
|
|
2163
2194
|
}
|
2164
2195
|
goto st0;
|
2165
2196
|
tr100:
|
2166
|
-
#line
|
2197
|
+
#line 332 "unicorn_http.rl"
|
2167
2198
|
{
|
2168
2199
|
VALUE str;
|
2169
2200
|
|
2170
|
-
|
2201
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
2171
2202
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
2172
2203
|
/*
|
2173
2204
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -2181,22 +2212,22 @@ tr100:
|
|
2181
2212
|
}
|
2182
2213
|
goto st73;
|
2183
2214
|
tr110:
|
2184
|
-
#line
|
2215
|
+
#line 357 "unicorn_http.rl"
|
2185
2216
|
{
|
2186
2217
|
VALUE val;
|
2187
2218
|
|
2188
|
-
|
2219
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
|
2189
2220
|
val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
|
2190
2221
|
|
2191
2222
|
/* rack says PATH_INFO must start with "/" or be empty */
|
2192
2223
|
if (!STR_CSTR_EQ(val, "*"))
|
2193
2224
|
rb_hash_aset(hp->env, g_path_info, val);
|
2194
2225
|
}
|
2195
|
-
#line
|
2226
|
+
#line 332 "unicorn_http.rl"
|
2196
2227
|
{
|
2197
2228
|
VALUE str;
|
2198
2229
|
|
2199
|
-
|
2230
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
2200
2231
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
2201
2232
|
/*
|
2202
2233
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -2210,18 +2241,18 @@ tr110:
|
|
2210
2241
|
}
|
2211
2242
|
goto st73;
|
2212
2243
|
tr116:
|
2213
|
-
#line
|
2244
|
+
#line 351 "unicorn_http.rl"
|
2214
2245
|
{MARK(start.query, p); }
|
2215
|
-
#line
|
2246
|
+
#line 352 "unicorn_http.rl"
|
2216
2247
|
{
|
2217
|
-
|
2248
|
+
VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
|
2218
2249
|
rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
|
2219
2250
|
}
|
2220
|
-
#line
|
2251
|
+
#line 332 "unicorn_http.rl"
|
2221
2252
|
{
|
2222
2253
|
VALUE str;
|
2223
2254
|
|
2224
|
-
|
2255
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
2225
2256
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
2226
2257
|
/*
|
2227
2258
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -2235,16 +2266,16 @@ tr116:
|
|
2235
2266
|
}
|
2236
2267
|
goto st73;
|
2237
2268
|
tr120:
|
2238
|
-
#line
|
2269
|
+
#line 352 "unicorn_http.rl"
|
2239
2270
|
{
|
2240
|
-
|
2271
|
+
VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
|
2241
2272
|
rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
|
2242
2273
|
}
|
2243
|
-
#line
|
2274
|
+
#line 332 "unicorn_http.rl"
|
2244
2275
|
{
|
2245
2276
|
VALUE str;
|
2246
2277
|
|
2247
|
-
|
2278
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
|
2248
2279
|
str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
|
2249
2280
|
/*
|
2250
2281
|
* "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
|
@@ -2261,7 +2292,7 @@ st73:
|
|
2261
2292
|
if ( ++p == pe )
|
2262
2293
|
goto _test_eof73;
|
2263
2294
|
case 73:
|
2264
|
-
#line
|
2295
|
+
#line 2296 "unicorn_http.c"
|
2265
2296
|
switch( (*p) ) {
|
2266
2297
|
case 13: goto tr102;
|
2267
2298
|
case 32: goto tr37;
|
@@ -2273,14 +2304,14 @@ case 73:
|
|
2273
2304
|
goto st0;
|
2274
2305
|
goto tr101;
|
2275
2306
|
tr101:
|
2276
|
-
#line
|
2307
|
+
#line 318 "unicorn_http.rl"
|
2277
2308
|
{MARK(mark, p); }
|
2278
2309
|
goto st74;
|
2279
2310
|
st74:
|
2280
2311
|
if ( ++p == pe )
|
2281
2312
|
goto _test_eof74;
|
2282
2313
|
case 74:
|
2283
|
-
#line
|
2314
|
+
#line 2315 "unicorn_http.c"
|
2284
2315
|
switch( (*p) ) {
|
2285
2316
|
case 13: goto tr105;
|
2286
2317
|
case 32: goto tr40;
|
@@ -2292,14 +2323,14 @@ case 74:
|
|
2292
2323
|
goto st0;
|
2293
2324
|
goto st74;
|
2294
2325
|
tr103:
|
2295
|
-
#line
|
2326
|
+
#line 318 "unicorn_http.rl"
|
2296
2327
|
{MARK(mark, p); }
|
2297
2328
|
goto st75;
|
2298
2329
|
st75:
|
2299
2330
|
if ( ++p == pe )
|
2300
2331
|
goto _test_eof75;
|
2301
2332
|
case 75:
|
2302
|
-
#line
|
2333
|
+
#line 2334 "unicorn_http.c"
|
2303
2334
|
if ( (*p) < 65 ) {
|
2304
2335
|
if ( 48 <= (*p) && (*p) <= 57 )
|
2305
2336
|
goto st76;
|
@@ -2323,20 +2354,20 @@ case 76:
|
|
2323
2354
|
goto st74;
|
2324
2355
|
goto st0;
|
2325
2356
|
tr97:
|
2326
|
-
#line
|
2357
|
+
#line 318 "unicorn_http.rl"
|
2327
2358
|
{MARK(mark, p); }
|
2328
2359
|
goto st77;
|
2329
2360
|
tr136:
|
2330
|
-
#line
|
2361
|
+
#line 331 "unicorn_http.rl"
|
2331
2362
|
{ rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
|
2332
|
-
#line
|
2363
|
+
#line 318 "unicorn_http.rl"
|
2333
2364
|
{MARK(mark, p); }
|
2334
2365
|
goto st77;
|
2335
2366
|
st77:
|
2336
2367
|
if ( ++p == pe )
|
2337
2368
|
goto _test_eof77;
|
2338
2369
|
case 77:
|
2339
|
-
#line
|
2370
|
+
#line 2371 "unicorn_http.c"
|
2340
2371
|
switch( (*p) ) {
|
2341
2372
|
case 13: goto tr109;
|
2342
2373
|
case 32: goto tr44;
|
@@ -2375,11 +2406,11 @@ case 79:
|
|
2375
2406
|
goto st77;
|
2376
2407
|
goto st0;
|
2377
2408
|
tr112:
|
2378
|
-
#line
|
2409
|
+
#line 357 "unicorn_http.rl"
|
2379
2410
|
{
|
2380
2411
|
VALUE val;
|
2381
2412
|
|
2382
|
-
|
2413
|
+
VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
|
2383
2414
|
val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
|
2384
2415
|
|
2385
2416
|
/* rack says PATH_INFO must start with "/" or be empty */
|
@@ -2391,7 +2422,7 @@ st80:
|
|
2391
2422
|
if ( ++p == pe )
|
2392
2423
|
goto _test_eof80;
|
2393
2424
|
case 80:
|
2394
|
-
#line
|
2425
|
+
#line 2426 "unicorn_http.c"
|
2395
2426
|
switch( (*p) ) {
|
2396
2427
|
case 13: goto tr115;
|
2397
2428
|
case 32: goto tr50;
|
@@ -2403,14 +2434,14 @@ case 80:
|
|
2403
2434
|
goto st0;
|
2404
2435
|
goto tr114;
|
2405
2436
|
tr114:
|
2406
|
-
#line
|
2437
|
+
#line 351 "unicorn_http.rl"
|
2407
2438
|
{MARK(start.query, p); }
|
2408
2439
|
goto st81;
|
2409
2440
|
st81:
|
2410
2441
|
if ( ++p == pe )
|
2411
2442
|
goto _test_eof81;
|
2412
2443
|
case 81:
|
2413
|
-
#line
|
2444
|
+
#line 2445 "unicorn_http.c"
|
2414
2445
|
switch( (*p) ) {
|
2415
2446
|
case 13: goto tr119;
|
2416
2447
|
case 32: goto tr54;
|
@@ -2422,14 +2453,14 @@ case 81:
|
|
2422
2453
|
goto st0;
|
2423
2454
|
goto st81;
|
2424
2455
|
tr117:
|
2425
|
-
#line
|
2456
|
+
#line 351 "unicorn_http.rl"
|
2426
2457
|
{MARK(start.query, p); }
|
2427
2458
|
goto st82;
|
2428
2459
|
st82:
|
2429
2460
|
if ( ++p == pe )
|
2430
2461
|
goto _test_eof82;
|
2431
2462
|
case 82:
|
2432
|
-
#line
|
2463
|
+
#line 2464 "unicorn_http.c"
|
2433
2464
|
if ( (*p) < 65 ) {
|
2434
2465
|
if ( 48 <= (*p) && (*p) <= 57 )
|
2435
2466
|
goto st83;
|
@@ -2453,58 +2484,58 @@ case 83:
|
|
2453
2484
|
goto st81;
|
2454
2485
|
goto st0;
|
2455
2486
|
tr98:
|
2456
|
-
#line
|
2487
|
+
#line 318 "unicorn_http.rl"
|
2457
2488
|
{MARK(mark, p); }
|
2458
|
-
#line
|
2489
|
+
#line 322 "unicorn_http.rl"
|
2459
2490
|
{ downcase_char(deconst(p)); }
|
2460
2491
|
goto st84;
|
2461
2492
|
st84:
|
2462
2493
|
if ( ++p == pe )
|
2463
2494
|
goto _test_eof84;
|
2464
2495
|
case 84:
|
2465
|
-
#line
|
2496
|
+
#line 2497 "unicorn_http.c"
|
2466
2497
|
switch( (*p) ) {
|
2467
2498
|
case 84: goto tr123;
|
2468
2499
|
case 116: goto tr123;
|
2469
2500
|
}
|
2470
2501
|
goto st0;
|
2471
2502
|
tr123:
|
2472
|
-
#line
|
2503
|
+
#line 322 "unicorn_http.rl"
|
2473
2504
|
{ downcase_char(deconst(p)); }
|
2474
2505
|
goto st85;
|
2475
2506
|
st85:
|
2476
2507
|
if ( ++p == pe )
|
2477
2508
|
goto _test_eof85;
|
2478
2509
|
case 85:
|
2479
|
-
#line
|
2510
|
+
#line 2511 "unicorn_http.c"
|
2480
2511
|
switch( (*p) ) {
|
2481
2512
|
case 84: goto tr124;
|
2482
2513
|
case 116: goto tr124;
|
2483
2514
|
}
|
2484
2515
|
goto st0;
|
2485
2516
|
tr124:
|
2486
|
-
#line
|
2517
|
+
#line 322 "unicorn_http.rl"
|
2487
2518
|
{ downcase_char(deconst(p)); }
|
2488
2519
|
goto st86;
|
2489
2520
|
st86:
|
2490
2521
|
if ( ++p == pe )
|
2491
2522
|
goto _test_eof86;
|
2492
2523
|
case 86:
|
2493
|
-
#line
|
2524
|
+
#line 2525 "unicorn_http.c"
|
2494
2525
|
switch( (*p) ) {
|
2495
2526
|
case 80: goto tr125;
|
2496
2527
|
case 112: goto tr125;
|
2497
2528
|
}
|
2498
2529
|
goto st0;
|
2499
2530
|
tr125:
|
2500
|
-
#line
|
2531
|
+
#line 322 "unicorn_http.rl"
|
2501
2532
|
{ downcase_char(deconst(p)); }
|
2502
2533
|
goto st87;
|
2503
2534
|
st87:
|
2504
2535
|
if ( ++p == pe )
|
2505
2536
|
goto _test_eof87;
|
2506
2537
|
case 87:
|
2507
|
-
#line
|
2538
|
+
#line 2539 "unicorn_http.c"
|
2508
2539
|
switch( (*p) ) {
|
2509
2540
|
case 58: goto tr126;
|
2510
2541
|
case 83: goto tr127;
|
@@ -2512,7 +2543,7 @@ case 87:
|
|
2512
2543
|
}
|
2513
2544
|
goto st0;
|
2514
2545
|
tr126:
|
2515
|
-
#line
|
2546
|
+
#line 328 "unicorn_http.rl"
|
2516
2547
|
{
|
2517
2548
|
rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
|
2518
2549
|
}
|
@@ -2521,7 +2552,7 @@ st88:
|
|
2521
2552
|
if ( ++p == pe )
|
2522
2553
|
goto _test_eof88;
|
2523
2554
|
case 88:
|
2524
|
-
#line
|
2555
|
+
#line 2556 "unicorn_http.c"
|
2525
2556
|
if ( (*p) == 47 )
|
2526
2557
|
goto st89;
|
2527
2558
|
goto st0;
|
@@ -2609,14 +2640,14 @@ case 93:
|
|
2609
2640
|
goto st91;
|
2610
2641
|
goto st0;
|
2611
2642
|
tr132:
|
2612
|
-
#line
|
2643
|
+
#line 318 "unicorn_http.rl"
|
2613
2644
|
{MARK(mark, p); }
|
2614
2645
|
goto st94;
|
2615
2646
|
st94:
|
2616
2647
|
if ( ++p == pe )
|
2617
2648
|
goto _test_eof94;
|
2618
2649
|
case 94:
|
2619
|
-
#line
|
2650
|
+
#line 2651 "unicorn_http.c"
|
2620
2651
|
switch( (*p) ) {
|
2621
2652
|
case 37: goto st92;
|
2622
2653
|
case 47: goto tr136;
|
@@ -2668,14 +2699,14 @@ case 95:
|
|
2668
2699
|
goto st0;
|
2669
2700
|
goto st91;
|
2670
2701
|
tr133:
|
2671
|
-
#line
|
2702
|
+
#line 318 "unicorn_http.rl"
|
2672
2703
|
{MARK(mark, p); }
|
2673
2704
|
goto st96;
|
2674
2705
|
st96:
|
2675
2706
|
if ( ++p == pe )
|
2676
2707
|
goto _test_eof96;
|
2677
2708
|
case 96:
|
2678
|
-
#line
|
2709
|
+
#line 2710 "unicorn_http.c"
|
2679
2710
|
switch( (*p) ) {
|
2680
2711
|
case 37: goto st92;
|
2681
2712
|
case 47: goto st0;
|
@@ -2753,14 +2784,14 @@ case 98:
|
|
2753
2784
|
goto st0;
|
2754
2785
|
goto st91;
|
2755
2786
|
tr127:
|
2756
|
-
#line
|
2787
|
+
#line 322 "unicorn_http.rl"
|
2757
2788
|
{ downcase_char(deconst(p)); }
|
2758
2789
|
goto st99;
|
2759
2790
|
st99:
|
2760
2791
|
if ( ++p == pe )
|
2761
2792
|
goto _test_eof99;
|
2762
2793
|
case 99:
|
2763
|
-
#line
|
2794
|
+
#line 2795 "unicorn_http.c"
|
2764
2795
|
if ( (*p) == 58 )
|
2765
2796
|
goto tr126;
|
2766
2797
|
goto st0;
|
@@ -2780,18 +2811,18 @@ case 100:
|
|
2780
2811
|
goto tr141;
|
2781
2812
|
goto st0;
|
2782
2813
|
tr140:
|
2783
|
-
#line
|
2814
|
+
#line 367 "unicorn_http.rl"
|
2784
2815
|
{
|
2785
2816
|
hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
|
2786
2817
|
if (hp->len.chunk < 0)
|
2787
|
-
|
2818
|
+
parser_raise(eHttpParserError, "invalid chunk size");
|
2788
2819
|
}
|
2789
2820
|
goto st101;
|
2790
2821
|
st101:
|
2791
2822
|
if ( ++p == pe )
|
2792
2823
|
goto _test_eof101;
|
2793
2824
|
case 101:
|
2794
|
-
#line
|
2825
|
+
#line 2826 "unicorn_http.c"
|
2795
2826
|
switch( (*p) ) {
|
2796
2827
|
case 13: goto st102;
|
2797
2828
|
case 48: goto tr140;
|
@@ -2814,7 +2845,7 @@ case 102:
|
|
2814
2845
|
goto tr144;
|
2815
2846
|
goto st0;
|
2816
2847
|
tr144:
|
2817
|
-
#line
|
2848
|
+
#line 396 "unicorn_http.rl"
|
2818
2849
|
{
|
2819
2850
|
HP_FL_SET(hp, INTRAILER);
|
2820
2851
|
cs = http_parser_en_Trailers;
|
@@ -2827,21 +2858,21 @@ st123:
|
|
2827
2858
|
if ( ++p == pe )
|
2828
2859
|
goto _test_eof123;
|
2829
2860
|
case 123:
|
2830
|
-
#line
|
2861
|
+
#line 2862 "unicorn_http.c"
|
2831
2862
|
goto st0;
|
2832
2863
|
tr141:
|
2833
|
-
#line
|
2864
|
+
#line 367 "unicorn_http.rl"
|
2834
2865
|
{
|
2835
2866
|
hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
|
2836
2867
|
if (hp->len.chunk < 0)
|
2837
|
-
|
2868
|
+
parser_raise(eHttpParserError, "invalid chunk size");
|
2838
2869
|
}
|
2839
2870
|
goto st103;
|
2840
2871
|
st103:
|
2841
2872
|
if ( ++p == pe )
|
2842
2873
|
goto _test_eof103;
|
2843
2874
|
case 103:
|
2844
|
-
#line
|
2875
|
+
#line 2876 "unicorn_http.c"
|
2845
2876
|
switch( (*p) ) {
|
2846
2877
|
case 13: goto st104;
|
2847
2878
|
case 59: goto st108;
|
@@ -2868,7 +2899,7 @@ st105:
|
|
2868
2899
|
case 105:
|
2869
2900
|
goto tr148;
|
2870
2901
|
tr148:
|
2871
|
-
#line
|
2902
|
+
#line 404 "unicorn_http.rl"
|
2872
2903
|
{
|
2873
2904
|
skip_chunk_data_hack: {
|
2874
2905
|
size_t nr = MIN((size_t)hp->len.chunk, REMAINING);
|
@@ -2890,7 +2921,7 @@ st106:
|
|
2890
2921
|
if ( ++p == pe )
|
2891
2922
|
goto _test_eof106;
|
2892
2923
|
case 106:
|
2893
|
-
#line
|
2924
|
+
#line 2925 "unicorn_http.c"
|
2894
2925
|
if ( (*p) == 13 )
|
2895
2926
|
goto st107;
|
2896
2927
|
goto st0;
|
@@ -3112,14 +3143,14 @@ case 114:
|
|
3112
3143
|
goto tr157;
|
3113
3144
|
goto st0;
|
3114
3145
|
tr159:
|
3115
|
-
#line
|
3146
|
+
#line 324 "unicorn_http.rl"
|
3116
3147
|
{ MARK(mark, p); }
|
3117
3148
|
goto st115;
|
3118
3149
|
st115:
|
3119
3150
|
if ( ++p == pe )
|
3120
3151
|
goto _test_eof115;
|
3121
3152
|
case 115:
|
3122
|
-
#line
|
3153
|
+
#line 3154 "unicorn_http.c"
|
3123
3154
|
switch( (*p) ) {
|
3124
3155
|
case 9: goto tr159;
|
3125
3156
|
case 13: goto tr160;
|
@@ -3127,42 +3158,42 @@ case 115:
|
|
3127
3158
|
}
|
3128
3159
|
goto tr158;
|
3129
3160
|
tr158:
|
3130
|
-
#line
|
3161
|
+
#line 324 "unicorn_http.rl"
|
3131
3162
|
{ MARK(mark, p); }
|
3132
3163
|
goto st116;
|
3133
3164
|
st116:
|
3134
3165
|
if ( ++p == pe )
|
3135
3166
|
goto _test_eof116;
|
3136
3167
|
case 116:
|
3137
|
-
#line
|
3168
|
+
#line 3169 "unicorn_http.c"
|
3138
3169
|
if ( (*p) == 13 )
|
3139
3170
|
goto tr162;
|
3140
3171
|
goto st116;
|
3141
3172
|
tr160:
|
3142
|
-
#line
|
3173
|
+
#line 324 "unicorn_http.rl"
|
3143
3174
|
{ MARK(mark, p); }
|
3144
|
-
#line
|
3175
|
+
#line 326 "unicorn_http.rl"
|
3145
3176
|
{ write_cont_value(hp, buffer, p); }
|
3146
3177
|
goto st117;
|
3147
3178
|
tr162:
|
3148
|
-
#line
|
3179
|
+
#line 326 "unicorn_http.rl"
|
3149
3180
|
{ write_cont_value(hp, buffer, p); }
|
3150
3181
|
goto st117;
|
3151
3182
|
tr169:
|
3152
|
-
#line
|
3183
|
+
#line 324 "unicorn_http.rl"
|
3153
3184
|
{ MARK(mark, p); }
|
3154
|
-
#line
|
3185
|
+
#line 325 "unicorn_http.rl"
|
3155
3186
|
{ write_value(hp, buffer, p); }
|
3156
3187
|
goto st117;
|
3157
3188
|
tr171:
|
3158
|
-
#line
|
3189
|
+
#line 325 "unicorn_http.rl"
|
3159
3190
|
{ write_value(hp, buffer, p); }
|
3160
3191
|
goto st117;
|
3161
3192
|
st117:
|
3162
3193
|
if ( ++p == pe )
|
3163
3194
|
goto _test_eof117;
|
3164
3195
|
case 117:
|
3165
|
-
#line
|
3196
|
+
#line 3197 "unicorn_http.c"
|
3166
3197
|
if ( (*p) == 10 )
|
3167
3198
|
goto st114;
|
3168
3199
|
goto st0;
|
@@ -3174,7 +3205,7 @@ case 118:
|
|
3174
3205
|
goto tr164;
|
3175
3206
|
goto st0;
|
3176
3207
|
tr164:
|
3177
|
-
#line
|
3208
|
+
#line 391 "unicorn_http.rl"
|
3178
3209
|
{
|
3179
3210
|
cs = http_parser_first_final;
|
3180
3211
|
goto post_exec;
|
@@ -3184,23 +3215,23 @@ st124:
|
|
3184
3215
|
if ( ++p == pe )
|
3185
3216
|
goto _test_eof124;
|
3186
3217
|
case 124:
|
3187
|
-
#line
|
3218
|
+
#line 3219 "unicorn_http.c"
|
3188
3219
|
goto st0;
|
3189
3220
|
tr157:
|
3190
|
-
#line
|
3221
|
+
#line 320 "unicorn_http.rl"
|
3191
3222
|
{ MARK(start.field, p); }
|
3192
|
-
#line
|
3223
|
+
#line 321 "unicorn_http.rl"
|
3193
3224
|
{ snake_upcase_char(deconst(p)); }
|
3194
3225
|
goto st119;
|
3195
3226
|
tr165:
|
3196
|
-
#line
|
3227
|
+
#line 321 "unicorn_http.rl"
|
3197
3228
|
{ snake_upcase_char(deconst(p)); }
|
3198
3229
|
goto st119;
|
3199
3230
|
st119:
|
3200
3231
|
if ( ++p == pe )
|
3201
3232
|
goto _test_eof119;
|
3202
3233
|
case 119:
|
3203
|
-
#line
|
3234
|
+
#line 3235 "unicorn_http.c"
|
3204
3235
|
switch( (*p) ) {
|
3205
3236
|
case 33: goto tr165;
|
3206
3237
|
case 58: goto tr166;
|
@@ -3226,18 +3257,18 @@ case 119:
|
|
3226
3257
|
goto tr165;
|
3227
3258
|
goto st0;
|
3228
3259
|
tr168:
|
3229
|
-
#line
|
3260
|
+
#line 324 "unicorn_http.rl"
|
3230
3261
|
{ MARK(mark, p); }
|
3231
3262
|
goto st120;
|
3232
3263
|
tr166:
|
3233
|
-
#line
|
3264
|
+
#line 323 "unicorn_http.rl"
|
3234
3265
|
{ hp->s.field_len = LEN(start.field, p); }
|
3235
3266
|
goto st120;
|
3236
3267
|
st120:
|
3237
3268
|
if ( ++p == pe )
|
3238
3269
|
goto _test_eof120;
|
3239
3270
|
case 120:
|
3240
|
-
#line
|
3271
|
+
#line 3272 "unicorn_http.c"
|
3241
3272
|
switch( (*p) ) {
|
3242
3273
|
case 9: goto tr168;
|
3243
3274
|
case 13: goto tr169;
|
@@ -3245,14 +3276,14 @@ case 120:
|
|
3245
3276
|
}
|
3246
3277
|
goto tr167;
|
3247
3278
|
tr167:
|
3248
|
-
#line
|
3279
|
+
#line 324 "unicorn_http.rl"
|
3249
3280
|
{ MARK(mark, p); }
|
3250
3281
|
goto st121;
|
3251
3282
|
st121:
|
3252
3283
|
if ( ++p == pe )
|
3253
3284
|
goto _test_eof121;
|
3254
3285
|
case 121:
|
3255
|
-
#line
|
3286
|
+
#line 3287 "unicorn_http.c"
|
3256
3287
|
if ( (*p) == 13 )
|
3257
3288
|
goto tr171;
|
3258
3289
|
goto st121;
|
@@ -3385,7 +3416,7 @@ case 121:
|
|
3385
3416
|
_out: {}
|
3386
3417
|
}
|
3387
3418
|
|
3388
|
-
#line
|
3419
|
+
#line 465 "unicorn_http.rl"
|
3389
3420
|
post_exec: /* "_out:" also goes here */
|
3390
3421
|
if (hp->cs != http_parser_error)
|
3391
3422
|
hp->cs = cs;
|
@@ -3553,6 +3584,34 @@ static VALUE HttpParser_clear(VALUE self)
|
|
3553
3584
|
return self;
|
3554
3585
|
}
|
3555
3586
|
|
3587
|
+
/**
|
3588
|
+
* call-seq:
|
3589
|
+
* parser.dechunk! => parser
|
3590
|
+
*
|
3591
|
+
* Resets the parser to a state suitable for dechunking response bodies
|
3592
|
+
*
|
3593
|
+
*/
|
3594
|
+
static VALUE HttpParser_dechunk_bang(VALUE self)
|
3595
|
+
{
|
3596
|
+
struct http_parser *hp = data_get(self);
|
3597
|
+
|
3598
|
+
http_parser_init(hp);
|
3599
|
+
|
3600
|
+
/*
|
3601
|
+
* we don't care about trailers in dechunk-only mode,
|
3602
|
+
* but if we did we'd set UH_FL_HASTRAILER and clear hp->env
|
3603
|
+
*/
|
3604
|
+
if (0) {
|
3605
|
+
rb_funcall(hp->env, id_clear, 0);
|
3606
|
+
hp->flags = UH_FL_HASTRAILER;
|
3607
|
+
}
|
3608
|
+
|
3609
|
+
hp->flags |= UH_FL_HASBODY | UH_FL_INBODY | UH_FL_CHUNKED;
|
3610
|
+
hp->cs = http_parser_en_ChunkedBody;
|
3611
|
+
|
3612
|
+
return self;
|
3613
|
+
}
|
3614
|
+
|
3556
3615
|
/**
|
3557
3616
|
* call-seq:
|
3558
3617
|
* parser.reset => nil
|
@@ -3632,7 +3691,8 @@ static VALUE HttpParser_parse(VALUE self)
|
|
3632
3691
|
}
|
3633
3692
|
|
3634
3693
|
http_parser_execute(hp, RSTRING_PTR(data), RSTRING_LEN(data));
|
3635
|
-
|
3694
|
+
if (hp->offset > MAX_HEADER_LEN)
|
3695
|
+
parser_raise(e413, "HTTP header is too large");
|
3636
3696
|
|
3637
3697
|
if (hp->cs == http_parser_first_final ||
|
3638
3698
|
hp->cs == http_parser_en_ChunkedBody) {
|
@@ -3645,11 +3705,32 @@ static VALUE HttpParser_parse(VALUE self)
|
|
3645
3705
|
}
|
3646
3706
|
|
3647
3707
|
if (hp->cs == http_parser_error)
|
3648
|
-
|
3708
|
+
parser_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
|
3649
3709
|
|
3650
3710
|
return Qnil;
|
3651
3711
|
}
|
3652
3712
|
|
3713
|
+
/**
|
3714
|
+
* Document-method: parse
|
3715
|
+
* call-seq:
|
3716
|
+
* parser.add_parse(buffer) => env or nil
|
3717
|
+
*
|
3718
|
+
* adds the contents of +buffer+ to the internal buffer and attempts to
|
3719
|
+
* continue parsing. Returns the +env+ Hash on success or nil if more
|
3720
|
+
* data is needed.
|
3721
|
+
*
|
3722
|
+
* Raises HttpParserError if there are parsing errors.
|
3723
|
+
*/
|
3724
|
+
static VALUE HttpParser_add_parse(VALUE self, VALUE buffer)
|
3725
|
+
{
|
3726
|
+
struct http_parser *hp = data_get(self);
|
3727
|
+
|
3728
|
+
Check_Type(buffer, T_STRING);
|
3729
|
+
rb_str_buf_append(hp->buf, buffer);
|
3730
|
+
|
3731
|
+
return HttpParser_parse(self);
|
3732
|
+
}
|
3733
|
+
|
3653
3734
|
/**
|
3654
3735
|
* Document-method: trailers
|
3655
3736
|
* call-seq:
|
@@ -3758,71 +3839,80 @@ static VALUE HttpParser_env(VALUE self)
|
|
3758
3839
|
|
3759
3840
|
/**
|
3760
3841
|
* call-seq:
|
3761
|
-
* parser.filter_body(
|
3842
|
+
* parser.filter_body(dst, src) => nil/src
|
3762
3843
|
*
|
3763
|
-
* Takes a String of +
|
3844
|
+
* Takes a String of +src+, will modify data if dechunking is done.
|
3764
3845
|
* Returns +nil+ if there is more data left to process. Returns
|
3765
|
-
* +
|
3766
|
-
* it may modify +
|
3846
|
+
* +src+ if body processing is complete. When returning +src+,
|
3847
|
+
* it may modify +src+ so the start of the string points to where
|
3767
3848
|
* the body ended so that trailer processing can begin.
|
3768
3849
|
*
|
3769
3850
|
* Raises HttpParserError if there are dechunking errors.
|
3770
|
-
* Basically this is a glorified memcpy(3) that copies +
|
3851
|
+
* Basically this is a glorified memcpy(3) that copies +src+
|
3771
3852
|
* into +buf+ while filtering it through the dechunker.
|
3772
3853
|
*/
|
3773
|
-
static VALUE HttpParser_filter_body(VALUE self, VALUE
|
3854
|
+
static VALUE HttpParser_filter_body(VALUE self, VALUE dst, VALUE src)
|
3774
3855
|
{
|
3775
3856
|
struct http_parser *hp = data_get(self);
|
3776
|
-
char *
|
3777
|
-
long
|
3857
|
+
char *srcptr;
|
3858
|
+
long srclen;
|
3778
3859
|
|
3779
|
-
|
3780
|
-
|
3860
|
+
srcptr = RSTRING_PTR(src);
|
3861
|
+
srclen = RSTRING_LEN(src);
|
3781
3862
|
|
3782
|
-
StringValue(
|
3783
|
-
rb_str_resize(buf, dlen); /* we can never copy more than dlen bytes */
|
3784
|
-
OBJ_TAINT(buf); /* keep weirdo $SAFE users happy */
|
3863
|
+
StringValue(dst);
|
3785
3864
|
|
3786
3865
|
if (HP_FL_TEST(hp, CHUNKED)) {
|
3787
3866
|
if (!chunked_eof(hp)) {
|
3867
|
+
rb_str_modify(dst);
|
3868
|
+
rb_str_resize(dst, srclen); /* we can never copy more than srclen bytes */
|
3869
|
+
|
3788
3870
|
hp->s.dest_offset = 0;
|
3789
|
-
hp->cont =
|
3790
|
-
hp->buf =
|
3791
|
-
http_parser_execute(hp,
|
3871
|
+
hp->cont = dst;
|
3872
|
+
hp->buf = src;
|
3873
|
+
http_parser_execute(hp, srcptr, srclen);
|
3792
3874
|
if (hp->cs == http_parser_error)
|
3793
|
-
|
3875
|
+
parser_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
|
3794
3876
|
|
3795
3877
|
assert(hp->s.dest_offset <= hp->offset &&
|
3796
3878
|
"destination buffer overflow");
|
3797
|
-
advance_str(
|
3798
|
-
rb_str_set_len(
|
3879
|
+
advance_str(src, hp->offset);
|
3880
|
+
rb_str_set_len(dst, hp->s.dest_offset);
|
3799
3881
|
|
3800
|
-
if (RSTRING_LEN(
|
3882
|
+
if (RSTRING_LEN(dst) == 0 && chunked_eof(hp)) {
|
3801
3883
|
assert(hp->len.chunk == 0 && "chunk at EOF but more to parse");
|
3802
3884
|
} else {
|
3803
|
-
|
3885
|
+
src = Qnil;
|
3804
3886
|
}
|
3805
3887
|
}
|
3806
3888
|
} else {
|
3807
3889
|
/* no need to enter the Ragel machine for unchunked transfers */
|
3808
3890
|
assert(hp->len.content >= 0 && "negative Content-Length");
|
3809
3891
|
if (hp->len.content > 0) {
|
3810
|
-
long nr = MIN(
|
3811
|
-
|
3812
|
-
|
3813
|
-
|
3892
|
+
long nr = MIN(srclen, hp->len.content);
|
3893
|
+
|
3894
|
+
rb_str_modify(dst);
|
3895
|
+
rb_str_resize(dst, nr);
|
3896
|
+
/*
|
3897
|
+
* using rb_str_replace() to avoid memcpy() doesn't help in
|
3898
|
+
* most cases because a GC-aware programmer will pass an explicit
|
3899
|
+
* buffer to env["rack.input"].read and reuse the buffer in a loop.
|
3900
|
+
* This causes copy-on-write behavior to be triggered anyways
|
3901
|
+
* when the +src+ buffer is modified (when reading off the socket).
|
3902
|
+
*/
|
3903
|
+
hp->buf = src;
|
3904
|
+
memcpy(RSTRING_PTR(dst), srcptr, nr);
|
3814
3905
|
hp->len.content -= nr;
|
3815
3906
|
if (hp->len.content == 0) {
|
3816
3907
|
HP_FL_SET(hp, REQEOF);
|
3817
3908
|
hp->cs = http_parser_first_final;
|
3818
3909
|
}
|
3819
|
-
advance_str(
|
3820
|
-
|
3821
|
-
data = Qnil;
|
3910
|
+
advance_str(src, nr);
|
3911
|
+
src = Qnil;
|
3822
3912
|
}
|
3823
3913
|
}
|
3824
3914
|
hp->offset = 0; /* for trailer parsing */
|
3825
|
-
return
|
3915
|
+
return src;
|
3826
3916
|
}
|
3827
3917
|
|
3828
3918
|
#define SET_GLOBAL(var,str) do { \
|
@@ -3838,13 +3928,19 @@ void Init_unicorn_http(void)
|
|
3838
3928
|
cHttpParser = rb_define_class_under(mUnicorn, "HttpParser", rb_cObject);
|
3839
3929
|
eHttpParserError =
|
3840
3930
|
rb_define_class_under(mUnicorn, "HttpParserError", rb_eIOError);
|
3931
|
+
e413 = rb_define_class_under(mUnicorn, "RequestEntityTooLargeError",
|
3932
|
+
eHttpParserError);
|
3933
|
+
e414 = rb_define_class_under(mUnicorn, "RequestURITooLongError",
|
3934
|
+
eHttpParserError);
|
3841
3935
|
|
3842
3936
|
init_globals();
|
3843
3937
|
rb_define_alloc_func(cHttpParser, HttpParser_alloc);
|
3844
3938
|
rb_define_method(cHttpParser, "initialize", HttpParser_init, 0);
|
3845
3939
|
rb_define_method(cHttpParser, "clear", HttpParser_clear, 0);
|
3846
3940
|
rb_define_method(cHttpParser, "reset", HttpParser_reset, 0);
|
3941
|
+
rb_define_method(cHttpParser, "dechunk!", HttpParser_dechunk_bang, 0);
|
3847
3942
|
rb_define_method(cHttpParser, "parse", HttpParser_parse, 0);
|
3943
|
+
rb_define_method(cHttpParser, "add_parse", HttpParser_add_parse, 1);
|
3848
3944
|
rb_define_method(cHttpParser, "headers", HttpParser_headers, 2);
|
3849
3945
|
rb_define_method(cHttpParser, "trailers", HttpParser_headers, 2);
|
3850
3946
|
rb_define_method(cHttpParser, "filter_body", HttpParser_filter_body, 2);
|
@@ -3879,6 +3975,7 @@ void Init_unicorn_http(void)
|
|
3879
3975
|
rb_define_singleton_method(cHttpParser, "keepalive_requests=", set_ka_req, 1);
|
3880
3976
|
rb_define_singleton_method(cHttpParser, "trust_x_forwarded=", set_xftrust, 1);
|
3881
3977
|
rb_define_singleton_method(cHttpParser, "trust_x_forwarded?", xftrust, 0);
|
3978
|
+
rb_define_singleton_method(cHttpParser, "max_header_len=", set_maxhdrlen, 1);
|
3882
3979
|
|
3883
3980
|
init_common_fields();
|
3884
3981
|
SET_GLOBAL(g_http_host, "HOST");
|
@@ -3887,6 +3984,7 @@ void Init_unicorn_http(void)
|
|
3887
3984
|
SET_GLOBAL(g_content_length, "CONTENT_LENGTH");
|
3888
3985
|
SET_GLOBAL(g_http_connection, "CONNECTION");
|
3889
3986
|
id_clear = rb_intern("clear");
|
3987
|
+
id_set_backtrace = rb_intern("set_backtrace");
|
3890
3988
|
init_unicorn_httpdate();
|
3891
3989
|
}
|
3892
3990
|
#undef SET_GLOBAL
|