pitchfork 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.git-blame-ignore-revs +3 -0
  3. data/.gitattributes +5 -0
  4. data/.github/workflows/ci.yml +30 -0
  5. data/.gitignore +23 -0
  6. data/COPYING +674 -0
  7. data/Dockerfile +4 -0
  8. data/Gemfile +9 -0
  9. data/Gemfile.lock +30 -0
  10. data/LICENSE +67 -0
  11. data/README.md +123 -0
  12. data/Rakefile +72 -0
  13. data/docs/Application_Timeouts.md +74 -0
  14. data/docs/CONFIGURATION.md +388 -0
  15. data/docs/DESIGN.md +86 -0
  16. data/docs/FORK_SAFETY.md +80 -0
  17. data/docs/PHILOSOPHY.md +90 -0
  18. data/docs/REFORKING.md +113 -0
  19. data/docs/SIGNALS.md +38 -0
  20. data/docs/TUNING.md +106 -0
  21. data/examples/constant_caches.ru +43 -0
  22. data/examples/echo.ru +25 -0
  23. data/examples/hello.ru +5 -0
  24. data/examples/nginx.conf +156 -0
  25. data/examples/pitchfork.conf.minimal.rb +5 -0
  26. data/examples/pitchfork.conf.rb +77 -0
  27. data/examples/unicorn.socket +11 -0
  28. data/exe/pitchfork +116 -0
  29. data/ext/pitchfork_http/CFLAGS +13 -0
  30. data/ext/pitchfork_http/c_util.h +116 -0
  31. data/ext/pitchfork_http/child_subreaper.h +25 -0
  32. data/ext/pitchfork_http/common_field_optimization.h +130 -0
  33. data/ext/pitchfork_http/epollexclusive.h +124 -0
  34. data/ext/pitchfork_http/ext_help.h +38 -0
  35. data/ext/pitchfork_http/extconf.rb +14 -0
  36. data/ext/pitchfork_http/global_variables.h +97 -0
  37. data/ext/pitchfork_http/httpdate.c +79 -0
  38. data/ext/pitchfork_http/pitchfork_http.c +4318 -0
  39. data/ext/pitchfork_http/pitchfork_http.rl +1024 -0
  40. data/ext/pitchfork_http/pitchfork_http_common.rl +76 -0
  41. data/lib/pitchfork/app/old_rails/static.rb +59 -0
  42. data/lib/pitchfork/children.rb +124 -0
  43. data/lib/pitchfork/configurator.rb +314 -0
  44. data/lib/pitchfork/const.rb +23 -0
  45. data/lib/pitchfork/http_parser.rb +206 -0
  46. data/lib/pitchfork/http_response.rb +63 -0
  47. data/lib/pitchfork/http_server.rb +822 -0
  48. data/lib/pitchfork/launcher.rb +9 -0
  49. data/lib/pitchfork/mem_info.rb +36 -0
  50. data/lib/pitchfork/message.rb +130 -0
  51. data/lib/pitchfork/mold_selector.rb +29 -0
  52. data/lib/pitchfork/preread_input.rb +33 -0
  53. data/lib/pitchfork/refork_condition.rb +21 -0
  54. data/lib/pitchfork/select_waiter.rb +9 -0
  55. data/lib/pitchfork/socket_helper.rb +199 -0
  56. data/lib/pitchfork/stream_input.rb +152 -0
  57. data/lib/pitchfork/tee_input.rb +133 -0
  58. data/lib/pitchfork/tmpio.rb +35 -0
  59. data/lib/pitchfork/version.rb +8 -0
  60. data/lib/pitchfork/worker.rb +244 -0
  61. data/lib/pitchfork.rb +158 -0
  62. data/pitchfork.gemspec +30 -0
  63. metadata +137 -0
@@ -0,0 +1,4318 @@
1
+
2
+ #line 1 "pitchfork_http.rl"
3
+ /**
4
+ * Copyright (c) 2009 Eric Wong (all bugs are Eric's fault)
5
+ * Copyright (c) 2005 Zed A. Shaw
6
+ * You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
7
+ * the GPLv2+ (GPLv3+ preferred)
8
+ */
9
+ #include "ruby.h"
10
+ #include "ext_help.h"
11
+ #include <assert.h>
12
+ #include <string.h>
13
+ #include <sys/types.h>
14
+ #include "common_field_optimization.h"
15
+ #include "global_variables.h"
16
+ #include "c_util.h"
17
+ #include "epollexclusive.h"
18
+ #include "child_subreaper.h"
19
+
20
+ void init_pitchfork_httpdate(void);
21
+
22
+ #define UH_FL_CHUNKED 0x1
23
+ #define UH_FL_HASBODY 0x2
24
+ #define UH_FL_INBODY 0x4
25
+ #define UH_FL_HASTRAILER 0x8
26
+ #define UH_FL_INTRAILER 0x10
27
+ #define UH_FL_INCHUNK 0x20
28
+ #define UH_FL_REQEOF 0x40
29
+ #define UH_FL_KAVERSION 0x80
30
+ #define UH_FL_HASHEADER 0x100
31
+ #define UH_FL_TO_CLEAR 0x200
32
+ #define UH_FL_RESSTART 0x400 /* for check_client_connection */
33
+ #define UH_FL_HIJACK 0x800
34
+
35
+ /* all of these flags need to be set for keepalive to be supported */
36
+ #define UH_FL_KEEPALIVE (UH_FL_KAVERSION | UH_FL_REQEOF | UH_FL_HASHEADER)
37
+
38
+ static unsigned int MAX_HEADER_LEN = 1024 * (80 + 32); /* same as Mongrel */
39
+
40
+ /* this is only intended for use with Rainbows! */
41
+ static VALUE set_maxhdrlen(VALUE self, VALUE len)
42
+ {
43
+ return UINT2NUM(MAX_HEADER_LEN = NUM2UINT(len));
44
+ }
45
+
46
+ /* keep this small for other servers (e.g. yahns) since every client has one */
47
+ struct http_parser {
48
+ int cs; /* Ragel internal state */
49
+ unsigned int flags;
50
+ unsigned int mark;
51
+ unsigned int offset;
52
+ union { /* these 2 fields don't nest */
53
+ unsigned int field;
54
+ unsigned int query;
55
+ } start;
56
+ union {
57
+ unsigned int field_len; /* only used during header processing */
58
+ unsigned int dest_offset; /* only used during body processing */
59
+ } s;
60
+ VALUE buf;
61
+ VALUE env;
62
+ VALUE cont; /* Qfalse: unset, Qnil: ignored header, T_STRING: append */
63
+ union {
64
+ off_t content;
65
+ off_t chunk;
66
+ } len;
67
+ };
68
+
69
+ static ID id_set_backtrace, id_is_chunked_p;
70
+ static VALUE cHttpParser;
71
+
72
+ static void finalize_header(struct http_parser *hp);
73
+
74
+ static void parser_raise(VALUE klass, const char *msg)
75
+ {
76
+ VALUE exc = rb_exc_new2(klass, msg);
77
+ VALUE bt = rb_ary_new();
78
+
79
+ rb_funcall(exc, id_set_backtrace, 1, bt);
80
+ rb_exc_raise(exc);
81
+ }
82
+
83
+ static inline unsigned int ulong2uint(unsigned long n)
84
+ {
85
+ unsigned int i = (unsigned int)n;
86
+
87
+ if (sizeof(unsigned int) != sizeof(unsigned long)) {
88
+ if ((unsigned long)i != n) {
89
+ rb_raise(rb_eRangeError, "too large to be 32-bit uint: %lu", n);
90
+ }
91
+ }
92
+ return i;
93
+ }
94
+
95
+ #define REMAINING (unsigned long)(pe - p)
96
+ #define LEN(AT, FPC) (ulong2uint(FPC - buffer) - hp->AT)
97
+ #define MARK(M,FPC) (hp->M = ulong2uint((FPC) - buffer))
98
+ #define PTR_TO(F) (buffer + hp->F)
99
+ #define STR_NEW(M,FPC) rb_str_new(PTR_TO(M), LEN(M, FPC))
100
+ #define STRIPPED_STR_NEW(M,FPC) stripped_str_new(PTR_TO(M), LEN(M, FPC))
101
+
102
+ #define HP_FL_TEST(hp,fl) ((hp)->flags & (UH_FL_##fl))
103
+ #define HP_FL_SET(hp,fl) ((hp)->flags |= (UH_FL_##fl))
104
+ #define HP_FL_UNSET(hp,fl) ((hp)->flags &= ~(UH_FL_##fl))
105
+ #define HP_FL_ALL(hp,fl) (HP_FL_TEST(hp, fl) == (UH_FL_##fl))
106
+
107
+ static int is_lws(char c)
108
+ {
109
+ return (c == ' ' || c == '\t');
110
+ }
111
+
112
+ static VALUE stripped_str_new(const char *str, long len)
113
+ {
114
+ long end;
115
+
116
+ for (end = len - 1; end >= 0 && is_lws(str[end]); end--);
117
+
118
+ return rb_str_new(str, end + 1);
119
+ }
120
+
121
+ /*
122
+ * handles values of the "Connection:" header, keepalive is implied
123
+ * for HTTP/1.1 but needs to be explicitly enabled with HTTP/1.0
124
+ * Additionally, we require GET/HEAD requests to support keepalive.
125
+ */
126
+ static void hp_keepalive_connection(struct http_parser *hp, VALUE val)
127
+ {
128
+ if (STR_CSTR_CASE_EQ(val, "keep-alive")) {
129
+ /* basically have HTTP/1.0 masquerade as HTTP/1.1+ */
130
+ HP_FL_SET(hp, KAVERSION);
131
+ } else if (STR_CSTR_CASE_EQ(val, "close")) {
132
+ /*
133
+ * it doesn't matter what HTTP version or request method we have,
134
+ * if a client says "Connection: close", we disable keepalive
135
+ */
136
+ HP_FL_UNSET(hp, KAVERSION);
137
+ } else {
138
+ /*
139
+ * client could've sent anything, ignore it for now. Maybe
140
+ * "HP_FL_UNSET(hp, KAVERSION);" just in case?
141
+ * Raising an exception might be too mean...
142
+ */
143
+ }
144
+ }
145
+
146
+ static void
147
+ request_method(struct http_parser *hp, const char *ptr, size_t len)
148
+ {
149
+ VALUE v = rb_str_new(ptr, len);
150
+
151
+ rb_hash_aset(hp->env, g_request_method, v);
152
+ }
153
+
154
+ static void
155
+ http_version(struct http_parser *hp, const char *ptr, size_t len)
156
+ {
157
+ VALUE v;
158
+
159
+ HP_FL_SET(hp, HASHEADER);
160
+
161
+ if (CONST_MEM_EQ("HTTP/1.1", ptr, len)) {
162
+ /* HTTP/1.1 implies keepalive unless "Connection: close" is set */
163
+ HP_FL_SET(hp, KAVERSION);
164
+ v = g_http_11;
165
+ } else if (CONST_MEM_EQ("HTTP/1.0", ptr, len)) {
166
+ v = g_http_10;
167
+ } else {
168
+ v = rb_str_new(ptr, len);
169
+ }
170
+ rb_hash_aset(hp->env, g_server_protocol, v);
171
+ rb_hash_aset(hp->env, g_http_version, v);
172
+ }
173
+
174
+ static inline void hp_invalid_if_trailer(struct http_parser *hp)
175
+ {
176
+ if (HP_FL_TEST(hp, INTRAILER))
177
+ parser_raise(eHttpParserError, "invalid Trailer");
178
+ }
179
+
180
+ static void write_cont_value(struct http_parser *hp,
181
+ char *buffer, const char *p)
182
+ {
183
+ char *vptr;
184
+ long end;
185
+ long len = LEN(mark, p);
186
+ long cont_len;
187
+
188
+ if (hp->cont == Qfalse)
189
+ parser_raise(eHttpParserError, "invalid continuation line");
190
+ if (NIL_P(hp->cont))
191
+ return; /* we're ignoring this header (probably Host:) */
192
+
193
+ assert(TYPE(hp->cont) == T_STRING && "continuation line is not a string");
194
+ assert(hp->mark > 0 && "impossible continuation line offset");
195
+
196
+ if (len == 0)
197
+ return;
198
+
199
+ cont_len = RSTRING_LEN(hp->cont);
200
+ if (cont_len > 0) {
201
+ --hp->mark;
202
+ len = LEN(mark, p);
203
+ }
204
+ vptr = PTR_TO(mark);
205
+
206
+ /* normalize tab to space */
207
+ if (cont_len > 0) {
208
+ assert((' ' == *vptr || '\t' == *vptr) && "invalid leading white space");
209
+ *vptr = ' ';
210
+ }
211
+
212
+ for (end = len - 1; end >= 0 && is_lws(vptr[end]); end--);
213
+ rb_str_buf_cat(hp->cont, vptr, end + 1);
214
+ }
215
+
216
+ static int is_chunked(VALUE v)
217
+ {
218
+ /* common case first */
219
+ if (STR_CSTR_CASE_EQ(v, "chunked"))
220
+ return 1;
221
+
222
+ /*
223
+ * call Ruby function in pitchfork/http_parser.rb to deal with unlikely
224
+ * comma-delimited case
225
+ */
226
+ return rb_funcall(cHttpParser, id_is_chunked_p, 1, v) != Qfalse;
227
+ }
228
+
229
+ static void write_value(struct http_parser *hp,
230
+ const char *buffer, const char *p)
231
+ {
232
+ VALUE f = find_common_field(PTR_TO(start.field), hp->s.field_len);
233
+ VALUE v;
234
+ VALUE e;
235
+
236
+ VALIDATE_MAX_LENGTH(LEN(mark, p), FIELD_VALUE);
237
+ v = LEN(mark, p) == 0 ? rb_str_buf_new(128) : STRIPPED_STR_NEW(mark, p);
238
+ if (NIL_P(f)) {
239
+ const char *field = PTR_TO(start.field);
240
+ size_t flen = hp->s.field_len;
241
+
242
+ VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
243
+
244
+ /*
245
+ * ignore "Version" headers since they conflict with the HTTP_VERSION
246
+ * rack env variable.
247
+ */
248
+ if (CONST_MEM_EQ("VERSION", field, flen)) {
249
+ hp->cont = Qnil;
250
+ return;
251
+ }
252
+ f = uncommon_field(field, flen);
253
+ } else if (f == g_http_connection) {
254
+ hp_keepalive_connection(hp, v);
255
+ } else if (f == g_content_length && !HP_FL_TEST(hp, CHUNKED)) {
256
+ if (hp->len.content)
257
+ parser_raise(eHttpParserError, "Content-Length already set");
258
+ hp->len.content = parse_length(RSTRING_PTR(v), RSTRING_LEN(v));
259
+ if (hp->len.content < 0)
260
+ parser_raise(eHttpParserError, "invalid Content-Length");
261
+ if (hp->len.content != 0)
262
+ HP_FL_SET(hp, HASBODY);
263
+ hp_invalid_if_trailer(hp);
264
+ } else if (f == g_http_transfer_encoding) {
265
+ if (is_chunked(v)) {
266
+ if (HP_FL_TEST(hp, CHUNKED))
267
+ /*
268
+ * RFC 7230 3.3.1:
269
+ * A sender MUST NOT apply chunked more than once to a message body
270
+ * (i.e., chunking an already chunked message is not allowed).
271
+ */
272
+ parser_raise(eHttpParserError, "Transfer-Encoding double chunked");
273
+
274
+ HP_FL_SET(hp, CHUNKED);
275
+ HP_FL_SET(hp, HASBODY);
276
+
277
+ /* RFC 7230 3.3.3, 3: favor chunked if Content-Length exists */
278
+ hp->len.content = 0;
279
+ } else if (HP_FL_TEST(hp, CHUNKED)) {
280
+ /*
281
+ * RFC 7230 3.3.3, point 3 states:
282
+ * If a Transfer-Encoding header field is present in a request and
283
+ * the chunked transfer coding is not the final encoding, the
284
+ * message body length cannot be determined reliably; the server
285
+ * MUST respond with the 400 (Bad Request) status code and then
286
+ * close the connection.
287
+ */
288
+ parser_raise(eHttpParserError, "invalid Transfer-Encoding");
289
+ }
290
+ hp_invalid_if_trailer(hp);
291
+ } else if (f == g_http_trailer) {
292
+ HP_FL_SET(hp, HASTRAILER);
293
+ hp_invalid_if_trailer(hp);
294
+ } else {
295
+ assert(TYPE(f) == T_STRING && "memoized object is not a string");
296
+ assert_frozen(f);
297
+ }
298
+
299
+ e = rb_hash_aref(hp->env, f);
300
+ if (NIL_P(e)) {
301
+ hp->cont = rb_hash_aset(hp->env, f, v);
302
+ } else if (f == g_http_host) {
303
+ /*
304
+ * ignored, absolute URLs in REQUEST_URI take precedence over
305
+ * the Host: header (ref: rfc 2616, section 5.2.1)
306
+ */
307
+ hp->cont = Qnil;
308
+ } else {
309
+ rb_str_buf_cat(e, ",", 1);
310
+ hp->cont = rb_str_buf_append(e, v);
311
+ }
312
+ }
313
+
314
+ /** Machine **/
315
+
316
+
317
+ #line 421 "pitchfork_http.rl"
318
+
319
+
320
+ /** Data **/
321
+
322
+ #line 323 "pitchfork_http.c"
323
+ static const int http_parser_start = 1;
324
+ static const int http_parser_first_final = 122;
325
+ static const int http_parser_error = 0;
326
+
327
+ static const int http_parser_en_ChunkedBody = 100;
328
+ static const int http_parser_en_ChunkedBody_chunk_chunk_end = 105;
329
+ static const int http_parser_en_Trailers = 114;
330
+ static const int http_parser_en_main = 1;
331
+
332
+
333
+ #line 425 "pitchfork_http.rl"
334
+
335
+ static void http_parser_init(struct http_parser *hp)
336
+ {
337
+ int cs = 0;
338
+ hp->flags = 0;
339
+ hp->mark = 0;
340
+ hp->offset = 0;
341
+ hp->start.field = 0;
342
+ hp->s.field_len = 0;
343
+ hp->len.content = 0;
344
+ hp->cont = Qfalse; /* zero on MRI, should be optimized away by above */
345
+
346
+ #line 347 "pitchfork_http.c"
347
+ {
348
+ cs = http_parser_start;
349
+ }
350
+
351
+ #line 437 "pitchfork_http.rl"
352
+ hp->cs = cs;
353
+ }
354
+
355
+ /** exec **/
356
+ static void
357
+ http_parser_execute(struct http_parser *hp, char *buffer, size_t len)
358
+ {
359
+ const char *p, *pe;
360
+ int cs = hp->cs;
361
+ size_t off = hp->offset;
362
+
363
+ if (cs == http_parser_first_final)
364
+ return;
365
+
366
+ assert(off <= len && "offset past end of buffer");
367
+
368
+ p = buffer+off;
369
+ pe = buffer+len;
370
+
371
+ assert((void *)(pe - p) == (void *)(len - off) &&
372
+ "pointers aren't same distance");
373
+
374
+ if (HP_FL_TEST(hp, INCHUNK)) {
375
+ HP_FL_UNSET(hp, INCHUNK);
376
+ goto skip_chunk_data_hack;
377
+ }
378
+
379
+ #line 380 "pitchfork_http.c"
380
+ {
381
+ if ( p == pe )
382
+ goto _test_eof;
383
+ switch ( cs )
384
+ {
385
+ case 1:
386
+ switch( (*p) ) {
387
+ case 33: goto tr0;
388
+ case 71: goto tr2;
389
+ case 124: goto tr0;
390
+ case 126: goto tr0;
391
+ }
392
+ if ( (*p) < 45 ) {
393
+ if ( (*p) > 39 ) {
394
+ if ( 42 <= (*p) && (*p) <= 43 )
395
+ goto tr0;
396
+ } else if ( (*p) >= 35 )
397
+ goto tr0;
398
+ } else if ( (*p) > 46 ) {
399
+ if ( (*p) < 65 ) {
400
+ if ( 48 <= (*p) && (*p) <= 57 )
401
+ goto tr0;
402
+ } else if ( (*p) > 90 ) {
403
+ if ( 94 <= (*p) && (*p) <= 122 )
404
+ goto tr0;
405
+ } else
406
+ goto tr0;
407
+ } else
408
+ goto tr0;
409
+ goto st0;
410
+ st0:
411
+ cs = 0;
412
+ goto _out;
413
+ tr0:
414
+ #line 317 "pitchfork_http.rl"
415
+ {MARK(mark, p); }
416
+ goto st2;
417
+ st2:
418
+ if ( ++p == pe )
419
+ goto _test_eof2;
420
+ case 2:
421
+ #line 422 "pitchfork_http.c"
422
+ switch( (*p) ) {
423
+ case 32: goto tr3;
424
+ case 33: goto st49;
425
+ case 124: goto st49;
426
+ case 126: goto st49;
427
+ }
428
+ if ( (*p) < 45 ) {
429
+ if ( (*p) > 39 ) {
430
+ if ( 42 <= (*p) && (*p) <= 43 )
431
+ goto st49;
432
+ } else if ( (*p) >= 35 )
433
+ goto st49;
434
+ } else if ( (*p) > 46 ) {
435
+ if ( (*p) < 65 ) {
436
+ if ( 48 <= (*p) && (*p) <= 57 )
437
+ goto st49;
438
+ } else if ( (*p) > 90 ) {
439
+ if ( 94 <= (*p) && (*p) <= 122 )
440
+ goto st49;
441
+ } else
442
+ goto st49;
443
+ } else
444
+ goto st49;
445
+ goto st0;
446
+ tr3:
447
+ #line 326 "pitchfork_http.rl"
448
+ { request_method(hp, PTR_TO(mark), LEN(mark, p)); }
449
+ goto st3;
450
+ st3:
451
+ if ( ++p == pe )
452
+ goto _test_eof3;
453
+ case 3:
454
+ #line 455 "pitchfork_http.c"
455
+ switch( (*p) ) {
456
+ case 42: goto tr5;
457
+ case 47: goto tr6;
458
+ case 72: goto tr7;
459
+ case 104: goto tr7;
460
+ }
461
+ goto st0;
462
+ tr5:
463
+ #line 317 "pitchfork_http.rl"
464
+ {MARK(mark, p); }
465
+ goto st4;
466
+ st4:
467
+ if ( ++p == pe )
468
+ goto _test_eof4;
469
+ case 4:
470
+ #line 471 "pitchfork_http.c"
471
+ switch( (*p) ) {
472
+ case 32: goto tr8;
473
+ case 35: goto tr9;
474
+ }
475
+ goto st0;
476
+ tr8:
477
+ #line 331 "pitchfork_http.rl"
478
+ {
479
+ VALUE str;
480
+
481
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
482
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
483
+ /*
484
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
485
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
486
+ */
487
+ if (STR_CSTR_EQ(str, "*")) {
488
+ str = rb_str_new(NULL, 0);
489
+ rb_hash_aset(hp->env, g_path_info, str);
490
+ rb_hash_aset(hp->env, g_request_path, str);
491
+ }
492
+ }
493
+ goto st5;
494
+ tr41:
495
+ #line 317 "pitchfork_http.rl"
496
+ {MARK(mark, p); }
497
+ #line 346 "pitchfork_http.rl"
498
+ {
499
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
500
+ rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
501
+ }
502
+ goto st5;
503
+ tr44:
504
+ #line 346 "pitchfork_http.rl"
505
+ {
506
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
507
+ rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
508
+ }
509
+ goto st5;
510
+ tr48:
511
+ #line 356 "pitchfork_http.rl"
512
+ {
513
+ VALUE val;
514
+
515
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
516
+ val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
517
+
518
+ /* rack says PATH_INFO must start with "/" or be empty */
519
+ if (!STR_CSTR_EQ(val, "*"))
520
+ rb_hash_aset(hp->env, g_path_info, val);
521
+ }
522
+ #line 331 "pitchfork_http.rl"
523
+ {
524
+ VALUE str;
525
+
526
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
527
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
528
+ /*
529
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
530
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
531
+ */
532
+ if (STR_CSTR_EQ(str, "*")) {
533
+ str = rb_str_new(NULL, 0);
534
+ rb_hash_aset(hp->env, g_path_info, str);
535
+ rb_hash_aset(hp->env, g_request_path, str);
536
+ }
537
+ }
538
+ goto st5;
539
+ tr54:
540
+ #line 350 "pitchfork_http.rl"
541
+ {MARK(start.query, p); }
542
+ #line 351 "pitchfork_http.rl"
543
+ {
544
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
545
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
546
+ }
547
+ #line 331 "pitchfork_http.rl"
548
+ {
549
+ VALUE str;
550
+
551
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
552
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
553
+ /*
554
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
555
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
556
+ */
557
+ if (STR_CSTR_EQ(str, "*")) {
558
+ str = rb_str_new(NULL, 0);
559
+ rb_hash_aset(hp->env, g_path_info, str);
560
+ rb_hash_aset(hp->env, g_request_path, str);
561
+ }
562
+ }
563
+ goto st5;
564
+ tr58:
565
+ #line 351 "pitchfork_http.rl"
566
+ {
567
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
568
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
569
+ }
570
+ #line 331 "pitchfork_http.rl"
571
+ {
572
+ VALUE str;
573
+
574
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
575
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
576
+ /*
577
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
578
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
579
+ */
580
+ if (STR_CSTR_EQ(str, "*")) {
581
+ str = rb_str_new(NULL, 0);
582
+ rb_hash_aset(hp->env, g_path_info, str);
583
+ rb_hash_aset(hp->env, g_request_path, str);
584
+ }
585
+ }
586
+ goto st5;
587
+ st5:
588
+ if ( ++p == pe )
589
+ goto _test_eof5;
590
+ case 5:
591
+ #line 592 "pitchfork_http.c"
592
+ if ( (*p) == 72 )
593
+ goto tr10;
594
+ goto st0;
595
+ tr10:
596
+ #line 317 "pitchfork_http.rl"
597
+ {MARK(mark, p); }
598
+ goto st6;
599
+ st6:
600
+ if ( ++p == pe )
601
+ goto _test_eof6;
602
+ case 6:
603
+ #line 604 "pitchfork_http.c"
604
+ if ( (*p) == 84 )
605
+ goto st7;
606
+ goto st0;
607
+ st7:
608
+ if ( ++p == pe )
609
+ goto _test_eof7;
610
+ case 7:
611
+ if ( (*p) == 84 )
612
+ goto st8;
613
+ goto st0;
614
+ st8:
615
+ if ( ++p == pe )
616
+ goto _test_eof8;
617
+ case 8:
618
+ if ( (*p) == 80 )
619
+ goto st9;
620
+ goto st0;
621
+ st9:
622
+ if ( ++p == pe )
623
+ goto _test_eof9;
624
+ case 9:
625
+ if ( (*p) == 47 )
626
+ goto st10;
627
+ goto st0;
628
+ st10:
629
+ if ( ++p == pe )
630
+ goto _test_eof10;
631
+ case 10:
632
+ if ( 48 <= (*p) && (*p) <= 57 )
633
+ goto st11;
634
+ goto st0;
635
+ st11:
636
+ if ( ++p == pe )
637
+ goto _test_eof11;
638
+ case 11:
639
+ if ( (*p) == 46 )
640
+ goto st12;
641
+ if ( 48 <= (*p) && (*p) <= 57 )
642
+ goto st11;
643
+ goto st0;
644
+ st12:
645
+ if ( ++p == pe )
646
+ goto _test_eof12;
647
+ case 12:
648
+ if ( 48 <= (*p) && (*p) <= 57 )
649
+ goto st13;
650
+ goto st0;
651
+ st13:
652
+ if ( ++p == pe )
653
+ goto _test_eof13;
654
+ case 13:
655
+ switch( (*p) ) {
656
+ case 10: goto tr18;
657
+ case 13: goto tr19;
658
+ }
659
+ if ( 48 <= (*p) && (*p) <= 57 )
660
+ goto st13;
661
+ goto st0;
662
+ tr18:
663
+ #line 355 "pitchfork_http.rl"
664
+ { http_version(hp, PTR_TO(mark), LEN(mark, p)); }
665
+ goto st14;
666
+ tr25:
667
+ #line 323 "pitchfork_http.rl"
668
+ { MARK(mark, p); }
669
+ #line 325 "pitchfork_http.rl"
670
+ { write_cont_value(hp, buffer, p); }
671
+ goto st14;
672
+ tr30:
673
+ #line 325 "pitchfork_http.rl"
674
+ { write_cont_value(hp, buffer, p); }
675
+ goto st14;
676
+ tr35:
677
+ #line 323 "pitchfork_http.rl"
678
+ { MARK(mark, p); }
679
+ #line 324 "pitchfork_http.rl"
680
+ { write_value(hp, buffer, p); }
681
+ goto st14;
682
+ tr39:
683
+ #line 324 "pitchfork_http.rl"
684
+ { write_value(hp, buffer, p); }
685
+ goto st14;
686
+ st14:
687
+ if ( ++p == pe )
688
+ goto _test_eof14;
689
+ case 14:
690
+ #line 691 "pitchfork_http.c"
691
+ switch( (*p) ) {
692
+ case 9: goto st15;
693
+ case 10: goto tr21;
694
+ case 13: goto st18;
695
+ case 32: goto st15;
696
+ case 33: goto tr23;
697
+ case 124: goto tr23;
698
+ case 126: goto tr23;
699
+ }
700
+ if ( (*p) < 45 ) {
701
+ if ( (*p) > 39 ) {
702
+ if ( 42 <= (*p) && (*p) <= 43 )
703
+ goto tr23;
704
+ } else if ( (*p) >= 35 )
705
+ goto tr23;
706
+ } else if ( (*p) > 46 ) {
707
+ if ( (*p) < 65 ) {
708
+ if ( 48 <= (*p) && (*p) <= 57 )
709
+ goto tr23;
710
+ } else if ( (*p) > 90 ) {
711
+ if ( 94 <= (*p) && (*p) <= 122 )
712
+ goto tr23;
713
+ } else
714
+ goto tr23;
715
+ } else
716
+ goto tr23;
717
+ goto st0;
718
+ tr24:
719
+ #line 323 "pitchfork_http.rl"
720
+ { MARK(mark, p); }
721
+ goto st15;
722
+ st15:
723
+ if ( ++p == pe )
724
+ goto _test_eof15;
725
+ case 15:
726
+ #line 727 "pitchfork_http.c"
727
+ switch( (*p) ) {
728
+ case 9: goto tr24;
729
+ case 10: goto tr25;
730
+ case 13: goto tr26;
731
+ case 32: goto tr24;
732
+ case 127: goto st0;
733
+ }
734
+ if ( (*p) <= 31 )
735
+ goto st0;
736
+ goto tr27;
737
+ tr19:
738
+ #line 355 "pitchfork_http.rl"
739
+ { http_version(hp, PTR_TO(mark), LEN(mark, p)); }
740
+ goto st16;
741
+ tr26:
742
+ #line 323 "pitchfork_http.rl"
743
+ { MARK(mark, p); }
744
+ #line 325 "pitchfork_http.rl"
745
+ { write_cont_value(hp, buffer, p); }
746
+ goto st16;
747
+ tr31:
748
+ #line 325 "pitchfork_http.rl"
749
+ { write_cont_value(hp, buffer, p); }
750
+ goto st16;
751
+ tr36:
752
+ #line 323 "pitchfork_http.rl"
753
+ { MARK(mark, p); }
754
+ #line 324 "pitchfork_http.rl"
755
+ { write_value(hp, buffer, p); }
756
+ goto st16;
757
+ tr40:
758
+ #line 324 "pitchfork_http.rl"
759
+ { write_value(hp, buffer, p); }
760
+ goto st16;
761
+ st16:
762
+ if ( ++p == pe )
763
+ goto _test_eof16;
764
+ case 16:
765
+ #line 766 "pitchfork_http.c"
766
+ if ( (*p) == 10 )
767
+ goto st14;
768
+ goto st0;
769
+ tr27:
770
+ #line 323 "pitchfork_http.rl"
771
+ { MARK(mark, p); }
772
+ goto st17;
773
+ st17:
774
+ if ( ++p == pe )
775
+ goto _test_eof17;
776
+ case 17:
777
+ #line 778 "pitchfork_http.c"
778
+ switch( (*p) ) {
779
+ case 10: goto tr30;
780
+ case 13: goto tr31;
781
+ case 127: goto st0;
782
+ }
783
+ if ( (*p) > 8 ) {
784
+ if ( 11 <= (*p) && (*p) <= 31 )
785
+ goto st0;
786
+ } else
787
+ goto st0;
788
+ goto st17;
789
+ tr21:
790
+ #line 371 "pitchfork_http.rl"
791
+ {
792
+ finalize_header(hp);
793
+
794
+ cs = http_parser_first_final;
795
+ if (HP_FL_TEST(hp, HASBODY)) {
796
+ HP_FL_SET(hp, INBODY);
797
+ if (HP_FL_TEST(hp, CHUNKED))
798
+ cs = http_parser_en_ChunkedBody;
799
+ } else {
800
+ HP_FL_SET(hp, REQEOF);
801
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
802
+ }
803
+ /*
804
+ * go back to Ruby so we can call the Rack application, we'll reenter
805
+ * the parser iff the body needs to be processed.
806
+ */
807
+ goto post_exec;
808
+ }
809
+ goto st122;
810
+ tr104:
811
+ #line 331 "pitchfork_http.rl"
812
+ {
813
+ VALUE str;
814
+
815
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
816
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
817
+ /*
818
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
819
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
820
+ */
821
+ if (STR_CSTR_EQ(str, "*")) {
822
+ str = rb_str_new(NULL, 0);
823
+ rb_hash_aset(hp->env, g_path_info, str);
824
+ rb_hash_aset(hp->env, g_request_path, str);
825
+ }
826
+ }
827
+ #line 371 "pitchfork_http.rl"
828
+ {
829
+ finalize_header(hp);
830
+
831
+ cs = http_parser_first_final;
832
+ if (HP_FL_TEST(hp, HASBODY)) {
833
+ HP_FL_SET(hp, INBODY);
834
+ if (HP_FL_TEST(hp, CHUNKED))
835
+ cs = http_parser_en_ChunkedBody;
836
+ } else {
837
+ HP_FL_SET(hp, REQEOF);
838
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
839
+ }
840
+ /*
841
+ * go back to Ruby so we can call the Rack application, we'll reenter
842
+ * the parser iff the body needs to be processed.
843
+ */
844
+ goto post_exec;
845
+ }
846
+ goto st122;
847
+ tr107:
848
+ #line 317 "pitchfork_http.rl"
849
+ {MARK(mark, p); }
850
+ #line 346 "pitchfork_http.rl"
851
+ {
852
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
853
+ rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
854
+ }
855
+ #line 371 "pitchfork_http.rl"
856
+ {
857
+ finalize_header(hp);
858
+
859
+ cs = http_parser_first_final;
860
+ if (HP_FL_TEST(hp, HASBODY)) {
861
+ HP_FL_SET(hp, INBODY);
862
+ if (HP_FL_TEST(hp, CHUNKED))
863
+ cs = http_parser_en_ChunkedBody;
864
+ } else {
865
+ HP_FL_SET(hp, REQEOF);
866
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
867
+ }
868
+ /*
869
+ * go back to Ruby so we can call the Rack application, we'll reenter
870
+ * the parser iff the body needs to be processed.
871
+ */
872
+ goto post_exec;
873
+ }
874
+ goto st122;
875
+ tr111:
876
+ #line 346 "pitchfork_http.rl"
877
+ {
878
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
879
+ rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
880
+ }
881
+ #line 371 "pitchfork_http.rl"
882
+ {
883
+ finalize_header(hp);
884
+
885
+ cs = http_parser_first_final;
886
+ if (HP_FL_TEST(hp, HASBODY)) {
887
+ HP_FL_SET(hp, INBODY);
888
+ if (HP_FL_TEST(hp, CHUNKED))
889
+ cs = http_parser_en_ChunkedBody;
890
+ } else {
891
+ HP_FL_SET(hp, REQEOF);
892
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
893
+ }
894
+ /*
895
+ * go back to Ruby so we can call the Rack application, we'll reenter
896
+ * the parser iff the body needs to be processed.
897
+ */
898
+ goto post_exec;
899
+ }
900
+ goto st122;
901
+ tr116:
902
+ #line 356 "pitchfork_http.rl"
903
+ {
904
+ VALUE val;
905
+
906
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
907
+ val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
908
+
909
+ /* rack says PATH_INFO must start with "/" or be empty */
910
+ if (!STR_CSTR_EQ(val, "*"))
911
+ rb_hash_aset(hp->env, g_path_info, val);
912
+ }
913
+ #line 331 "pitchfork_http.rl"
914
+ {
915
+ VALUE str;
916
+
917
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
918
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
919
+ /*
920
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
921
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
922
+ */
923
+ if (STR_CSTR_EQ(str, "*")) {
924
+ str = rb_str_new(NULL, 0);
925
+ rb_hash_aset(hp->env, g_path_info, str);
926
+ rb_hash_aset(hp->env, g_request_path, str);
927
+ }
928
+ }
929
+ #line 371 "pitchfork_http.rl"
930
+ {
931
+ finalize_header(hp);
932
+
933
+ cs = http_parser_first_final;
934
+ if (HP_FL_TEST(hp, HASBODY)) {
935
+ HP_FL_SET(hp, INBODY);
936
+ if (HP_FL_TEST(hp, CHUNKED))
937
+ cs = http_parser_en_ChunkedBody;
938
+ } else {
939
+ HP_FL_SET(hp, REQEOF);
940
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
941
+ }
942
+ /*
943
+ * go back to Ruby so we can call the Rack application, we'll reenter
944
+ * the parser iff the body needs to be processed.
945
+ */
946
+ goto post_exec;
947
+ }
948
+ goto st122;
949
+ tr123:
950
+ #line 350 "pitchfork_http.rl"
951
+ {MARK(start.query, p); }
952
+ #line 351 "pitchfork_http.rl"
953
+ {
954
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
955
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
956
+ }
957
+ #line 331 "pitchfork_http.rl"
958
+ {
959
+ VALUE str;
960
+
961
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
962
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
963
+ /*
964
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
965
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
966
+ */
967
+ if (STR_CSTR_EQ(str, "*")) {
968
+ str = rb_str_new(NULL, 0);
969
+ rb_hash_aset(hp->env, g_path_info, str);
970
+ rb_hash_aset(hp->env, g_request_path, str);
971
+ }
972
+ }
973
+ #line 371 "pitchfork_http.rl"
974
+ {
975
+ finalize_header(hp);
976
+
977
+ cs = http_parser_first_final;
978
+ if (HP_FL_TEST(hp, HASBODY)) {
979
+ HP_FL_SET(hp, INBODY);
980
+ if (HP_FL_TEST(hp, CHUNKED))
981
+ cs = http_parser_en_ChunkedBody;
982
+ } else {
983
+ HP_FL_SET(hp, REQEOF);
984
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
985
+ }
986
+ /*
987
+ * go back to Ruby so we can call the Rack application, we'll reenter
988
+ * the parser iff the body needs to be processed.
989
+ */
990
+ goto post_exec;
991
+ }
992
+ goto st122;
993
+ tr128:
994
+ #line 351 "pitchfork_http.rl"
995
+ {
996
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
997
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
998
+ }
999
+ #line 331 "pitchfork_http.rl"
1000
+ {
1001
+ VALUE str;
1002
+
1003
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1004
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1005
+ /*
1006
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1007
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1008
+ */
1009
+ if (STR_CSTR_EQ(str, "*")) {
1010
+ str = rb_str_new(NULL, 0);
1011
+ rb_hash_aset(hp->env, g_path_info, str);
1012
+ rb_hash_aset(hp->env, g_request_path, str);
1013
+ }
1014
+ }
1015
+ #line 371 "pitchfork_http.rl"
1016
+ {
1017
+ finalize_header(hp);
1018
+
1019
+ cs = http_parser_first_final;
1020
+ if (HP_FL_TEST(hp, HASBODY)) {
1021
+ HP_FL_SET(hp, INBODY);
1022
+ if (HP_FL_TEST(hp, CHUNKED))
1023
+ cs = http_parser_en_ChunkedBody;
1024
+ } else {
1025
+ HP_FL_SET(hp, REQEOF);
1026
+ assert(!HP_FL_TEST(hp, CHUNKED) && "chunked encoding without body!");
1027
+ }
1028
+ /*
1029
+ * go back to Ruby so we can call the Rack application, we'll reenter
1030
+ * the parser iff the body needs to be processed.
1031
+ */
1032
+ goto post_exec;
1033
+ }
1034
+ goto st122;
1035
+ st122:
1036
+ if ( ++p == pe )
1037
+ goto _test_eof122;
1038
+ case 122:
1039
+ #line 1040 "pitchfork_http.c"
1040
+ goto st0;
1041
+ tr105:
1042
+ #line 331 "pitchfork_http.rl"
1043
+ {
1044
+ VALUE str;
1045
+
1046
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1047
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1048
+ /*
1049
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1050
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1051
+ */
1052
+ if (STR_CSTR_EQ(str, "*")) {
1053
+ str = rb_str_new(NULL, 0);
1054
+ rb_hash_aset(hp->env, g_path_info, str);
1055
+ rb_hash_aset(hp->env, g_request_path, str);
1056
+ }
1057
+ }
1058
+ goto st18;
1059
+ tr108:
1060
+ #line 317 "pitchfork_http.rl"
1061
+ {MARK(mark, p); }
1062
+ #line 346 "pitchfork_http.rl"
1063
+ {
1064
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
1065
+ rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
1066
+ }
1067
+ goto st18;
1068
+ tr112:
1069
+ #line 346 "pitchfork_http.rl"
1070
+ {
1071
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT);
1072
+ rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p));
1073
+ }
1074
+ goto st18;
1075
+ tr117:
1076
+ #line 356 "pitchfork_http.rl"
1077
+ {
1078
+ VALUE val;
1079
+
1080
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
1081
+ val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
1082
+
1083
+ /* rack says PATH_INFO must start with "/" or be empty */
1084
+ if (!STR_CSTR_EQ(val, "*"))
1085
+ rb_hash_aset(hp->env, g_path_info, val);
1086
+ }
1087
+ #line 331 "pitchfork_http.rl"
1088
+ {
1089
+ VALUE str;
1090
+
1091
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1092
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1093
+ /*
1094
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1095
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1096
+ */
1097
+ if (STR_CSTR_EQ(str, "*")) {
1098
+ str = rb_str_new(NULL, 0);
1099
+ rb_hash_aset(hp->env, g_path_info, str);
1100
+ rb_hash_aset(hp->env, g_request_path, str);
1101
+ }
1102
+ }
1103
+ goto st18;
1104
+ tr124:
1105
+ #line 350 "pitchfork_http.rl"
1106
+ {MARK(start.query, p); }
1107
+ #line 351 "pitchfork_http.rl"
1108
+ {
1109
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1110
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1111
+ }
1112
+ #line 331 "pitchfork_http.rl"
1113
+ {
1114
+ VALUE str;
1115
+
1116
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1117
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1118
+ /*
1119
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1120
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1121
+ */
1122
+ if (STR_CSTR_EQ(str, "*")) {
1123
+ str = rb_str_new(NULL, 0);
1124
+ rb_hash_aset(hp->env, g_path_info, str);
1125
+ rb_hash_aset(hp->env, g_request_path, str);
1126
+ }
1127
+ }
1128
+ goto st18;
1129
+ tr129:
1130
+ #line 351 "pitchfork_http.rl"
1131
+ {
1132
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1133
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1134
+ }
1135
+ #line 331 "pitchfork_http.rl"
1136
+ {
1137
+ VALUE str;
1138
+
1139
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1140
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1141
+ /*
1142
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1143
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1144
+ */
1145
+ if (STR_CSTR_EQ(str, "*")) {
1146
+ str = rb_str_new(NULL, 0);
1147
+ rb_hash_aset(hp->env, g_path_info, str);
1148
+ rb_hash_aset(hp->env, g_request_path, str);
1149
+ }
1150
+ }
1151
+ goto st18;
1152
+ st18:
1153
+ if ( ++p == pe )
1154
+ goto _test_eof18;
1155
+ case 18:
1156
+ #line 1157 "pitchfork_http.c"
1157
+ if ( (*p) == 10 )
1158
+ goto tr21;
1159
+ goto st0;
1160
+ tr23:
1161
+ #line 319 "pitchfork_http.rl"
1162
+ { MARK(start.field, p); }
1163
+ #line 320 "pitchfork_http.rl"
1164
+ { snake_upcase_char(deconst(p)); }
1165
+ goto st19;
1166
+ tr32:
1167
+ #line 320 "pitchfork_http.rl"
1168
+ { snake_upcase_char(deconst(p)); }
1169
+ goto st19;
1170
+ st19:
1171
+ if ( ++p == pe )
1172
+ goto _test_eof19;
1173
+ case 19:
1174
+ #line 1175 "pitchfork_http.c"
1175
+ switch( (*p) ) {
1176
+ case 33: goto tr32;
1177
+ case 58: goto tr33;
1178
+ case 124: goto tr32;
1179
+ case 126: goto tr32;
1180
+ }
1181
+ if ( (*p) < 45 ) {
1182
+ if ( (*p) > 39 ) {
1183
+ if ( 42 <= (*p) && (*p) <= 43 )
1184
+ goto tr32;
1185
+ } else if ( (*p) >= 35 )
1186
+ goto tr32;
1187
+ } else if ( (*p) > 46 ) {
1188
+ if ( (*p) < 65 ) {
1189
+ if ( 48 <= (*p) && (*p) <= 57 )
1190
+ goto tr32;
1191
+ } else if ( (*p) > 90 ) {
1192
+ if ( 94 <= (*p) && (*p) <= 122 )
1193
+ goto tr32;
1194
+ } else
1195
+ goto tr32;
1196
+ } else
1197
+ goto tr32;
1198
+ goto st0;
1199
+ tr34:
1200
+ #line 323 "pitchfork_http.rl"
1201
+ { MARK(mark, p); }
1202
+ goto st20;
1203
+ tr33:
1204
+ #line 322 "pitchfork_http.rl"
1205
+ { hp->s.field_len = LEN(start.field, p); }
1206
+ goto st20;
1207
+ st20:
1208
+ if ( ++p == pe )
1209
+ goto _test_eof20;
1210
+ case 20:
1211
+ #line 1212 "pitchfork_http.c"
1212
+ switch( (*p) ) {
1213
+ case 9: goto tr34;
1214
+ case 10: goto tr35;
1215
+ case 13: goto tr36;
1216
+ case 32: goto tr34;
1217
+ case 127: goto st0;
1218
+ }
1219
+ if ( (*p) <= 31 )
1220
+ goto st0;
1221
+ goto tr37;
1222
+ tr37:
1223
+ #line 323 "pitchfork_http.rl"
1224
+ { MARK(mark, p); }
1225
+ goto st21;
1226
+ st21:
1227
+ if ( ++p == pe )
1228
+ goto _test_eof21;
1229
+ case 21:
1230
+ #line 1231 "pitchfork_http.c"
1231
+ switch( (*p) ) {
1232
+ case 10: goto tr39;
1233
+ case 13: goto tr40;
1234
+ case 127: goto st0;
1235
+ }
1236
+ if ( (*p) > 8 ) {
1237
+ if ( 11 <= (*p) && (*p) <= 31 )
1238
+ goto st0;
1239
+ } else
1240
+ goto st0;
1241
+ goto st21;
1242
+ tr9:
1243
+ #line 331 "pitchfork_http.rl"
1244
+ {
1245
+ VALUE str;
1246
+
1247
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1248
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1249
+ /*
1250
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1251
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1252
+ */
1253
+ if (STR_CSTR_EQ(str, "*")) {
1254
+ str = rb_str_new(NULL, 0);
1255
+ rb_hash_aset(hp->env, g_path_info, str);
1256
+ rb_hash_aset(hp->env, g_request_path, str);
1257
+ }
1258
+ }
1259
+ goto st22;
1260
+ tr50:
1261
+ #line 356 "pitchfork_http.rl"
1262
+ {
1263
+ VALUE val;
1264
+
1265
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
1266
+ val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
1267
+
1268
+ /* rack says PATH_INFO must start with "/" or be empty */
1269
+ if (!STR_CSTR_EQ(val, "*"))
1270
+ rb_hash_aset(hp->env, g_path_info, val);
1271
+ }
1272
+ #line 331 "pitchfork_http.rl"
1273
+ {
1274
+ VALUE str;
1275
+
1276
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1277
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1278
+ /*
1279
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1280
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1281
+ */
1282
+ if (STR_CSTR_EQ(str, "*")) {
1283
+ str = rb_str_new(NULL, 0);
1284
+ rb_hash_aset(hp->env, g_path_info, str);
1285
+ rb_hash_aset(hp->env, g_request_path, str);
1286
+ }
1287
+ }
1288
+ goto st22;
1289
+ tr56:
1290
+ #line 350 "pitchfork_http.rl"
1291
+ {MARK(start.query, p); }
1292
+ #line 351 "pitchfork_http.rl"
1293
+ {
1294
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1295
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1296
+ }
1297
+ #line 331 "pitchfork_http.rl"
1298
+ {
1299
+ VALUE str;
1300
+
1301
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1302
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1303
+ /*
1304
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1305
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1306
+ */
1307
+ if (STR_CSTR_EQ(str, "*")) {
1308
+ str = rb_str_new(NULL, 0);
1309
+ rb_hash_aset(hp->env, g_path_info, str);
1310
+ rb_hash_aset(hp->env, g_request_path, str);
1311
+ }
1312
+ }
1313
+ goto st22;
1314
+ tr60:
1315
+ #line 351 "pitchfork_http.rl"
1316
+ {
1317
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
1318
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
1319
+ }
1320
+ #line 331 "pitchfork_http.rl"
1321
+ {
1322
+ VALUE str;
1323
+
1324
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
1325
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
1326
+ /*
1327
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
1328
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
1329
+ */
1330
+ if (STR_CSTR_EQ(str, "*")) {
1331
+ str = rb_str_new(NULL, 0);
1332
+ rb_hash_aset(hp->env, g_path_info, str);
1333
+ rb_hash_aset(hp->env, g_request_path, str);
1334
+ }
1335
+ }
1336
+ goto st22;
1337
+ st22:
1338
+ if ( ++p == pe )
1339
+ goto _test_eof22;
1340
+ case 22:
1341
+ #line 1342 "pitchfork_http.c"
1342
+ switch( (*p) ) {
1343
+ case 32: goto tr41;
1344
+ case 35: goto st0;
1345
+ case 37: goto tr43;
1346
+ case 127: goto st0;
1347
+ }
1348
+ if ( (*p) <= 31 )
1349
+ goto st0;
1350
+ goto tr42;
1351
+ tr42:
1352
+ #line 317 "pitchfork_http.rl"
1353
+ {MARK(mark, p); }
1354
+ goto st23;
1355
+ st23:
1356
+ if ( ++p == pe )
1357
+ goto _test_eof23;
1358
+ case 23:
1359
+ #line 1360 "pitchfork_http.c"
1360
+ switch( (*p) ) {
1361
+ case 32: goto tr44;
1362
+ case 35: goto st0;
1363
+ case 37: goto st24;
1364
+ case 127: goto st0;
1365
+ }
1366
+ if ( (*p) <= 31 )
1367
+ goto st0;
1368
+ goto st23;
1369
+ tr43:
1370
+ #line 317 "pitchfork_http.rl"
1371
+ {MARK(mark, p); }
1372
+ goto st24;
1373
+ st24:
1374
+ if ( ++p == pe )
1375
+ goto _test_eof24;
1376
+ case 24:
1377
+ #line 1378 "pitchfork_http.c"
1378
+ if ( (*p) < 65 ) {
1379
+ if ( 48 <= (*p) && (*p) <= 57 )
1380
+ goto st25;
1381
+ } else if ( (*p) > 70 ) {
1382
+ if ( 97 <= (*p) && (*p) <= 102 )
1383
+ goto st25;
1384
+ } else
1385
+ goto st25;
1386
+ goto st0;
1387
+ st25:
1388
+ if ( ++p == pe )
1389
+ goto _test_eof25;
1390
+ case 25:
1391
+ if ( (*p) < 65 ) {
1392
+ if ( 48 <= (*p) && (*p) <= 57 )
1393
+ goto st23;
1394
+ } else if ( (*p) > 70 ) {
1395
+ if ( 97 <= (*p) && (*p) <= 102 )
1396
+ goto st23;
1397
+ } else
1398
+ goto st23;
1399
+ goto st0;
1400
+ tr6:
1401
+ #line 317 "pitchfork_http.rl"
1402
+ {MARK(mark, p); }
1403
+ goto st26;
1404
+ tr76:
1405
+ #line 330 "pitchfork_http.rl"
1406
+ { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
1407
+ #line 317 "pitchfork_http.rl"
1408
+ {MARK(mark, p); }
1409
+ goto st26;
1410
+ st26:
1411
+ if ( ++p == pe )
1412
+ goto _test_eof26;
1413
+ case 26:
1414
+ #line 1415 "pitchfork_http.c"
1415
+ switch( (*p) ) {
1416
+ case 32: goto tr48;
1417
+ case 35: goto tr50;
1418
+ case 37: goto st27;
1419
+ case 63: goto tr52;
1420
+ case 127: goto st0;
1421
+ }
1422
+ if ( (*p) <= 31 )
1423
+ goto st0;
1424
+ goto st26;
1425
+ st27:
1426
+ if ( ++p == pe )
1427
+ goto _test_eof27;
1428
+ case 27:
1429
+ if ( (*p) < 65 ) {
1430
+ if ( 48 <= (*p) && (*p) <= 57 )
1431
+ goto st28;
1432
+ } else if ( (*p) > 70 ) {
1433
+ if ( 97 <= (*p) && (*p) <= 102 )
1434
+ goto st28;
1435
+ } else
1436
+ goto st28;
1437
+ goto st0;
1438
+ st28:
1439
+ if ( ++p == pe )
1440
+ goto _test_eof28;
1441
+ case 28:
1442
+ if ( (*p) < 65 ) {
1443
+ if ( 48 <= (*p) && (*p) <= 57 )
1444
+ goto st26;
1445
+ } else if ( (*p) > 70 ) {
1446
+ if ( 97 <= (*p) && (*p) <= 102 )
1447
+ goto st26;
1448
+ } else
1449
+ goto st26;
1450
+ goto st0;
1451
+ tr52:
1452
+ #line 356 "pitchfork_http.rl"
1453
+ {
1454
+ VALUE val;
1455
+
1456
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
1457
+ val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
1458
+
1459
+ /* rack says PATH_INFO must start with "/" or be empty */
1460
+ if (!STR_CSTR_EQ(val, "*"))
1461
+ rb_hash_aset(hp->env, g_path_info, val);
1462
+ }
1463
+ goto st29;
1464
+ st29:
1465
+ if ( ++p == pe )
1466
+ goto _test_eof29;
1467
+ case 29:
1468
+ #line 1469 "pitchfork_http.c"
1469
+ switch( (*p) ) {
1470
+ case 32: goto tr54;
1471
+ case 35: goto tr56;
1472
+ case 37: goto tr57;
1473
+ case 127: goto st0;
1474
+ }
1475
+ if ( (*p) <= 31 )
1476
+ goto st0;
1477
+ goto tr55;
1478
+ tr55:
1479
+ #line 350 "pitchfork_http.rl"
1480
+ {MARK(start.query, p); }
1481
+ goto st30;
1482
+ st30:
1483
+ if ( ++p == pe )
1484
+ goto _test_eof30;
1485
+ case 30:
1486
+ #line 1487 "pitchfork_http.c"
1487
+ switch( (*p) ) {
1488
+ case 32: goto tr58;
1489
+ case 35: goto tr60;
1490
+ case 37: goto st31;
1491
+ case 127: goto st0;
1492
+ }
1493
+ if ( (*p) <= 31 )
1494
+ goto st0;
1495
+ goto st30;
1496
+ tr57:
1497
+ #line 350 "pitchfork_http.rl"
1498
+ {MARK(start.query, p); }
1499
+ goto st31;
1500
+ st31:
1501
+ if ( ++p == pe )
1502
+ goto _test_eof31;
1503
+ case 31:
1504
+ #line 1505 "pitchfork_http.c"
1505
+ if ( (*p) < 65 ) {
1506
+ if ( 48 <= (*p) && (*p) <= 57 )
1507
+ goto st32;
1508
+ } else if ( (*p) > 70 ) {
1509
+ if ( 97 <= (*p) && (*p) <= 102 )
1510
+ goto st32;
1511
+ } else
1512
+ goto st32;
1513
+ goto st0;
1514
+ st32:
1515
+ if ( ++p == pe )
1516
+ goto _test_eof32;
1517
+ case 32:
1518
+ if ( (*p) < 65 ) {
1519
+ if ( 48 <= (*p) && (*p) <= 57 )
1520
+ goto st30;
1521
+ } else if ( (*p) > 70 ) {
1522
+ if ( 97 <= (*p) && (*p) <= 102 )
1523
+ goto st30;
1524
+ } else
1525
+ goto st30;
1526
+ goto st0;
1527
+ tr7:
1528
+ #line 317 "pitchfork_http.rl"
1529
+ {MARK(mark, p); }
1530
+ #line 321 "pitchfork_http.rl"
1531
+ { downcase_char(deconst(p)); }
1532
+ goto st33;
1533
+ st33:
1534
+ if ( ++p == pe )
1535
+ goto _test_eof33;
1536
+ case 33:
1537
+ #line 1538 "pitchfork_http.c"
1538
+ switch( (*p) ) {
1539
+ case 84: goto tr63;
1540
+ case 116: goto tr63;
1541
+ }
1542
+ goto st0;
1543
+ tr63:
1544
+ #line 321 "pitchfork_http.rl"
1545
+ { downcase_char(deconst(p)); }
1546
+ goto st34;
1547
+ st34:
1548
+ if ( ++p == pe )
1549
+ goto _test_eof34;
1550
+ case 34:
1551
+ #line 1552 "pitchfork_http.c"
1552
+ switch( (*p) ) {
1553
+ case 84: goto tr64;
1554
+ case 116: goto tr64;
1555
+ }
1556
+ goto st0;
1557
+ tr64:
1558
+ #line 321 "pitchfork_http.rl"
1559
+ { downcase_char(deconst(p)); }
1560
+ goto st35;
1561
+ st35:
1562
+ if ( ++p == pe )
1563
+ goto _test_eof35;
1564
+ case 35:
1565
+ #line 1566 "pitchfork_http.c"
1566
+ switch( (*p) ) {
1567
+ case 80: goto tr65;
1568
+ case 112: goto tr65;
1569
+ }
1570
+ goto st0;
1571
+ tr65:
1572
+ #line 321 "pitchfork_http.rl"
1573
+ { downcase_char(deconst(p)); }
1574
+ goto st36;
1575
+ st36:
1576
+ if ( ++p == pe )
1577
+ goto _test_eof36;
1578
+ case 36:
1579
+ #line 1580 "pitchfork_http.c"
1580
+ switch( (*p) ) {
1581
+ case 58: goto tr66;
1582
+ case 83: goto tr67;
1583
+ case 115: goto tr67;
1584
+ }
1585
+ goto st0;
1586
+ tr66:
1587
+ #line 327 "pitchfork_http.rl"
1588
+ {
1589
+ rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
1590
+ }
1591
+ goto st37;
1592
+ st37:
1593
+ if ( ++p == pe )
1594
+ goto _test_eof37;
1595
+ case 37:
1596
+ #line 1597 "pitchfork_http.c"
1597
+ if ( (*p) == 47 )
1598
+ goto st38;
1599
+ goto st0;
1600
+ st38:
1601
+ if ( ++p == pe )
1602
+ goto _test_eof38;
1603
+ case 38:
1604
+ if ( (*p) == 47 )
1605
+ goto st39;
1606
+ goto st0;
1607
+ st39:
1608
+ if ( ++p == pe )
1609
+ goto _test_eof39;
1610
+ case 39:
1611
+ switch( (*p) ) {
1612
+ case 37: goto st41;
1613
+ case 47: goto st0;
1614
+ case 60: goto st0;
1615
+ case 91: goto tr73;
1616
+ case 95: goto tr72;
1617
+ case 127: goto st0;
1618
+ }
1619
+ if ( (*p) < 45 ) {
1620
+ if ( (*p) > 32 ) {
1621
+ if ( 34 <= (*p) && (*p) <= 35 )
1622
+ goto st0;
1623
+ } else
1624
+ goto st0;
1625
+ } else if ( (*p) > 57 ) {
1626
+ if ( (*p) < 65 ) {
1627
+ if ( 62 <= (*p) && (*p) <= 64 )
1628
+ goto st0;
1629
+ } else if ( (*p) > 90 ) {
1630
+ if ( 97 <= (*p) && (*p) <= 122 )
1631
+ goto tr72;
1632
+ } else
1633
+ goto tr72;
1634
+ } else
1635
+ goto tr72;
1636
+ goto st40;
1637
+ st40:
1638
+ if ( ++p == pe )
1639
+ goto _test_eof40;
1640
+ case 40:
1641
+ switch( (*p) ) {
1642
+ case 37: goto st41;
1643
+ case 47: goto st0;
1644
+ case 60: goto st0;
1645
+ case 64: goto st39;
1646
+ case 127: goto st0;
1647
+ }
1648
+ if ( (*p) < 34 ) {
1649
+ if ( (*p) <= 32 )
1650
+ goto st0;
1651
+ } else if ( (*p) > 35 ) {
1652
+ if ( 62 <= (*p) && (*p) <= 63 )
1653
+ goto st0;
1654
+ } else
1655
+ goto st0;
1656
+ goto st40;
1657
+ st41:
1658
+ if ( ++p == pe )
1659
+ goto _test_eof41;
1660
+ case 41:
1661
+ if ( (*p) < 65 ) {
1662
+ if ( 48 <= (*p) && (*p) <= 57 )
1663
+ goto st42;
1664
+ } else if ( (*p) > 70 ) {
1665
+ if ( 97 <= (*p) && (*p) <= 102 )
1666
+ goto st42;
1667
+ } else
1668
+ goto st42;
1669
+ goto st0;
1670
+ st42:
1671
+ if ( ++p == pe )
1672
+ goto _test_eof42;
1673
+ case 42:
1674
+ if ( (*p) < 65 ) {
1675
+ if ( 48 <= (*p) && (*p) <= 57 )
1676
+ goto st40;
1677
+ } else if ( (*p) > 70 ) {
1678
+ if ( 97 <= (*p) && (*p) <= 102 )
1679
+ goto st40;
1680
+ } else
1681
+ goto st40;
1682
+ goto st0;
1683
+ tr72:
1684
+ #line 317 "pitchfork_http.rl"
1685
+ {MARK(mark, p); }
1686
+ goto st43;
1687
+ st43:
1688
+ if ( ++p == pe )
1689
+ goto _test_eof43;
1690
+ case 43:
1691
+ #line 1692 "pitchfork_http.c"
1692
+ switch( (*p) ) {
1693
+ case 37: goto st41;
1694
+ case 47: goto tr76;
1695
+ case 58: goto st44;
1696
+ case 60: goto st0;
1697
+ case 64: goto st39;
1698
+ case 95: goto st43;
1699
+ case 127: goto st0;
1700
+ }
1701
+ if ( (*p) < 45 ) {
1702
+ if ( (*p) > 32 ) {
1703
+ if ( 34 <= (*p) && (*p) <= 35 )
1704
+ goto st0;
1705
+ } else
1706
+ goto st0;
1707
+ } else if ( (*p) > 57 ) {
1708
+ if ( (*p) < 65 ) {
1709
+ if ( 62 <= (*p) && (*p) <= 63 )
1710
+ goto st0;
1711
+ } else if ( (*p) > 90 ) {
1712
+ if ( 97 <= (*p) && (*p) <= 122 )
1713
+ goto st43;
1714
+ } else
1715
+ goto st43;
1716
+ } else
1717
+ goto st43;
1718
+ goto st40;
1719
+ st44:
1720
+ if ( ++p == pe )
1721
+ goto _test_eof44;
1722
+ case 44:
1723
+ switch( (*p) ) {
1724
+ case 37: goto st41;
1725
+ case 47: goto tr76;
1726
+ case 60: goto st0;
1727
+ case 64: goto st39;
1728
+ case 127: goto st0;
1729
+ }
1730
+ if ( (*p) < 34 ) {
1731
+ if ( (*p) <= 32 )
1732
+ goto st0;
1733
+ } else if ( (*p) > 35 ) {
1734
+ if ( (*p) > 57 ) {
1735
+ if ( 62 <= (*p) && (*p) <= 63 )
1736
+ goto st0;
1737
+ } else if ( (*p) >= 48 )
1738
+ goto st44;
1739
+ } else
1740
+ goto st0;
1741
+ goto st40;
1742
+ tr73:
1743
+ #line 317 "pitchfork_http.rl"
1744
+ {MARK(mark, p); }
1745
+ goto st45;
1746
+ st45:
1747
+ if ( ++p == pe )
1748
+ goto _test_eof45;
1749
+ case 45:
1750
+ #line 1751 "pitchfork_http.c"
1751
+ switch( (*p) ) {
1752
+ case 37: goto st41;
1753
+ case 47: goto st0;
1754
+ case 60: goto st0;
1755
+ case 64: goto st39;
1756
+ case 127: goto st0;
1757
+ }
1758
+ if ( (*p) < 48 ) {
1759
+ if ( (*p) > 32 ) {
1760
+ if ( 34 <= (*p) && (*p) <= 35 )
1761
+ goto st0;
1762
+ } else
1763
+ goto st0;
1764
+ } else if ( (*p) > 58 ) {
1765
+ if ( (*p) < 65 ) {
1766
+ if ( 62 <= (*p) && (*p) <= 63 )
1767
+ goto st0;
1768
+ } else if ( (*p) > 70 ) {
1769
+ if ( 97 <= (*p) && (*p) <= 102 )
1770
+ goto st46;
1771
+ } else
1772
+ goto st46;
1773
+ } else
1774
+ goto st46;
1775
+ goto st40;
1776
+ st46:
1777
+ if ( ++p == pe )
1778
+ goto _test_eof46;
1779
+ case 46:
1780
+ switch( (*p) ) {
1781
+ case 37: goto st41;
1782
+ case 47: goto st0;
1783
+ case 60: goto st0;
1784
+ case 64: goto st39;
1785
+ case 93: goto st47;
1786
+ case 127: goto st0;
1787
+ }
1788
+ if ( (*p) < 48 ) {
1789
+ if ( (*p) > 32 ) {
1790
+ if ( 34 <= (*p) && (*p) <= 35 )
1791
+ goto st0;
1792
+ } else
1793
+ goto st0;
1794
+ } else if ( (*p) > 58 ) {
1795
+ if ( (*p) < 65 ) {
1796
+ if ( 62 <= (*p) && (*p) <= 63 )
1797
+ goto st0;
1798
+ } else if ( (*p) > 70 ) {
1799
+ if ( 97 <= (*p) && (*p) <= 102 )
1800
+ goto st46;
1801
+ } else
1802
+ goto st46;
1803
+ } else
1804
+ goto st46;
1805
+ goto st40;
1806
+ st47:
1807
+ if ( ++p == pe )
1808
+ goto _test_eof47;
1809
+ case 47:
1810
+ switch( (*p) ) {
1811
+ case 37: goto st41;
1812
+ case 47: goto tr76;
1813
+ case 58: goto st44;
1814
+ case 60: goto st0;
1815
+ case 64: goto st39;
1816
+ case 127: goto st0;
1817
+ }
1818
+ if ( (*p) < 34 ) {
1819
+ if ( (*p) <= 32 )
1820
+ goto st0;
1821
+ } else if ( (*p) > 35 ) {
1822
+ if ( 62 <= (*p) && (*p) <= 63 )
1823
+ goto st0;
1824
+ } else
1825
+ goto st0;
1826
+ goto st40;
1827
+ tr67:
1828
+ #line 321 "pitchfork_http.rl"
1829
+ { downcase_char(deconst(p)); }
1830
+ goto st48;
1831
+ st48:
1832
+ if ( ++p == pe )
1833
+ goto _test_eof48;
1834
+ case 48:
1835
+ #line 1836 "pitchfork_http.c"
1836
+ if ( (*p) == 58 )
1837
+ goto tr66;
1838
+ goto st0;
1839
+ st49:
1840
+ if ( ++p == pe )
1841
+ goto _test_eof49;
1842
+ case 49:
1843
+ switch( (*p) ) {
1844
+ case 32: goto tr3;
1845
+ case 33: goto st50;
1846
+ case 124: goto st50;
1847
+ case 126: goto st50;
1848
+ }
1849
+ if ( (*p) < 45 ) {
1850
+ if ( (*p) > 39 ) {
1851
+ if ( 42 <= (*p) && (*p) <= 43 )
1852
+ goto st50;
1853
+ } else if ( (*p) >= 35 )
1854
+ goto st50;
1855
+ } else if ( (*p) > 46 ) {
1856
+ if ( (*p) < 65 ) {
1857
+ if ( 48 <= (*p) && (*p) <= 57 )
1858
+ goto st50;
1859
+ } else if ( (*p) > 90 ) {
1860
+ if ( 94 <= (*p) && (*p) <= 122 )
1861
+ goto st50;
1862
+ } else
1863
+ goto st50;
1864
+ } else
1865
+ goto st50;
1866
+ goto st0;
1867
+ st50:
1868
+ if ( ++p == pe )
1869
+ goto _test_eof50;
1870
+ case 50:
1871
+ switch( (*p) ) {
1872
+ case 32: goto tr3;
1873
+ case 33: goto st51;
1874
+ case 124: goto st51;
1875
+ case 126: goto st51;
1876
+ }
1877
+ if ( (*p) < 45 ) {
1878
+ if ( (*p) > 39 ) {
1879
+ if ( 42 <= (*p) && (*p) <= 43 )
1880
+ goto st51;
1881
+ } else if ( (*p) >= 35 )
1882
+ goto st51;
1883
+ } else if ( (*p) > 46 ) {
1884
+ if ( (*p) < 65 ) {
1885
+ if ( 48 <= (*p) && (*p) <= 57 )
1886
+ goto st51;
1887
+ } else if ( (*p) > 90 ) {
1888
+ if ( 94 <= (*p) && (*p) <= 122 )
1889
+ goto st51;
1890
+ } else
1891
+ goto st51;
1892
+ } else
1893
+ goto st51;
1894
+ goto st0;
1895
+ st51:
1896
+ if ( ++p == pe )
1897
+ goto _test_eof51;
1898
+ case 51:
1899
+ switch( (*p) ) {
1900
+ case 32: goto tr3;
1901
+ case 33: goto st52;
1902
+ case 124: goto st52;
1903
+ case 126: goto st52;
1904
+ }
1905
+ if ( (*p) < 45 ) {
1906
+ if ( (*p) > 39 ) {
1907
+ if ( 42 <= (*p) && (*p) <= 43 )
1908
+ goto st52;
1909
+ } else if ( (*p) >= 35 )
1910
+ goto st52;
1911
+ } else if ( (*p) > 46 ) {
1912
+ if ( (*p) < 65 ) {
1913
+ if ( 48 <= (*p) && (*p) <= 57 )
1914
+ goto st52;
1915
+ } else if ( (*p) > 90 ) {
1916
+ if ( 94 <= (*p) && (*p) <= 122 )
1917
+ goto st52;
1918
+ } else
1919
+ goto st52;
1920
+ } else
1921
+ goto st52;
1922
+ goto st0;
1923
+ st52:
1924
+ if ( ++p == pe )
1925
+ goto _test_eof52;
1926
+ case 52:
1927
+ switch( (*p) ) {
1928
+ case 32: goto tr3;
1929
+ case 33: goto st53;
1930
+ case 124: goto st53;
1931
+ case 126: goto st53;
1932
+ }
1933
+ if ( (*p) < 45 ) {
1934
+ if ( (*p) > 39 ) {
1935
+ if ( 42 <= (*p) && (*p) <= 43 )
1936
+ goto st53;
1937
+ } else if ( (*p) >= 35 )
1938
+ goto st53;
1939
+ } else if ( (*p) > 46 ) {
1940
+ if ( (*p) < 65 ) {
1941
+ if ( 48 <= (*p) && (*p) <= 57 )
1942
+ goto st53;
1943
+ } else if ( (*p) > 90 ) {
1944
+ if ( 94 <= (*p) && (*p) <= 122 )
1945
+ goto st53;
1946
+ } else
1947
+ goto st53;
1948
+ } else
1949
+ goto st53;
1950
+ goto st0;
1951
+ st53:
1952
+ if ( ++p == pe )
1953
+ goto _test_eof53;
1954
+ case 53:
1955
+ switch( (*p) ) {
1956
+ case 32: goto tr3;
1957
+ case 33: goto st54;
1958
+ case 124: goto st54;
1959
+ case 126: goto st54;
1960
+ }
1961
+ if ( (*p) < 45 ) {
1962
+ if ( (*p) > 39 ) {
1963
+ if ( 42 <= (*p) && (*p) <= 43 )
1964
+ goto st54;
1965
+ } else if ( (*p) >= 35 )
1966
+ goto st54;
1967
+ } else if ( (*p) > 46 ) {
1968
+ if ( (*p) < 65 ) {
1969
+ if ( 48 <= (*p) && (*p) <= 57 )
1970
+ goto st54;
1971
+ } else if ( (*p) > 90 ) {
1972
+ if ( 94 <= (*p) && (*p) <= 122 )
1973
+ goto st54;
1974
+ } else
1975
+ goto st54;
1976
+ } else
1977
+ goto st54;
1978
+ goto st0;
1979
+ st54:
1980
+ if ( ++p == pe )
1981
+ goto _test_eof54;
1982
+ case 54:
1983
+ switch( (*p) ) {
1984
+ case 32: goto tr3;
1985
+ case 33: goto st55;
1986
+ case 124: goto st55;
1987
+ case 126: goto st55;
1988
+ }
1989
+ if ( (*p) < 45 ) {
1990
+ if ( (*p) > 39 ) {
1991
+ if ( 42 <= (*p) && (*p) <= 43 )
1992
+ goto st55;
1993
+ } else if ( (*p) >= 35 )
1994
+ goto st55;
1995
+ } else if ( (*p) > 46 ) {
1996
+ if ( (*p) < 65 ) {
1997
+ if ( 48 <= (*p) && (*p) <= 57 )
1998
+ goto st55;
1999
+ } else if ( (*p) > 90 ) {
2000
+ if ( 94 <= (*p) && (*p) <= 122 )
2001
+ goto st55;
2002
+ } else
2003
+ goto st55;
2004
+ } else
2005
+ goto st55;
2006
+ goto st0;
2007
+ st55:
2008
+ if ( ++p == pe )
2009
+ goto _test_eof55;
2010
+ case 55:
2011
+ switch( (*p) ) {
2012
+ case 32: goto tr3;
2013
+ case 33: goto st56;
2014
+ case 124: goto st56;
2015
+ case 126: goto st56;
2016
+ }
2017
+ if ( (*p) < 45 ) {
2018
+ if ( (*p) > 39 ) {
2019
+ if ( 42 <= (*p) && (*p) <= 43 )
2020
+ goto st56;
2021
+ } else if ( (*p) >= 35 )
2022
+ goto st56;
2023
+ } else if ( (*p) > 46 ) {
2024
+ if ( (*p) < 65 ) {
2025
+ if ( 48 <= (*p) && (*p) <= 57 )
2026
+ goto st56;
2027
+ } else if ( (*p) > 90 ) {
2028
+ if ( 94 <= (*p) && (*p) <= 122 )
2029
+ goto st56;
2030
+ } else
2031
+ goto st56;
2032
+ } else
2033
+ goto st56;
2034
+ goto st0;
2035
+ st56:
2036
+ if ( ++p == pe )
2037
+ goto _test_eof56;
2038
+ case 56:
2039
+ switch( (*p) ) {
2040
+ case 32: goto tr3;
2041
+ case 33: goto st57;
2042
+ case 124: goto st57;
2043
+ case 126: goto st57;
2044
+ }
2045
+ if ( (*p) < 45 ) {
2046
+ if ( (*p) > 39 ) {
2047
+ if ( 42 <= (*p) && (*p) <= 43 )
2048
+ goto st57;
2049
+ } else if ( (*p) >= 35 )
2050
+ goto st57;
2051
+ } else if ( (*p) > 46 ) {
2052
+ if ( (*p) < 65 ) {
2053
+ if ( 48 <= (*p) && (*p) <= 57 )
2054
+ goto st57;
2055
+ } else if ( (*p) > 90 ) {
2056
+ if ( 94 <= (*p) && (*p) <= 122 )
2057
+ goto st57;
2058
+ } else
2059
+ goto st57;
2060
+ } else
2061
+ goto st57;
2062
+ goto st0;
2063
+ st57:
2064
+ if ( ++p == pe )
2065
+ goto _test_eof57;
2066
+ case 57:
2067
+ switch( (*p) ) {
2068
+ case 32: goto tr3;
2069
+ case 33: goto st58;
2070
+ case 124: goto st58;
2071
+ case 126: goto st58;
2072
+ }
2073
+ if ( (*p) < 45 ) {
2074
+ if ( (*p) > 39 ) {
2075
+ if ( 42 <= (*p) && (*p) <= 43 )
2076
+ goto st58;
2077
+ } else if ( (*p) >= 35 )
2078
+ goto st58;
2079
+ } else if ( (*p) > 46 ) {
2080
+ if ( (*p) < 65 ) {
2081
+ if ( 48 <= (*p) && (*p) <= 57 )
2082
+ goto st58;
2083
+ } else if ( (*p) > 90 ) {
2084
+ if ( 94 <= (*p) && (*p) <= 122 )
2085
+ goto st58;
2086
+ } else
2087
+ goto st58;
2088
+ } else
2089
+ goto st58;
2090
+ goto st0;
2091
+ st58:
2092
+ if ( ++p == pe )
2093
+ goto _test_eof58;
2094
+ case 58:
2095
+ switch( (*p) ) {
2096
+ case 32: goto tr3;
2097
+ case 33: goto st59;
2098
+ case 124: goto st59;
2099
+ case 126: goto st59;
2100
+ }
2101
+ if ( (*p) < 45 ) {
2102
+ if ( (*p) > 39 ) {
2103
+ if ( 42 <= (*p) && (*p) <= 43 )
2104
+ goto st59;
2105
+ } else if ( (*p) >= 35 )
2106
+ goto st59;
2107
+ } else if ( (*p) > 46 ) {
2108
+ if ( (*p) < 65 ) {
2109
+ if ( 48 <= (*p) && (*p) <= 57 )
2110
+ goto st59;
2111
+ } else if ( (*p) > 90 ) {
2112
+ if ( 94 <= (*p) && (*p) <= 122 )
2113
+ goto st59;
2114
+ } else
2115
+ goto st59;
2116
+ } else
2117
+ goto st59;
2118
+ goto st0;
2119
+ st59:
2120
+ if ( ++p == pe )
2121
+ goto _test_eof59;
2122
+ case 59:
2123
+ switch( (*p) ) {
2124
+ case 32: goto tr3;
2125
+ case 33: goto st60;
2126
+ case 124: goto st60;
2127
+ case 126: goto st60;
2128
+ }
2129
+ if ( (*p) < 45 ) {
2130
+ if ( (*p) > 39 ) {
2131
+ if ( 42 <= (*p) && (*p) <= 43 )
2132
+ goto st60;
2133
+ } else if ( (*p) >= 35 )
2134
+ goto st60;
2135
+ } else if ( (*p) > 46 ) {
2136
+ if ( (*p) < 65 ) {
2137
+ if ( 48 <= (*p) && (*p) <= 57 )
2138
+ goto st60;
2139
+ } else if ( (*p) > 90 ) {
2140
+ if ( 94 <= (*p) && (*p) <= 122 )
2141
+ goto st60;
2142
+ } else
2143
+ goto st60;
2144
+ } else
2145
+ goto st60;
2146
+ goto st0;
2147
+ st60:
2148
+ if ( ++p == pe )
2149
+ goto _test_eof60;
2150
+ case 60:
2151
+ switch( (*p) ) {
2152
+ case 32: goto tr3;
2153
+ case 33: goto st61;
2154
+ case 124: goto st61;
2155
+ case 126: goto st61;
2156
+ }
2157
+ if ( (*p) < 45 ) {
2158
+ if ( (*p) > 39 ) {
2159
+ if ( 42 <= (*p) && (*p) <= 43 )
2160
+ goto st61;
2161
+ } else if ( (*p) >= 35 )
2162
+ goto st61;
2163
+ } else if ( (*p) > 46 ) {
2164
+ if ( (*p) < 65 ) {
2165
+ if ( 48 <= (*p) && (*p) <= 57 )
2166
+ goto st61;
2167
+ } else if ( (*p) > 90 ) {
2168
+ if ( 94 <= (*p) && (*p) <= 122 )
2169
+ goto st61;
2170
+ } else
2171
+ goto st61;
2172
+ } else
2173
+ goto st61;
2174
+ goto st0;
2175
+ st61:
2176
+ if ( ++p == pe )
2177
+ goto _test_eof61;
2178
+ case 61:
2179
+ switch( (*p) ) {
2180
+ case 32: goto tr3;
2181
+ case 33: goto st62;
2182
+ case 124: goto st62;
2183
+ case 126: goto st62;
2184
+ }
2185
+ if ( (*p) < 45 ) {
2186
+ if ( (*p) > 39 ) {
2187
+ if ( 42 <= (*p) && (*p) <= 43 )
2188
+ goto st62;
2189
+ } else if ( (*p) >= 35 )
2190
+ goto st62;
2191
+ } else if ( (*p) > 46 ) {
2192
+ if ( (*p) < 65 ) {
2193
+ if ( 48 <= (*p) && (*p) <= 57 )
2194
+ goto st62;
2195
+ } else if ( (*p) > 90 ) {
2196
+ if ( 94 <= (*p) && (*p) <= 122 )
2197
+ goto st62;
2198
+ } else
2199
+ goto st62;
2200
+ } else
2201
+ goto st62;
2202
+ goto st0;
2203
+ st62:
2204
+ if ( ++p == pe )
2205
+ goto _test_eof62;
2206
+ case 62:
2207
+ switch( (*p) ) {
2208
+ case 32: goto tr3;
2209
+ case 33: goto st63;
2210
+ case 124: goto st63;
2211
+ case 126: goto st63;
2212
+ }
2213
+ if ( (*p) < 45 ) {
2214
+ if ( (*p) > 39 ) {
2215
+ if ( 42 <= (*p) && (*p) <= 43 )
2216
+ goto st63;
2217
+ } else if ( (*p) >= 35 )
2218
+ goto st63;
2219
+ } else if ( (*p) > 46 ) {
2220
+ if ( (*p) < 65 ) {
2221
+ if ( 48 <= (*p) && (*p) <= 57 )
2222
+ goto st63;
2223
+ } else if ( (*p) > 90 ) {
2224
+ if ( 94 <= (*p) && (*p) <= 122 )
2225
+ goto st63;
2226
+ } else
2227
+ goto st63;
2228
+ } else
2229
+ goto st63;
2230
+ goto st0;
2231
+ st63:
2232
+ if ( ++p == pe )
2233
+ goto _test_eof63;
2234
+ case 63:
2235
+ switch( (*p) ) {
2236
+ case 32: goto tr3;
2237
+ case 33: goto st64;
2238
+ case 124: goto st64;
2239
+ case 126: goto st64;
2240
+ }
2241
+ if ( (*p) < 45 ) {
2242
+ if ( (*p) > 39 ) {
2243
+ if ( 42 <= (*p) && (*p) <= 43 )
2244
+ goto st64;
2245
+ } else if ( (*p) >= 35 )
2246
+ goto st64;
2247
+ } else if ( (*p) > 46 ) {
2248
+ if ( (*p) < 65 ) {
2249
+ if ( 48 <= (*p) && (*p) <= 57 )
2250
+ goto st64;
2251
+ } else if ( (*p) > 90 ) {
2252
+ if ( 94 <= (*p) && (*p) <= 122 )
2253
+ goto st64;
2254
+ } else
2255
+ goto st64;
2256
+ } else
2257
+ goto st64;
2258
+ goto st0;
2259
+ st64:
2260
+ if ( ++p == pe )
2261
+ goto _test_eof64;
2262
+ case 64:
2263
+ switch( (*p) ) {
2264
+ case 32: goto tr3;
2265
+ case 33: goto st65;
2266
+ case 124: goto st65;
2267
+ case 126: goto st65;
2268
+ }
2269
+ if ( (*p) < 45 ) {
2270
+ if ( (*p) > 39 ) {
2271
+ if ( 42 <= (*p) && (*p) <= 43 )
2272
+ goto st65;
2273
+ } else if ( (*p) >= 35 )
2274
+ goto st65;
2275
+ } else if ( (*p) > 46 ) {
2276
+ if ( (*p) < 65 ) {
2277
+ if ( 48 <= (*p) && (*p) <= 57 )
2278
+ goto st65;
2279
+ } else if ( (*p) > 90 ) {
2280
+ if ( 94 <= (*p) && (*p) <= 122 )
2281
+ goto st65;
2282
+ } else
2283
+ goto st65;
2284
+ } else
2285
+ goto st65;
2286
+ goto st0;
2287
+ st65:
2288
+ if ( ++p == pe )
2289
+ goto _test_eof65;
2290
+ case 65:
2291
+ switch( (*p) ) {
2292
+ case 32: goto tr3;
2293
+ case 33: goto st66;
2294
+ case 124: goto st66;
2295
+ case 126: goto st66;
2296
+ }
2297
+ if ( (*p) < 45 ) {
2298
+ if ( (*p) > 39 ) {
2299
+ if ( 42 <= (*p) && (*p) <= 43 )
2300
+ goto st66;
2301
+ } else if ( (*p) >= 35 )
2302
+ goto st66;
2303
+ } else if ( (*p) > 46 ) {
2304
+ if ( (*p) < 65 ) {
2305
+ if ( 48 <= (*p) && (*p) <= 57 )
2306
+ goto st66;
2307
+ } else if ( (*p) > 90 ) {
2308
+ if ( 94 <= (*p) && (*p) <= 122 )
2309
+ goto st66;
2310
+ } else
2311
+ goto st66;
2312
+ } else
2313
+ goto st66;
2314
+ goto st0;
2315
+ st66:
2316
+ if ( ++p == pe )
2317
+ goto _test_eof66;
2318
+ case 66:
2319
+ switch( (*p) ) {
2320
+ case 32: goto tr3;
2321
+ case 33: goto st67;
2322
+ case 124: goto st67;
2323
+ case 126: goto st67;
2324
+ }
2325
+ if ( (*p) < 45 ) {
2326
+ if ( (*p) > 39 ) {
2327
+ if ( 42 <= (*p) && (*p) <= 43 )
2328
+ goto st67;
2329
+ } else if ( (*p) >= 35 )
2330
+ goto st67;
2331
+ } else if ( (*p) > 46 ) {
2332
+ if ( (*p) < 65 ) {
2333
+ if ( 48 <= (*p) && (*p) <= 57 )
2334
+ goto st67;
2335
+ } else if ( (*p) > 90 ) {
2336
+ if ( 94 <= (*p) && (*p) <= 122 )
2337
+ goto st67;
2338
+ } else
2339
+ goto st67;
2340
+ } else
2341
+ goto st67;
2342
+ goto st0;
2343
+ st67:
2344
+ if ( ++p == pe )
2345
+ goto _test_eof67;
2346
+ case 67:
2347
+ if ( (*p) == 32 )
2348
+ goto tr3;
2349
+ goto st0;
2350
+ tr2:
2351
+ #line 317 "pitchfork_http.rl"
2352
+ {MARK(mark, p); }
2353
+ goto st68;
2354
+ st68:
2355
+ if ( ++p == pe )
2356
+ goto _test_eof68;
2357
+ case 68:
2358
+ #line 2359 "pitchfork_http.c"
2359
+ switch( (*p) ) {
2360
+ case 32: goto tr3;
2361
+ case 33: goto st49;
2362
+ case 69: goto st69;
2363
+ case 124: goto st49;
2364
+ case 126: goto st49;
2365
+ }
2366
+ if ( (*p) < 45 ) {
2367
+ if ( (*p) > 39 ) {
2368
+ if ( 42 <= (*p) && (*p) <= 43 )
2369
+ goto st49;
2370
+ } else if ( (*p) >= 35 )
2371
+ goto st49;
2372
+ } else if ( (*p) > 46 ) {
2373
+ if ( (*p) < 65 ) {
2374
+ if ( 48 <= (*p) && (*p) <= 57 )
2375
+ goto st49;
2376
+ } else if ( (*p) > 90 ) {
2377
+ if ( 94 <= (*p) && (*p) <= 122 )
2378
+ goto st49;
2379
+ } else
2380
+ goto st49;
2381
+ } else
2382
+ goto st49;
2383
+ goto st0;
2384
+ st69:
2385
+ if ( ++p == pe )
2386
+ goto _test_eof69;
2387
+ case 69:
2388
+ switch( (*p) ) {
2389
+ case 32: goto tr3;
2390
+ case 33: goto st50;
2391
+ case 84: goto st70;
2392
+ case 124: goto st50;
2393
+ case 126: goto st50;
2394
+ }
2395
+ if ( (*p) < 45 ) {
2396
+ if ( (*p) > 39 ) {
2397
+ if ( 42 <= (*p) && (*p) <= 43 )
2398
+ goto st50;
2399
+ } else if ( (*p) >= 35 )
2400
+ goto st50;
2401
+ } else if ( (*p) > 46 ) {
2402
+ if ( (*p) < 65 ) {
2403
+ if ( 48 <= (*p) && (*p) <= 57 )
2404
+ goto st50;
2405
+ } else if ( (*p) > 90 ) {
2406
+ if ( 94 <= (*p) && (*p) <= 122 )
2407
+ goto st50;
2408
+ } else
2409
+ goto st50;
2410
+ } else
2411
+ goto st50;
2412
+ goto st0;
2413
+ st70:
2414
+ if ( ++p == pe )
2415
+ goto _test_eof70;
2416
+ case 70:
2417
+ switch( (*p) ) {
2418
+ case 32: goto tr100;
2419
+ case 33: goto st51;
2420
+ case 124: goto st51;
2421
+ case 126: goto st51;
2422
+ }
2423
+ if ( (*p) < 45 ) {
2424
+ if ( (*p) > 39 ) {
2425
+ if ( 42 <= (*p) && (*p) <= 43 )
2426
+ goto st51;
2427
+ } else if ( (*p) >= 35 )
2428
+ goto st51;
2429
+ } else if ( (*p) > 46 ) {
2430
+ if ( (*p) < 65 ) {
2431
+ if ( 48 <= (*p) && (*p) <= 57 )
2432
+ goto st51;
2433
+ } else if ( (*p) > 90 ) {
2434
+ if ( 94 <= (*p) && (*p) <= 122 )
2435
+ goto st51;
2436
+ } else
2437
+ goto st51;
2438
+ } else
2439
+ goto st51;
2440
+ goto st0;
2441
+ tr100:
2442
+ #line 326 "pitchfork_http.rl"
2443
+ { request_method(hp, PTR_TO(mark), LEN(mark, p)); }
2444
+ goto st71;
2445
+ st71:
2446
+ if ( ++p == pe )
2447
+ goto _test_eof71;
2448
+ case 71:
2449
+ #line 2450 "pitchfork_http.c"
2450
+ switch( (*p) ) {
2451
+ case 42: goto tr101;
2452
+ case 47: goto tr102;
2453
+ case 72: goto tr103;
2454
+ case 104: goto tr103;
2455
+ }
2456
+ goto st0;
2457
+ tr101:
2458
+ #line 317 "pitchfork_http.rl"
2459
+ {MARK(mark, p); }
2460
+ goto st72;
2461
+ st72:
2462
+ if ( ++p == pe )
2463
+ goto _test_eof72;
2464
+ case 72:
2465
+ #line 2466 "pitchfork_http.c"
2466
+ switch( (*p) ) {
2467
+ case 10: goto tr104;
2468
+ case 13: goto tr105;
2469
+ case 32: goto tr8;
2470
+ case 35: goto tr106;
2471
+ }
2472
+ goto st0;
2473
+ tr106:
2474
+ #line 331 "pitchfork_http.rl"
2475
+ {
2476
+ VALUE str;
2477
+
2478
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
2479
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
2480
+ /*
2481
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
2482
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
2483
+ */
2484
+ if (STR_CSTR_EQ(str, "*")) {
2485
+ str = rb_str_new(NULL, 0);
2486
+ rb_hash_aset(hp->env, g_path_info, str);
2487
+ rb_hash_aset(hp->env, g_request_path, str);
2488
+ }
2489
+ }
2490
+ goto st73;
2491
+ tr119:
2492
+ #line 356 "pitchfork_http.rl"
2493
+ {
2494
+ VALUE val;
2495
+
2496
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
2497
+ val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
2498
+
2499
+ /* rack says PATH_INFO must start with "/" or be empty */
2500
+ if (!STR_CSTR_EQ(val, "*"))
2501
+ rb_hash_aset(hp->env, g_path_info, val);
2502
+ }
2503
+ #line 331 "pitchfork_http.rl"
2504
+ {
2505
+ VALUE str;
2506
+
2507
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
2508
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
2509
+ /*
2510
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
2511
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
2512
+ */
2513
+ if (STR_CSTR_EQ(str, "*")) {
2514
+ str = rb_str_new(NULL, 0);
2515
+ rb_hash_aset(hp->env, g_path_info, str);
2516
+ rb_hash_aset(hp->env, g_request_path, str);
2517
+ }
2518
+ }
2519
+ goto st73;
2520
+ tr126:
2521
+ #line 350 "pitchfork_http.rl"
2522
+ {MARK(start.query, p); }
2523
+ #line 351 "pitchfork_http.rl"
2524
+ {
2525
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
2526
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
2527
+ }
2528
+ #line 331 "pitchfork_http.rl"
2529
+ {
2530
+ VALUE str;
2531
+
2532
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
2533
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
2534
+ /*
2535
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
2536
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
2537
+ */
2538
+ if (STR_CSTR_EQ(str, "*")) {
2539
+ str = rb_str_new(NULL, 0);
2540
+ rb_hash_aset(hp->env, g_path_info, str);
2541
+ rb_hash_aset(hp->env, g_request_path, str);
2542
+ }
2543
+ }
2544
+ goto st73;
2545
+ tr131:
2546
+ #line 351 "pitchfork_http.rl"
2547
+ {
2548
+ VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING);
2549
+ rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p));
2550
+ }
2551
+ #line 331 "pitchfork_http.rl"
2552
+ {
2553
+ VALUE str;
2554
+
2555
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI);
2556
+ str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p));
2557
+ /*
2558
+ * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*'
2559
+ * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain
2560
+ */
2561
+ if (STR_CSTR_EQ(str, "*")) {
2562
+ str = rb_str_new(NULL, 0);
2563
+ rb_hash_aset(hp->env, g_path_info, str);
2564
+ rb_hash_aset(hp->env, g_request_path, str);
2565
+ }
2566
+ }
2567
+ goto st73;
2568
+ st73:
2569
+ if ( ++p == pe )
2570
+ goto _test_eof73;
2571
+ case 73:
2572
+ #line 2573 "pitchfork_http.c"
2573
+ switch( (*p) ) {
2574
+ case 10: goto tr107;
2575
+ case 13: goto tr108;
2576
+ case 32: goto tr41;
2577
+ case 35: goto st0;
2578
+ case 37: goto tr110;
2579
+ case 127: goto st0;
2580
+ }
2581
+ if ( (*p) <= 31 )
2582
+ goto st0;
2583
+ goto tr109;
2584
+ tr109:
2585
+ #line 317 "pitchfork_http.rl"
2586
+ {MARK(mark, p); }
2587
+ goto st74;
2588
+ st74:
2589
+ if ( ++p == pe )
2590
+ goto _test_eof74;
2591
+ case 74:
2592
+ #line 2593 "pitchfork_http.c"
2593
+ switch( (*p) ) {
2594
+ case 10: goto tr111;
2595
+ case 13: goto tr112;
2596
+ case 32: goto tr44;
2597
+ case 35: goto st0;
2598
+ case 37: goto st75;
2599
+ case 127: goto st0;
2600
+ }
2601
+ if ( (*p) <= 31 )
2602
+ goto st0;
2603
+ goto st74;
2604
+ tr110:
2605
+ #line 317 "pitchfork_http.rl"
2606
+ {MARK(mark, p); }
2607
+ goto st75;
2608
+ st75:
2609
+ if ( ++p == pe )
2610
+ goto _test_eof75;
2611
+ case 75:
2612
+ #line 2613 "pitchfork_http.c"
2613
+ if ( (*p) < 65 ) {
2614
+ if ( 48 <= (*p) && (*p) <= 57 )
2615
+ goto st76;
2616
+ } else if ( (*p) > 70 ) {
2617
+ if ( 97 <= (*p) && (*p) <= 102 )
2618
+ goto st76;
2619
+ } else
2620
+ goto st76;
2621
+ goto st0;
2622
+ st76:
2623
+ if ( ++p == pe )
2624
+ goto _test_eof76;
2625
+ case 76:
2626
+ if ( (*p) < 65 ) {
2627
+ if ( 48 <= (*p) && (*p) <= 57 )
2628
+ goto st74;
2629
+ } else if ( (*p) > 70 ) {
2630
+ if ( 97 <= (*p) && (*p) <= 102 )
2631
+ goto st74;
2632
+ } else
2633
+ goto st74;
2634
+ goto st0;
2635
+ tr102:
2636
+ #line 317 "pitchfork_http.rl"
2637
+ {MARK(mark, p); }
2638
+ goto st77;
2639
+ tr147:
2640
+ #line 330 "pitchfork_http.rl"
2641
+ { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, p)); }
2642
+ #line 317 "pitchfork_http.rl"
2643
+ {MARK(mark, p); }
2644
+ goto st77;
2645
+ st77:
2646
+ if ( ++p == pe )
2647
+ goto _test_eof77;
2648
+ case 77:
2649
+ #line 2650 "pitchfork_http.c"
2650
+ switch( (*p) ) {
2651
+ case 10: goto tr116;
2652
+ case 13: goto tr117;
2653
+ case 32: goto tr48;
2654
+ case 35: goto tr119;
2655
+ case 37: goto st78;
2656
+ case 63: goto tr121;
2657
+ case 127: goto st0;
2658
+ }
2659
+ if ( (*p) <= 31 )
2660
+ goto st0;
2661
+ goto st77;
2662
+ st78:
2663
+ if ( ++p == pe )
2664
+ goto _test_eof78;
2665
+ case 78:
2666
+ if ( (*p) < 65 ) {
2667
+ if ( 48 <= (*p) && (*p) <= 57 )
2668
+ goto st79;
2669
+ } else if ( (*p) > 70 ) {
2670
+ if ( 97 <= (*p) && (*p) <= 102 )
2671
+ goto st79;
2672
+ } else
2673
+ goto st79;
2674
+ goto st0;
2675
+ st79:
2676
+ if ( ++p == pe )
2677
+ goto _test_eof79;
2678
+ case 79:
2679
+ if ( (*p) < 65 ) {
2680
+ if ( 48 <= (*p) && (*p) <= 57 )
2681
+ goto st77;
2682
+ } else if ( (*p) > 70 ) {
2683
+ if ( 97 <= (*p) && (*p) <= 102 )
2684
+ goto st77;
2685
+ } else
2686
+ goto st77;
2687
+ goto st0;
2688
+ tr121:
2689
+ #line 356 "pitchfork_http.rl"
2690
+ {
2691
+ VALUE val;
2692
+
2693
+ VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_PATH);
2694
+ val = rb_hash_aset(hp->env, g_request_path, STR_NEW(mark, p));
2695
+
2696
+ /* rack says PATH_INFO must start with "/" or be empty */
2697
+ if (!STR_CSTR_EQ(val, "*"))
2698
+ rb_hash_aset(hp->env, g_path_info, val);
2699
+ }
2700
+ goto st80;
2701
+ st80:
2702
+ if ( ++p == pe )
2703
+ goto _test_eof80;
2704
+ case 80:
2705
+ #line 2706 "pitchfork_http.c"
2706
+ switch( (*p) ) {
2707
+ case 10: goto tr123;
2708
+ case 13: goto tr124;
2709
+ case 32: goto tr54;
2710
+ case 35: goto tr126;
2711
+ case 37: goto tr127;
2712
+ case 127: goto st0;
2713
+ }
2714
+ if ( (*p) <= 31 )
2715
+ goto st0;
2716
+ goto tr125;
2717
+ tr125:
2718
+ #line 350 "pitchfork_http.rl"
2719
+ {MARK(start.query, p); }
2720
+ goto st81;
2721
+ st81:
2722
+ if ( ++p == pe )
2723
+ goto _test_eof81;
2724
+ case 81:
2725
+ #line 2726 "pitchfork_http.c"
2726
+ switch( (*p) ) {
2727
+ case 10: goto tr128;
2728
+ case 13: goto tr129;
2729
+ case 32: goto tr58;
2730
+ case 35: goto tr131;
2731
+ case 37: goto st82;
2732
+ case 127: goto st0;
2733
+ }
2734
+ if ( (*p) <= 31 )
2735
+ goto st0;
2736
+ goto st81;
2737
+ tr127:
2738
+ #line 350 "pitchfork_http.rl"
2739
+ {MARK(start.query, p); }
2740
+ goto st82;
2741
+ st82:
2742
+ if ( ++p == pe )
2743
+ goto _test_eof82;
2744
+ case 82:
2745
+ #line 2746 "pitchfork_http.c"
2746
+ if ( (*p) < 65 ) {
2747
+ if ( 48 <= (*p) && (*p) <= 57 )
2748
+ goto st83;
2749
+ } else if ( (*p) > 70 ) {
2750
+ if ( 97 <= (*p) && (*p) <= 102 )
2751
+ goto st83;
2752
+ } else
2753
+ goto st83;
2754
+ goto st0;
2755
+ st83:
2756
+ if ( ++p == pe )
2757
+ goto _test_eof83;
2758
+ case 83:
2759
+ if ( (*p) < 65 ) {
2760
+ if ( 48 <= (*p) && (*p) <= 57 )
2761
+ goto st81;
2762
+ } else if ( (*p) > 70 ) {
2763
+ if ( 97 <= (*p) && (*p) <= 102 )
2764
+ goto st81;
2765
+ } else
2766
+ goto st81;
2767
+ goto st0;
2768
+ tr103:
2769
+ #line 317 "pitchfork_http.rl"
2770
+ {MARK(mark, p); }
2771
+ #line 321 "pitchfork_http.rl"
2772
+ { downcase_char(deconst(p)); }
2773
+ goto st84;
2774
+ st84:
2775
+ if ( ++p == pe )
2776
+ goto _test_eof84;
2777
+ case 84:
2778
+ #line 2779 "pitchfork_http.c"
2779
+ switch( (*p) ) {
2780
+ case 84: goto tr134;
2781
+ case 116: goto tr134;
2782
+ }
2783
+ goto st0;
2784
+ tr134:
2785
+ #line 321 "pitchfork_http.rl"
2786
+ { downcase_char(deconst(p)); }
2787
+ goto st85;
2788
+ st85:
2789
+ if ( ++p == pe )
2790
+ goto _test_eof85;
2791
+ case 85:
2792
+ #line 2793 "pitchfork_http.c"
2793
+ switch( (*p) ) {
2794
+ case 84: goto tr135;
2795
+ case 116: goto tr135;
2796
+ }
2797
+ goto st0;
2798
+ tr135:
2799
+ #line 321 "pitchfork_http.rl"
2800
+ { downcase_char(deconst(p)); }
2801
+ goto st86;
2802
+ st86:
2803
+ if ( ++p == pe )
2804
+ goto _test_eof86;
2805
+ case 86:
2806
+ #line 2807 "pitchfork_http.c"
2807
+ switch( (*p) ) {
2808
+ case 80: goto tr136;
2809
+ case 112: goto tr136;
2810
+ }
2811
+ goto st0;
2812
+ tr136:
2813
+ #line 321 "pitchfork_http.rl"
2814
+ { downcase_char(deconst(p)); }
2815
+ goto st87;
2816
+ st87:
2817
+ if ( ++p == pe )
2818
+ goto _test_eof87;
2819
+ case 87:
2820
+ #line 2821 "pitchfork_http.c"
2821
+ switch( (*p) ) {
2822
+ case 58: goto tr137;
2823
+ case 83: goto tr138;
2824
+ case 115: goto tr138;
2825
+ }
2826
+ goto st0;
2827
+ tr137:
2828
+ #line 327 "pitchfork_http.rl"
2829
+ {
2830
+ rb_hash_aset(hp->env, g_rack_url_scheme, STR_NEW(mark, p));
2831
+ }
2832
+ goto st88;
2833
+ st88:
2834
+ if ( ++p == pe )
2835
+ goto _test_eof88;
2836
+ case 88:
2837
+ #line 2838 "pitchfork_http.c"
2838
+ if ( (*p) == 47 )
2839
+ goto st89;
2840
+ goto st0;
2841
+ st89:
2842
+ if ( ++p == pe )
2843
+ goto _test_eof89;
2844
+ case 89:
2845
+ if ( (*p) == 47 )
2846
+ goto st90;
2847
+ goto st0;
2848
+ st90:
2849
+ if ( ++p == pe )
2850
+ goto _test_eof90;
2851
+ case 90:
2852
+ switch( (*p) ) {
2853
+ case 37: goto st92;
2854
+ case 47: goto st0;
2855
+ case 60: goto st0;
2856
+ case 91: goto tr144;
2857
+ case 95: goto tr143;
2858
+ case 127: goto st0;
2859
+ }
2860
+ if ( (*p) < 45 ) {
2861
+ if ( (*p) > 32 ) {
2862
+ if ( 34 <= (*p) && (*p) <= 35 )
2863
+ goto st0;
2864
+ } else
2865
+ goto st0;
2866
+ } else if ( (*p) > 57 ) {
2867
+ if ( (*p) < 65 ) {
2868
+ if ( 62 <= (*p) && (*p) <= 64 )
2869
+ goto st0;
2870
+ } else if ( (*p) > 90 ) {
2871
+ if ( 97 <= (*p) && (*p) <= 122 )
2872
+ goto tr143;
2873
+ } else
2874
+ goto tr143;
2875
+ } else
2876
+ goto tr143;
2877
+ goto st91;
2878
+ st91:
2879
+ if ( ++p == pe )
2880
+ goto _test_eof91;
2881
+ case 91:
2882
+ switch( (*p) ) {
2883
+ case 37: goto st92;
2884
+ case 47: goto st0;
2885
+ case 60: goto st0;
2886
+ case 64: goto st90;
2887
+ case 127: goto st0;
2888
+ }
2889
+ if ( (*p) < 34 ) {
2890
+ if ( (*p) <= 32 )
2891
+ goto st0;
2892
+ } else if ( (*p) > 35 ) {
2893
+ if ( 62 <= (*p) && (*p) <= 63 )
2894
+ goto st0;
2895
+ } else
2896
+ goto st0;
2897
+ goto st91;
2898
+ st92:
2899
+ if ( ++p == pe )
2900
+ goto _test_eof92;
2901
+ case 92:
2902
+ if ( (*p) < 65 ) {
2903
+ if ( 48 <= (*p) && (*p) <= 57 )
2904
+ goto st93;
2905
+ } else if ( (*p) > 70 ) {
2906
+ if ( 97 <= (*p) && (*p) <= 102 )
2907
+ goto st93;
2908
+ } else
2909
+ goto st93;
2910
+ goto st0;
2911
+ st93:
2912
+ if ( ++p == pe )
2913
+ goto _test_eof93;
2914
+ case 93:
2915
+ if ( (*p) < 65 ) {
2916
+ if ( 48 <= (*p) && (*p) <= 57 )
2917
+ goto st91;
2918
+ } else if ( (*p) > 70 ) {
2919
+ if ( 97 <= (*p) && (*p) <= 102 )
2920
+ goto st91;
2921
+ } else
2922
+ goto st91;
2923
+ goto st0;
2924
+ tr143:
2925
+ #line 317 "pitchfork_http.rl"
2926
+ {MARK(mark, p); }
2927
+ goto st94;
2928
+ st94:
2929
+ if ( ++p == pe )
2930
+ goto _test_eof94;
2931
+ case 94:
2932
+ #line 2933 "pitchfork_http.c"
2933
+ switch( (*p) ) {
2934
+ case 37: goto st92;
2935
+ case 47: goto tr147;
2936
+ case 58: goto st95;
2937
+ case 60: goto st0;
2938
+ case 64: goto st90;
2939
+ case 95: goto st94;
2940
+ case 127: goto st0;
2941
+ }
2942
+ if ( (*p) < 45 ) {
2943
+ if ( (*p) > 32 ) {
2944
+ if ( 34 <= (*p) && (*p) <= 35 )
2945
+ goto st0;
2946
+ } else
2947
+ goto st0;
2948
+ } else if ( (*p) > 57 ) {
2949
+ if ( (*p) < 65 ) {
2950
+ if ( 62 <= (*p) && (*p) <= 63 )
2951
+ goto st0;
2952
+ } else if ( (*p) > 90 ) {
2953
+ if ( 97 <= (*p) && (*p) <= 122 )
2954
+ goto st94;
2955
+ } else
2956
+ goto st94;
2957
+ } else
2958
+ goto st94;
2959
+ goto st91;
2960
+ st95:
2961
+ if ( ++p == pe )
2962
+ goto _test_eof95;
2963
+ case 95:
2964
+ switch( (*p) ) {
2965
+ case 37: goto st92;
2966
+ case 47: goto tr147;
2967
+ case 60: goto st0;
2968
+ case 64: goto st90;
2969
+ case 127: goto st0;
2970
+ }
2971
+ if ( (*p) < 34 ) {
2972
+ if ( (*p) <= 32 )
2973
+ goto st0;
2974
+ } else if ( (*p) > 35 ) {
2975
+ if ( (*p) > 57 ) {
2976
+ if ( 62 <= (*p) && (*p) <= 63 )
2977
+ goto st0;
2978
+ } else if ( (*p) >= 48 )
2979
+ goto st95;
2980
+ } else
2981
+ goto st0;
2982
+ goto st91;
2983
+ tr144:
2984
+ #line 317 "pitchfork_http.rl"
2985
+ {MARK(mark, p); }
2986
+ goto st96;
2987
+ st96:
2988
+ if ( ++p == pe )
2989
+ goto _test_eof96;
2990
+ case 96:
2991
+ #line 2992 "pitchfork_http.c"
2992
+ switch( (*p) ) {
2993
+ case 37: goto st92;
2994
+ case 47: goto st0;
2995
+ case 60: goto st0;
2996
+ case 64: goto st90;
2997
+ case 127: goto st0;
2998
+ }
2999
+ if ( (*p) < 48 ) {
3000
+ if ( (*p) > 32 ) {
3001
+ if ( 34 <= (*p) && (*p) <= 35 )
3002
+ goto st0;
3003
+ } else
3004
+ goto st0;
3005
+ } else if ( (*p) > 58 ) {
3006
+ if ( (*p) < 65 ) {
3007
+ if ( 62 <= (*p) && (*p) <= 63 )
3008
+ goto st0;
3009
+ } else if ( (*p) > 70 ) {
3010
+ if ( 97 <= (*p) && (*p) <= 102 )
3011
+ goto st97;
3012
+ } else
3013
+ goto st97;
3014
+ } else
3015
+ goto st97;
3016
+ goto st91;
3017
+ st97:
3018
+ if ( ++p == pe )
3019
+ goto _test_eof97;
3020
+ case 97:
3021
+ switch( (*p) ) {
3022
+ case 37: goto st92;
3023
+ case 47: goto st0;
3024
+ case 60: goto st0;
3025
+ case 64: goto st90;
3026
+ case 93: goto st98;
3027
+ case 127: goto st0;
3028
+ }
3029
+ if ( (*p) < 48 ) {
3030
+ if ( (*p) > 32 ) {
3031
+ if ( 34 <= (*p) && (*p) <= 35 )
3032
+ goto st0;
3033
+ } else
3034
+ goto st0;
3035
+ } else if ( (*p) > 58 ) {
3036
+ if ( (*p) < 65 ) {
3037
+ if ( 62 <= (*p) && (*p) <= 63 )
3038
+ goto st0;
3039
+ } else if ( (*p) > 70 ) {
3040
+ if ( 97 <= (*p) && (*p) <= 102 )
3041
+ goto st97;
3042
+ } else
3043
+ goto st97;
3044
+ } else
3045
+ goto st97;
3046
+ goto st91;
3047
+ st98:
3048
+ if ( ++p == pe )
3049
+ goto _test_eof98;
3050
+ case 98:
3051
+ switch( (*p) ) {
3052
+ case 37: goto st92;
3053
+ case 47: goto tr147;
3054
+ case 58: goto st95;
3055
+ case 60: goto st0;
3056
+ case 64: goto st90;
3057
+ case 127: goto st0;
3058
+ }
3059
+ if ( (*p) < 34 ) {
3060
+ if ( (*p) <= 32 )
3061
+ goto st0;
3062
+ } else if ( (*p) > 35 ) {
3063
+ if ( 62 <= (*p) && (*p) <= 63 )
3064
+ goto st0;
3065
+ } else
3066
+ goto st0;
3067
+ goto st91;
3068
+ tr138:
3069
+ #line 321 "pitchfork_http.rl"
3070
+ { downcase_char(deconst(p)); }
3071
+ goto st99;
3072
+ st99:
3073
+ if ( ++p == pe )
3074
+ goto _test_eof99;
3075
+ case 99:
3076
+ #line 3077 "pitchfork_http.c"
3077
+ if ( (*p) == 58 )
3078
+ goto tr137;
3079
+ goto st0;
3080
+ st100:
3081
+ if ( ++p == pe )
3082
+ goto _test_eof100;
3083
+ case 100:
3084
+ if ( (*p) == 48 )
3085
+ goto tr151;
3086
+ if ( (*p) < 65 ) {
3087
+ if ( 49 <= (*p) && (*p) <= 57 )
3088
+ goto tr152;
3089
+ } else if ( (*p) > 70 ) {
3090
+ if ( 97 <= (*p) && (*p) <= 102 )
3091
+ goto tr152;
3092
+ } else
3093
+ goto tr152;
3094
+ goto st0;
3095
+ tr151:
3096
+ #line 366 "pitchfork_http.rl"
3097
+ {
3098
+ hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
3099
+ if (hp->len.chunk < 0)
3100
+ parser_raise(eHttpParserError, "invalid chunk size");
3101
+ }
3102
+ goto st101;
3103
+ st101:
3104
+ if ( ++p == pe )
3105
+ goto _test_eof101;
3106
+ case 101:
3107
+ #line 3108 "pitchfork_http.c"
3108
+ switch( (*p) ) {
3109
+ case 10: goto tr153;
3110
+ case 13: goto st102;
3111
+ case 48: goto tr151;
3112
+ case 59: goto st111;
3113
+ }
3114
+ if ( (*p) < 65 ) {
3115
+ if ( 49 <= (*p) && (*p) <= 57 )
3116
+ goto tr152;
3117
+ } else if ( (*p) > 70 ) {
3118
+ if ( 97 <= (*p) && (*p) <= 102 )
3119
+ goto tr152;
3120
+ } else
3121
+ goto tr152;
3122
+ goto st0;
3123
+ tr153:
3124
+ #line 395 "pitchfork_http.rl"
3125
+ {
3126
+ HP_FL_SET(hp, INTRAILER);
3127
+ cs = http_parser_en_Trailers;
3128
+ ++p;
3129
+ assert(p <= pe && "buffer overflow after chunked body");
3130
+ goto post_exec;
3131
+ }
3132
+ goto st123;
3133
+ st123:
3134
+ if ( ++p == pe )
3135
+ goto _test_eof123;
3136
+ case 123:
3137
+ #line 3138 "pitchfork_http.c"
3138
+ goto st0;
3139
+ st102:
3140
+ if ( ++p == pe )
3141
+ goto _test_eof102;
3142
+ case 102:
3143
+ if ( (*p) == 10 )
3144
+ goto tr153;
3145
+ goto st0;
3146
+ tr152:
3147
+ #line 366 "pitchfork_http.rl"
3148
+ {
3149
+ hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
3150
+ if (hp->len.chunk < 0)
3151
+ parser_raise(eHttpParserError, "invalid chunk size");
3152
+ }
3153
+ goto st103;
3154
+ st103:
3155
+ if ( ++p == pe )
3156
+ goto _test_eof103;
3157
+ case 103:
3158
+ #line 3159 "pitchfork_http.c"
3159
+ switch( (*p) ) {
3160
+ case 10: goto st104;
3161
+ case 13: goto st107;
3162
+ case 59: goto st108;
3163
+ }
3164
+ if ( (*p) < 65 ) {
3165
+ if ( 48 <= (*p) && (*p) <= 57 )
3166
+ goto tr152;
3167
+ } else if ( (*p) > 70 ) {
3168
+ if ( 97 <= (*p) && (*p) <= 102 )
3169
+ goto tr152;
3170
+ } else
3171
+ goto tr152;
3172
+ goto st0;
3173
+ st104:
3174
+ if ( ++p == pe )
3175
+ goto _test_eof104;
3176
+ case 104:
3177
+ goto tr159;
3178
+ tr159:
3179
+ #line 403 "pitchfork_http.rl"
3180
+ {
3181
+ skip_chunk_data_hack: {
3182
+ size_t nr = MIN((size_t)hp->len.chunk, REMAINING);
3183
+ memcpy(RSTRING_PTR(hp->cont) + hp->s.dest_offset, p, nr);
3184
+ hp->s.dest_offset += nr;
3185
+ hp->len.chunk -= nr;
3186
+ p += nr;
3187
+ assert(hp->len.chunk >= 0 && "negative chunk length");
3188
+ if ((size_t)hp->len.chunk > REMAINING) {
3189
+ HP_FL_SET(hp, INCHUNK);
3190
+ goto post_exec;
3191
+ } else {
3192
+ p--;
3193
+ {goto st105;}
3194
+ }
3195
+ }}
3196
+ goto st105;
3197
+ st105:
3198
+ if ( ++p == pe )
3199
+ goto _test_eof105;
3200
+ case 105:
3201
+ #line 3202 "pitchfork_http.c"
3202
+ switch( (*p) ) {
3203
+ case 10: goto st100;
3204
+ case 13: goto st106;
3205
+ }
3206
+ goto st0;
3207
+ st106:
3208
+ if ( ++p == pe )
3209
+ goto _test_eof106;
3210
+ case 106:
3211
+ if ( (*p) == 10 )
3212
+ goto st100;
3213
+ goto st0;
3214
+ st107:
3215
+ if ( ++p == pe )
3216
+ goto _test_eof107;
3217
+ case 107:
3218
+ if ( (*p) == 10 )
3219
+ goto st104;
3220
+ goto st0;
3221
+ st108:
3222
+ if ( ++p == pe )
3223
+ goto _test_eof108;
3224
+ case 108:
3225
+ switch( (*p) ) {
3226
+ case 10: goto st104;
3227
+ case 13: goto st107;
3228
+ case 32: goto st108;
3229
+ case 33: goto st109;
3230
+ case 59: goto st108;
3231
+ case 61: goto st110;
3232
+ case 124: goto st109;
3233
+ case 126: goto st109;
3234
+ }
3235
+ if ( (*p) < 45 ) {
3236
+ if ( (*p) > 39 ) {
3237
+ if ( 42 <= (*p) && (*p) <= 43 )
3238
+ goto st109;
3239
+ } else if ( (*p) >= 35 )
3240
+ goto st109;
3241
+ } else if ( (*p) > 46 ) {
3242
+ if ( (*p) < 65 ) {
3243
+ if ( 48 <= (*p) && (*p) <= 57 )
3244
+ goto st109;
3245
+ } else if ( (*p) > 90 ) {
3246
+ if ( 94 <= (*p) && (*p) <= 122 )
3247
+ goto st109;
3248
+ } else
3249
+ goto st109;
3250
+ } else
3251
+ goto st109;
3252
+ goto st0;
3253
+ st109:
3254
+ if ( ++p == pe )
3255
+ goto _test_eof109;
3256
+ case 109:
3257
+ switch( (*p) ) {
3258
+ case 10: goto st104;
3259
+ case 13: goto st107;
3260
+ case 33: goto st109;
3261
+ case 59: goto st108;
3262
+ case 61: goto st110;
3263
+ case 124: goto st109;
3264
+ case 126: goto st109;
3265
+ }
3266
+ if ( (*p) < 45 ) {
3267
+ if ( (*p) > 39 ) {
3268
+ if ( 42 <= (*p) && (*p) <= 43 )
3269
+ goto st109;
3270
+ } else if ( (*p) >= 35 )
3271
+ goto st109;
3272
+ } else if ( (*p) > 46 ) {
3273
+ if ( (*p) < 65 ) {
3274
+ if ( 48 <= (*p) && (*p) <= 57 )
3275
+ goto st109;
3276
+ } else if ( (*p) > 90 ) {
3277
+ if ( 94 <= (*p) && (*p) <= 122 )
3278
+ goto st109;
3279
+ } else
3280
+ goto st109;
3281
+ } else
3282
+ goto st109;
3283
+ goto st0;
3284
+ st110:
3285
+ if ( ++p == pe )
3286
+ goto _test_eof110;
3287
+ case 110:
3288
+ switch( (*p) ) {
3289
+ case 10: goto st104;
3290
+ case 13: goto st107;
3291
+ case 33: goto st110;
3292
+ case 59: goto st108;
3293
+ case 124: goto st110;
3294
+ case 126: goto st110;
3295
+ }
3296
+ if ( (*p) < 45 ) {
3297
+ if ( (*p) > 39 ) {
3298
+ if ( 42 <= (*p) && (*p) <= 43 )
3299
+ goto st110;
3300
+ } else if ( (*p) >= 35 )
3301
+ goto st110;
3302
+ } else if ( (*p) > 46 ) {
3303
+ if ( (*p) < 65 ) {
3304
+ if ( 48 <= (*p) && (*p) <= 57 )
3305
+ goto st110;
3306
+ } else if ( (*p) > 90 ) {
3307
+ if ( 94 <= (*p) && (*p) <= 122 )
3308
+ goto st110;
3309
+ } else
3310
+ goto st110;
3311
+ } else
3312
+ goto st110;
3313
+ goto st0;
3314
+ st111:
3315
+ if ( ++p == pe )
3316
+ goto _test_eof111;
3317
+ case 111:
3318
+ switch( (*p) ) {
3319
+ case 10: goto tr153;
3320
+ case 13: goto st102;
3321
+ case 32: goto st111;
3322
+ case 33: goto st112;
3323
+ case 59: goto st111;
3324
+ case 61: goto st113;
3325
+ case 124: goto st112;
3326
+ case 126: goto st112;
3327
+ }
3328
+ if ( (*p) < 45 ) {
3329
+ if ( (*p) > 39 ) {
3330
+ if ( 42 <= (*p) && (*p) <= 43 )
3331
+ goto st112;
3332
+ } else if ( (*p) >= 35 )
3333
+ goto st112;
3334
+ } else if ( (*p) > 46 ) {
3335
+ if ( (*p) < 65 ) {
3336
+ if ( 48 <= (*p) && (*p) <= 57 )
3337
+ goto st112;
3338
+ } else if ( (*p) > 90 ) {
3339
+ if ( 94 <= (*p) && (*p) <= 122 )
3340
+ goto st112;
3341
+ } else
3342
+ goto st112;
3343
+ } else
3344
+ goto st112;
3345
+ goto st0;
3346
+ st112:
3347
+ if ( ++p == pe )
3348
+ goto _test_eof112;
3349
+ case 112:
3350
+ switch( (*p) ) {
3351
+ case 10: goto tr153;
3352
+ case 13: goto st102;
3353
+ case 33: goto st112;
3354
+ case 59: goto st111;
3355
+ case 61: goto st113;
3356
+ case 124: goto st112;
3357
+ case 126: goto st112;
3358
+ }
3359
+ if ( (*p) < 45 ) {
3360
+ if ( (*p) > 39 ) {
3361
+ if ( 42 <= (*p) && (*p) <= 43 )
3362
+ goto st112;
3363
+ } else if ( (*p) >= 35 )
3364
+ goto st112;
3365
+ } else if ( (*p) > 46 ) {
3366
+ if ( (*p) < 65 ) {
3367
+ if ( 48 <= (*p) && (*p) <= 57 )
3368
+ goto st112;
3369
+ } else if ( (*p) > 90 ) {
3370
+ if ( 94 <= (*p) && (*p) <= 122 )
3371
+ goto st112;
3372
+ } else
3373
+ goto st112;
3374
+ } else
3375
+ goto st112;
3376
+ goto st0;
3377
+ st113:
3378
+ if ( ++p == pe )
3379
+ goto _test_eof113;
3380
+ case 113:
3381
+ switch( (*p) ) {
3382
+ case 10: goto tr153;
3383
+ case 13: goto st102;
3384
+ case 33: goto st113;
3385
+ case 59: goto st111;
3386
+ case 124: goto st113;
3387
+ case 126: goto st113;
3388
+ }
3389
+ if ( (*p) < 45 ) {
3390
+ if ( (*p) > 39 ) {
3391
+ if ( 42 <= (*p) && (*p) <= 43 )
3392
+ goto st113;
3393
+ } else if ( (*p) >= 35 )
3394
+ goto st113;
3395
+ } else if ( (*p) > 46 ) {
3396
+ if ( (*p) < 65 ) {
3397
+ if ( 48 <= (*p) && (*p) <= 57 )
3398
+ goto st113;
3399
+ } else if ( (*p) > 90 ) {
3400
+ if ( 94 <= (*p) && (*p) <= 122 )
3401
+ goto st113;
3402
+ } else
3403
+ goto st113;
3404
+ } else
3405
+ goto st113;
3406
+ goto st0;
3407
+ tr171:
3408
+ #line 323 "pitchfork_http.rl"
3409
+ { MARK(mark, p); }
3410
+ #line 325 "pitchfork_http.rl"
3411
+ { write_cont_value(hp, buffer, p); }
3412
+ goto st114;
3413
+ tr176:
3414
+ #line 325 "pitchfork_http.rl"
3415
+ { write_cont_value(hp, buffer, p); }
3416
+ goto st114;
3417
+ tr181:
3418
+ #line 323 "pitchfork_http.rl"
3419
+ { MARK(mark, p); }
3420
+ #line 324 "pitchfork_http.rl"
3421
+ { write_value(hp, buffer, p); }
3422
+ goto st114;
3423
+ tr185:
3424
+ #line 324 "pitchfork_http.rl"
3425
+ { write_value(hp, buffer, p); }
3426
+ goto st114;
3427
+ st114:
3428
+ if ( ++p == pe )
3429
+ goto _test_eof114;
3430
+ case 114:
3431
+ #line 3432 "pitchfork_http.c"
3432
+ switch( (*p) ) {
3433
+ case 9: goto st115;
3434
+ case 10: goto tr167;
3435
+ case 13: goto st118;
3436
+ case 32: goto st115;
3437
+ case 33: goto tr169;
3438
+ case 124: goto tr169;
3439
+ case 126: goto tr169;
3440
+ }
3441
+ if ( (*p) < 45 ) {
3442
+ if ( (*p) > 39 ) {
3443
+ if ( 42 <= (*p) && (*p) <= 43 )
3444
+ goto tr169;
3445
+ } else if ( (*p) >= 35 )
3446
+ goto tr169;
3447
+ } else if ( (*p) > 46 ) {
3448
+ if ( (*p) < 65 ) {
3449
+ if ( 48 <= (*p) && (*p) <= 57 )
3450
+ goto tr169;
3451
+ } else if ( (*p) > 90 ) {
3452
+ if ( 94 <= (*p) && (*p) <= 122 )
3453
+ goto tr169;
3454
+ } else
3455
+ goto tr169;
3456
+ } else
3457
+ goto tr169;
3458
+ goto st0;
3459
+ tr170:
3460
+ #line 323 "pitchfork_http.rl"
3461
+ { MARK(mark, p); }
3462
+ goto st115;
3463
+ st115:
3464
+ if ( ++p == pe )
3465
+ goto _test_eof115;
3466
+ case 115:
3467
+ #line 3468 "pitchfork_http.c"
3468
+ switch( (*p) ) {
3469
+ case 9: goto tr170;
3470
+ case 10: goto tr171;
3471
+ case 13: goto tr172;
3472
+ case 32: goto tr170;
3473
+ case 127: goto st0;
3474
+ }
3475
+ if ( (*p) <= 31 )
3476
+ goto st0;
3477
+ goto tr173;
3478
+ tr172:
3479
+ #line 323 "pitchfork_http.rl"
3480
+ { MARK(mark, p); }
3481
+ #line 325 "pitchfork_http.rl"
3482
+ { write_cont_value(hp, buffer, p); }
3483
+ goto st116;
3484
+ tr177:
3485
+ #line 325 "pitchfork_http.rl"
3486
+ { write_cont_value(hp, buffer, p); }
3487
+ goto st116;
3488
+ tr182:
3489
+ #line 323 "pitchfork_http.rl"
3490
+ { MARK(mark, p); }
3491
+ #line 324 "pitchfork_http.rl"
3492
+ { write_value(hp, buffer, p); }
3493
+ goto st116;
3494
+ tr186:
3495
+ #line 324 "pitchfork_http.rl"
3496
+ { write_value(hp, buffer, p); }
3497
+ goto st116;
3498
+ st116:
3499
+ if ( ++p == pe )
3500
+ goto _test_eof116;
3501
+ case 116:
3502
+ #line 3503 "pitchfork_http.c"
3503
+ if ( (*p) == 10 )
3504
+ goto st114;
3505
+ goto st0;
3506
+ tr173:
3507
+ #line 323 "pitchfork_http.rl"
3508
+ { MARK(mark, p); }
3509
+ goto st117;
3510
+ st117:
3511
+ if ( ++p == pe )
3512
+ goto _test_eof117;
3513
+ case 117:
3514
+ #line 3515 "pitchfork_http.c"
3515
+ switch( (*p) ) {
3516
+ case 10: goto tr176;
3517
+ case 13: goto tr177;
3518
+ case 127: goto st0;
3519
+ }
3520
+ if ( (*p) > 8 ) {
3521
+ if ( 11 <= (*p) && (*p) <= 31 )
3522
+ goto st0;
3523
+ } else
3524
+ goto st0;
3525
+ goto st117;
3526
+ tr167:
3527
+ #line 390 "pitchfork_http.rl"
3528
+ {
3529
+ cs = http_parser_first_final;
3530
+ goto post_exec;
3531
+ }
3532
+ goto st124;
3533
+ st124:
3534
+ if ( ++p == pe )
3535
+ goto _test_eof124;
3536
+ case 124:
3537
+ #line 3538 "pitchfork_http.c"
3538
+ goto st0;
3539
+ st118:
3540
+ if ( ++p == pe )
3541
+ goto _test_eof118;
3542
+ case 118:
3543
+ if ( (*p) == 10 )
3544
+ goto tr167;
3545
+ goto st0;
3546
+ tr169:
3547
+ #line 319 "pitchfork_http.rl"
3548
+ { MARK(start.field, p); }
3549
+ #line 320 "pitchfork_http.rl"
3550
+ { snake_upcase_char(deconst(p)); }
3551
+ goto st119;
3552
+ tr178:
3553
+ #line 320 "pitchfork_http.rl"
3554
+ { snake_upcase_char(deconst(p)); }
3555
+ goto st119;
3556
+ st119:
3557
+ if ( ++p == pe )
3558
+ goto _test_eof119;
3559
+ case 119:
3560
+ #line 3561 "pitchfork_http.c"
3561
+ switch( (*p) ) {
3562
+ case 33: goto tr178;
3563
+ case 58: goto tr179;
3564
+ case 124: goto tr178;
3565
+ case 126: goto tr178;
3566
+ }
3567
+ if ( (*p) < 45 ) {
3568
+ if ( (*p) > 39 ) {
3569
+ if ( 42 <= (*p) && (*p) <= 43 )
3570
+ goto tr178;
3571
+ } else if ( (*p) >= 35 )
3572
+ goto tr178;
3573
+ } else if ( (*p) > 46 ) {
3574
+ if ( (*p) < 65 ) {
3575
+ if ( 48 <= (*p) && (*p) <= 57 )
3576
+ goto tr178;
3577
+ } else if ( (*p) > 90 ) {
3578
+ if ( 94 <= (*p) && (*p) <= 122 )
3579
+ goto tr178;
3580
+ } else
3581
+ goto tr178;
3582
+ } else
3583
+ goto tr178;
3584
+ goto st0;
3585
+ tr180:
3586
+ #line 323 "pitchfork_http.rl"
3587
+ { MARK(mark, p); }
3588
+ goto st120;
3589
+ tr179:
3590
+ #line 322 "pitchfork_http.rl"
3591
+ { hp->s.field_len = LEN(start.field, p); }
3592
+ goto st120;
3593
+ st120:
3594
+ if ( ++p == pe )
3595
+ goto _test_eof120;
3596
+ case 120:
3597
+ #line 3598 "pitchfork_http.c"
3598
+ switch( (*p) ) {
3599
+ case 9: goto tr180;
3600
+ case 10: goto tr181;
3601
+ case 13: goto tr182;
3602
+ case 32: goto tr180;
3603
+ case 127: goto st0;
3604
+ }
3605
+ if ( (*p) <= 31 )
3606
+ goto st0;
3607
+ goto tr183;
3608
+ tr183:
3609
+ #line 323 "pitchfork_http.rl"
3610
+ { MARK(mark, p); }
3611
+ goto st121;
3612
+ st121:
3613
+ if ( ++p == pe )
3614
+ goto _test_eof121;
3615
+ case 121:
3616
+ #line 3617 "pitchfork_http.c"
3617
+ switch( (*p) ) {
3618
+ case 10: goto tr185;
3619
+ case 13: goto tr186;
3620
+ case 127: goto st0;
3621
+ }
3622
+ if ( (*p) > 8 ) {
3623
+ if ( 11 <= (*p) && (*p) <= 31 )
3624
+ goto st0;
3625
+ } else
3626
+ goto st0;
3627
+ goto st121;
3628
+ }
3629
+ _test_eof2: cs = 2; goto _test_eof;
3630
+ _test_eof3: cs = 3; goto _test_eof;
3631
+ _test_eof4: cs = 4; goto _test_eof;
3632
+ _test_eof5: cs = 5; goto _test_eof;
3633
+ _test_eof6: cs = 6; goto _test_eof;
3634
+ _test_eof7: cs = 7; goto _test_eof;
3635
+ _test_eof8: cs = 8; goto _test_eof;
3636
+ _test_eof9: cs = 9; goto _test_eof;
3637
+ _test_eof10: cs = 10; goto _test_eof;
3638
+ _test_eof11: cs = 11; goto _test_eof;
3639
+ _test_eof12: cs = 12; goto _test_eof;
3640
+ _test_eof13: cs = 13; goto _test_eof;
3641
+ _test_eof14: cs = 14; goto _test_eof;
3642
+ _test_eof15: cs = 15; goto _test_eof;
3643
+ _test_eof16: cs = 16; goto _test_eof;
3644
+ _test_eof17: cs = 17; goto _test_eof;
3645
+ _test_eof122: cs = 122; goto _test_eof;
3646
+ _test_eof18: cs = 18; goto _test_eof;
3647
+ _test_eof19: cs = 19; goto _test_eof;
3648
+ _test_eof20: cs = 20; goto _test_eof;
3649
+ _test_eof21: cs = 21; goto _test_eof;
3650
+ _test_eof22: cs = 22; goto _test_eof;
3651
+ _test_eof23: cs = 23; goto _test_eof;
3652
+ _test_eof24: cs = 24; goto _test_eof;
3653
+ _test_eof25: cs = 25; goto _test_eof;
3654
+ _test_eof26: cs = 26; goto _test_eof;
3655
+ _test_eof27: cs = 27; goto _test_eof;
3656
+ _test_eof28: cs = 28; goto _test_eof;
3657
+ _test_eof29: cs = 29; goto _test_eof;
3658
+ _test_eof30: cs = 30; goto _test_eof;
3659
+ _test_eof31: cs = 31; goto _test_eof;
3660
+ _test_eof32: cs = 32; goto _test_eof;
3661
+ _test_eof33: cs = 33; goto _test_eof;
3662
+ _test_eof34: cs = 34; goto _test_eof;
3663
+ _test_eof35: cs = 35; goto _test_eof;
3664
+ _test_eof36: cs = 36; goto _test_eof;
3665
+ _test_eof37: cs = 37; goto _test_eof;
3666
+ _test_eof38: cs = 38; goto _test_eof;
3667
+ _test_eof39: cs = 39; goto _test_eof;
3668
+ _test_eof40: cs = 40; goto _test_eof;
3669
+ _test_eof41: cs = 41; goto _test_eof;
3670
+ _test_eof42: cs = 42; goto _test_eof;
3671
+ _test_eof43: cs = 43; goto _test_eof;
3672
+ _test_eof44: cs = 44; goto _test_eof;
3673
+ _test_eof45: cs = 45; goto _test_eof;
3674
+ _test_eof46: cs = 46; goto _test_eof;
3675
+ _test_eof47: cs = 47; goto _test_eof;
3676
+ _test_eof48: cs = 48; goto _test_eof;
3677
+ _test_eof49: cs = 49; goto _test_eof;
3678
+ _test_eof50: cs = 50; goto _test_eof;
3679
+ _test_eof51: cs = 51; goto _test_eof;
3680
+ _test_eof52: cs = 52; goto _test_eof;
3681
+ _test_eof53: cs = 53; goto _test_eof;
3682
+ _test_eof54: cs = 54; goto _test_eof;
3683
+ _test_eof55: cs = 55; goto _test_eof;
3684
+ _test_eof56: cs = 56; goto _test_eof;
3685
+ _test_eof57: cs = 57; goto _test_eof;
3686
+ _test_eof58: cs = 58; goto _test_eof;
3687
+ _test_eof59: cs = 59; goto _test_eof;
3688
+ _test_eof60: cs = 60; goto _test_eof;
3689
+ _test_eof61: cs = 61; goto _test_eof;
3690
+ _test_eof62: cs = 62; goto _test_eof;
3691
+ _test_eof63: cs = 63; goto _test_eof;
3692
+ _test_eof64: cs = 64; goto _test_eof;
3693
+ _test_eof65: cs = 65; goto _test_eof;
3694
+ _test_eof66: cs = 66; goto _test_eof;
3695
+ _test_eof67: cs = 67; goto _test_eof;
3696
+ _test_eof68: cs = 68; goto _test_eof;
3697
+ _test_eof69: cs = 69; goto _test_eof;
3698
+ _test_eof70: cs = 70; goto _test_eof;
3699
+ _test_eof71: cs = 71; goto _test_eof;
3700
+ _test_eof72: cs = 72; goto _test_eof;
3701
+ _test_eof73: cs = 73; goto _test_eof;
3702
+ _test_eof74: cs = 74; goto _test_eof;
3703
+ _test_eof75: cs = 75; goto _test_eof;
3704
+ _test_eof76: cs = 76; goto _test_eof;
3705
+ _test_eof77: cs = 77; goto _test_eof;
3706
+ _test_eof78: cs = 78; goto _test_eof;
3707
+ _test_eof79: cs = 79; goto _test_eof;
3708
+ _test_eof80: cs = 80; goto _test_eof;
3709
+ _test_eof81: cs = 81; goto _test_eof;
3710
+ _test_eof82: cs = 82; goto _test_eof;
3711
+ _test_eof83: cs = 83; goto _test_eof;
3712
+ _test_eof84: cs = 84; goto _test_eof;
3713
+ _test_eof85: cs = 85; goto _test_eof;
3714
+ _test_eof86: cs = 86; goto _test_eof;
3715
+ _test_eof87: cs = 87; goto _test_eof;
3716
+ _test_eof88: cs = 88; goto _test_eof;
3717
+ _test_eof89: cs = 89; goto _test_eof;
3718
+ _test_eof90: cs = 90; goto _test_eof;
3719
+ _test_eof91: cs = 91; goto _test_eof;
3720
+ _test_eof92: cs = 92; goto _test_eof;
3721
+ _test_eof93: cs = 93; goto _test_eof;
3722
+ _test_eof94: cs = 94; goto _test_eof;
3723
+ _test_eof95: cs = 95; goto _test_eof;
3724
+ _test_eof96: cs = 96; goto _test_eof;
3725
+ _test_eof97: cs = 97; goto _test_eof;
3726
+ _test_eof98: cs = 98; goto _test_eof;
3727
+ _test_eof99: cs = 99; goto _test_eof;
3728
+ _test_eof100: cs = 100; goto _test_eof;
3729
+ _test_eof101: cs = 101; goto _test_eof;
3730
+ _test_eof123: cs = 123; goto _test_eof;
3731
+ _test_eof102: cs = 102; goto _test_eof;
3732
+ _test_eof103: cs = 103; goto _test_eof;
3733
+ _test_eof104: cs = 104; goto _test_eof;
3734
+ _test_eof105: cs = 105; goto _test_eof;
3735
+ _test_eof106: cs = 106; goto _test_eof;
3736
+ _test_eof107: cs = 107; goto _test_eof;
3737
+ _test_eof108: cs = 108; goto _test_eof;
3738
+ _test_eof109: cs = 109; goto _test_eof;
3739
+ _test_eof110: cs = 110; goto _test_eof;
3740
+ _test_eof111: cs = 111; goto _test_eof;
3741
+ _test_eof112: cs = 112; goto _test_eof;
3742
+ _test_eof113: cs = 113; goto _test_eof;
3743
+ _test_eof114: cs = 114; goto _test_eof;
3744
+ _test_eof115: cs = 115; goto _test_eof;
3745
+ _test_eof116: cs = 116; goto _test_eof;
3746
+ _test_eof117: cs = 117; goto _test_eof;
3747
+ _test_eof124: cs = 124; goto _test_eof;
3748
+ _test_eof118: cs = 118; goto _test_eof;
3749
+ _test_eof119: cs = 119; goto _test_eof;
3750
+ _test_eof120: cs = 120; goto _test_eof;
3751
+ _test_eof121: cs = 121; goto _test_eof;
3752
+
3753
+ _test_eof: {}
3754
+ _out: {}
3755
+ }
3756
+
3757
+ #line 464 "pitchfork_http.rl"
3758
+ post_exec: /* "_out:" also goes here */
3759
+ if (hp->cs != http_parser_error)
3760
+ hp->cs = cs;
3761
+ hp->offset = ulong2uint(p - buffer);
3762
+
3763
+ assert(p <= pe && "buffer overflow after parsing execute");
3764
+ assert(hp->offset <= len && "offset longer than length");
3765
+ }
3766
+
3767
+ static void hp_mark(void *ptr)
3768
+ {
3769
+ struct http_parser *hp = ptr;
3770
+
3771
+ rb_gc_mark(hp->buf);
3772
+ rb_gc_mark(hp->env);
3773
+ rb_gc_mark(hp->cont);
3774
+ }
3775
+
3776
+ static size_t hp_memsize(const void *ptr)
3777
+ {
3778
+ return sizeof(struct http_parser);
3779
+ }
3780
+
3781
+ static const rb_data_type_t hp_type = {
3782
+ "pitchfork_http",
3783
+ { hp_mark, RUBY_TYPED_DEFAULT_FREE, hp_memsize, /* reserved */ },
3784
+ /* parent, data, [ flags ] */
3785
+ };
3786
+
3787
+ static struct http_parser *data_get(VALUE self)
3788
+ {
3789
+ struct http_parser *hp;
3790
+
3791
+ TypedData_Get_Struct(self, struct http_parser, &hp_type, hp);
3792
+ assert(hp && "failed to extract http_parser struct");
3793
+ return hp;
3794
+ }
3795
+
3796
+ /*
3797
+ * set rack.url_scheme to "https" or "http", no others are allowed by Rack
3798
+ * this resembles the Rack::Request#scheme method as of rack commit
3799
+ * 35bb5ba6746b5d346de9202c004cc926039650c7
3800
+ */
3801
+ static void set_url_scheme(VALUE env, VALUE *server_port)
3802
+ {
3803
+ VALUE scheme = rb_hash_aref(env, g_rack_url_scheme);
3804
+
3805
+ if (NIL_P(scheme)) {
3806
+ /*
3807
+ * would anybody be horribly opposed to removing the X-Forwarded-SSL
3808
+ * and X-Forwarded-Proto handling from this parser? We've had it
3809
+ * forever and nobody has said anything against it, either.
3810
+ * Anyways, please send comments to our public mailing list:
3811
+ * pitchfork-public@yhbt.net (no HTML mail, no subscription necessary)
3812
+ */
3813
+ scheme = rb_hash_aref(env, g_http_x_forwarded_ssl);
3814
+ if (!NIL_P(scheme) && STR_CSTR_EQ(scheme, "on")) {
3815
+ *server_port = g_port_443;
3816
+ scheme = g_https;
3817
+ } else {
3818
+ scheme = rb_hash_aref(env, g_http_x_forwarded_proto);
3819
+ if (NIL_P(scheme)) {
3820
+ scheme = g_http;
3821
+ } else {
3822
+ long len = RSTRING_LEN(scheme);
3823
+ if (len >= 5 && !memcmp(RSTRING_PTR(scheme), "https", 5)) {
3824
+ if (len != 5)
3825
+ scheme = g_https;
3826
+ *server_port = g_port_443;
3827
+ } else {
3828
+ scheme = g_http;
3829
+ }
3830
+ }
3831
+ }
3832
+ rb_hash_aset(env, g_rack_url_scheme, scheme);
3833
+ } else if (STR_CSTR_EQ(scheme, "https")) {
3834
+ *server_port = g_port_443;
3835
+ } else {
3836
+ assert(*server_port == g_port_80 && "server_port not set");
3837
+ }
3838
+ }
3839
+
3840
+ /*
3841
+ * Parse and set the SERVER_NAME and SERVER_PORT variables
3842
+ * Not supporting X-Forwarded-Host/X-Forwarded-Port in here since
3843
+ * anybody who needs them is using an unsupported configuration and/or
3844
+ * incompetent. Rack::Request will handle X-Forwarded-{Port,Host} just
3845
+ * fine.
3846
+ */
3847
+ static void set_server_vars(VALUE env, VALUE *server_port)
3848
+ {
3849
+ VALUE server_name = g_localhost;
3850
+ VALUE host = rb_hash_aref(env, g_http_host);
3851
+
3852
+ if (!NIL_P(host)) {
3853
+ char *host_ptr = RSTRING_PTR(host);
3854
+ long host_len = RSTRING_LEN(host);
3855
+ char *colon;
3856
+
3857
+ if (*host_ptr == '[') { /* ipv6 address format */
3858
+ char *rbracket = memchr(host_ptr + 1, ']', host_len - 1);
3859
+
3860
+ if (rbracket)
3861
+ colon = (rbracket[1] == ':') ? rbracket + 1 : NULL;
3862
+ else
3863
+ colon = memchr(host_ptr + 1, ':', host_len - 1);
3864
+ } else {
3865
+ colon = memchr(host_ptr, ':', host_len);
3866
+ }
3867
+
3868
+ if (colon) {
3869
+ long port_start = colon - host_ptr + 1;
3870
+
3871
+ server_name = rb_str_substr(host, 0, colon - host_ptr);
3872
+ if ((host_len - port_start) > 0)
3873
+ *server_port = rb_str_substr(host, port_start, host_len);
3874
+ } else {
3875
+ server_name = host;
3876
+ }
3877
+ }
3878
+ rb_hash_aset(env, g_server_name, server_name);
3879
+ rb_hash_aset(env, g_server_port, *server_port);
3880
+ }
3881
+
3882
+ static void finalize_header(struct http_parser *hp)
3883
+ {
3884
+ VALUE server_port = g_port_80;
3885
+
3886
+ set_url_scheme(hp->env, &server_port);
3887
+ set_server_vars(hp->env, &server_port);
3888
+
3889
+ if (!HP_FL_TEST(hp, HASHEADER))
3890
+ rb_hash_aset(hp->env, g_server_protocol, g_http_09);
3891
+
3892
+ /* rack requires QUERY_STRING */
3893
+ if (NIL_P(rb_hash_aref(hp->env, g_query_string)))
3894
+ rb_hash_aset(hp->env, g_query_string, rb_str_new(NULL, 0));
3895
+ }
3896
+
3897
+ static VALUE HttpParser_alloc(VALUE klass)
3898
+ {
3899
+ struct http_parser *hp;
3900
+
3901
+ return TypedData_Make_Struct(klass, struct http_parser, &hp_type, hp);
3902
+ }
3903
+
3904
+ /**
3905
+ * call-seq:
3906
+ * parser.new => parser
3907
+ *
3908
+ * Creates a new parser.
3909
+ */
3910
+ static VALUE HttpParser_init(VALUE self)
3911
+ {
3912
+ struct http_parser *hp = data_get(self);
3913
+
3914
+ http_parser_init(hp);
3915
+ hp->buf = rb_str_new(NULL, 0);
3916
+ hp->env = rb_hash_new();
3917
+
3918
+ return self;
3919
+ }
3920
+
3921
+ /**
3922
+ * call-seq:
3923
+ * parser.clear => parser
3924
+ *
3925
+ * Resets the parser to it's initial state so that you can reuse it
3926
+ * rather than making new ones.
3927
+ */
3928
+ static VALUE HttpParser_clear(VALUE self)
3929
+ {
3930
+ struct http_parser *hp = data_get(self);
3931
+
3932
+ /* we can't safely reuse .buf and .env if hijacked */
3933
+ if (HP_FL_TEST(hp, HIJACK))
3934
+ return HttpParser_init(self);
3935
+
3936
+ http_parser_init(hp);
3937
+ rb_hash_clear(hp->env);
3938
+
3939
+ return self;
3940
+ }
3941
+
3942
+ static void advance_str(VALUE str, off_t nr)
3943
+ {
3944
+ long len = RSTRING_LEN(str);
3945
+
3946
+ if (len == 0)
3947
+ return;
3948
+
3949
+ rb_str_modify(str);
3950
+
3951
+ assert(nr <= len && "trying to advance past end of buffer");
3952
+ len -= nr;
3953
+ if (len > 0) /* unlikely, len is usually 0 */
3954
+ memmove(RSTRING_PTR(str), RSTRING_PTR(str) + nr, len);
3955
+ rb_str_set_len(str, len);
3956
+ }
3957
+
3958
+ /**
3959
+ * call-seq:
3960
+ * parser.content_length => nil or Integer
3961
+ *
3962
+ * Returns the number of bytes left to run through HttpParser#filter_body.
3963
+ * This will initially be the value of the "Content-Length" HTTP header
3964
+ * after header parsing is complete and will decrease in value as
3965
+ * HttpParser#filter_body is called for each chunk. This should return
3966
+ * zero for requests with no body.
3967
+ *
3968
+ * This will return nil on "Transfer-Encoding: chunked" requests.
3969
+ */
3970
+ static VALUE HttpParser_content_length(VALUE self)
3971
+ {
3972
+ struct http_parser *hp = data_get(self);
3973
+
3974
+ return HP_FL_TEST(hp, CHUNKED) ? Qnil : OFFT2NUM(hp->len.content);
3975
+ }
3976
+
3977
+ /**
3978
+ * Document-method: parse
3979
+ * call-seq:
3980
+ * parser.parse => env or nil
3981
+ *
3982
+ * Takes a Hash and a String of data, parses the String of data filling
3983
+ * in the Hash returning the Hash if parsing is finished, nil otherwise
3984
+ * When returning the env Hash, it may modify data to point to where
3985
+ * body processing should begin.
3986
+ *
3987
+ * Raises HttpParserError if there are parsing errors.
3988
+ */
3989
+ static VALUE HttpParser_parse(VALUE self)
3990
+ {
3991
+ struct http_parser *hp = data_get(self);
3992
+ VALUE data = hp->buf;
3993
+
3994
+ if (HP_FL_TEST(hp, TO_CLEAR))
3995
+ HttpParser_clear(self);
3996
+
3997
+ http_parser_execute(hp, RSTRING_PTR(data), RSTRING_LEN(data));
3998
+ if (hp->offset > MAX_HEADER_LEN)
3999
+ parser_raise(e413, "HTTP header is too large");
4000
+
4001
+ if (hp->cs == http_parser_first_final ||
4002
+ hp->cs == http_parser_en_ChunkedBody) {
4003
+ advance_str(data, hp->offset + 1);
4004
+ hp->offset = 0;
4005
+ if (HP_FL_TEST(hp, INTRAILER))
4006
+ HP_FL_SET(hp, REQEOF);
4007
+
4008
+ return hp->env;
4009
+ }
4010
+
4011
+ if (hp->cs == http_parser_error)
4012
+ parser_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
4013
+
4014
+ return Qnil;
4015
+ }
4016
+
4017
+ /**
4018
+ * Document-method: parse
4019
+ * call-seq:
4020
+ * parser.add_parse(buffer) => env or nil
4021
+ *
4022
+ * adds the contents of +buffer+ to the internal buffer and attempts to
4023
+ * continue parsing. Returns the +env+ Hash on success or nil if more
4024
+ * data is needed.
4025
+ *
4026
+ * Raises HttpParserError if there are parsing errors.
4027
+ */
4028
+ static VALUE HttpParser_add_parse(VALUE self, VALUE buffer)
4029
+ {
4030
+ struct http_parser *hp = data_get(self);
4031
+
4032
+ Check_Type(buffer, T_STRING);
4033
+ rb_str_buf_append(hp->buf, buffer);
4034
+
4035
+ return HttpParser_parse(self);
4036
+ }
4037
+
4038
+ /**
4039
+ * Document-method: trailers
4040
+ * call-seq:
4041
+ * parser.trailers(req, data) => req or nil
4042
+ *
4043
+ * This is an alias for HttpParser#headers
4044
+ */
4045
+
4046
+ /**
4047
+ * Document-method: headers
4048
+ */
4049
+ static VALUE HttpParser_headers(VALUE self, VALUE env, VALUE buf)
4050
+ {
4051
+ struct http_parser *hp = data_get(self);
4052
+
4053
+ hp->env = env;
4054
+ hp->buf = buf;
4055
+
4056
+ return HttpParser_parse(self);
4057
+ }
4058
+
4059
+ static int chunked_eof(struct http_parser *hp)
4060
+ {
4061
+ return ((hp->cs == http_parser_first_final) || HP_FL_TEST(hp, INTRAILER));
4062
+ }
4063
+
4064
+ /**
4065
+ * call-seq:
4066
+ * parser.body_eof? => true or false
4067
+ *
4068
+ * Detects if we're done filtering the body or not. This can be used
4069
+ * to detect when to stop calling HttpParser#filter_body.
4070
+ */
4071
+ static VALUE HttpParser_body_eof(VALUE self)
4072
+ {
4073
+ struct http_parser *hp = data_get(self);
4074
+
4075
+ if (HP_FL_TEST(hp, CHUNKED))
4076
+ return chunked_eof(hp) ? Qtrue : Qfalse;
4077
+
4078
+ return hp->len.content == 0 ? Qtrue : Qfalse;
4079
+ }
4080
+
4081
+ /**
4082
+ * call-seq:
4083
+ * parser.keepalive? => true or false
4084
+ *
4085
+ * This should be used to detect if a request can really handle
4086
+ * keepalives and pipelining. Currently, the rules are:
4087
+ *
4088
+ * 1. MUST be a GET or HEAD request
4089
+ * 2. MUST be HTTP/1.1 +or+ HTTP/1.0 with "Connection: keep-alive"
4090
+ * 3. MUST NOT have "Connection: close" set
4091
+ */
4092
+ static VALUE HttpParser_keepalive(VALUE self)
4093
+ {
4094
+ struct http_parser *hp = data_get(self);
4095
+
4096
+ return HP_FL_ALL(hp, KEEPALIVE) ? Qtrue : Qfalse;
4097
+ }
4098
+
4099
+ /**
4100
+ * call-seq:
4101
+ * parser.next? => true or false
4102
+ *
4103
+ * Exactly like HttpParser#keepalive?, except it will reset the internal
4104
+ * parser state on next parse if it returns true.
4105
+ */
4106
+ static VALUE HttpParser_next(VALUE self)
4107
+ {
4108
+ struct http_parser *hp = data_get(self);
4109
+
4110
+ if (HP_FL_ALL(hp, KEEPALIVE)) {
4111
+ HP_FL_SET(hp, TO_CLEAR);
4112
+ return Qtrue;
4113
+ }
4114
+ return Qfalse;
4115
+ }
4116
+
4117
+ /**
4118
+ * call-seq:
4119
+ * parser.headers? => true or false
4120
+ *
4121
+ * This should be used to detect if a request has headers (and if
4122
+ * the response will have headers as well). HTTP/0.9 requests
4123
+ * should return false, all subsequent HTTP versions will return true
4124
+ */
4125
+ static VALUE HttpParser_has_headers(VALUE self)
4126
+ {
4127
+ struct http_parser *hp = data_get(self);
4128
+
4129
+ return HP_FL_TEST(hp, HASHEADER) ? Qtrue : Qfalse;
4130
+ }
4131
+
4132
+ static VALUE HttpParser_buf(VALUE self)
4133
+ {
4134
+ return data_get(self)->buf;
4135
+ }
4136
+
4137
+ static VALUE HttpParser_env(VALUE self)
4138
+ {
4139
+ return data_get(self)->env;
4140
+ }
4141
+
4142
+ static VALUE HttpParser_hijacked_bang(VALUE self)
4143
+ {
4144
+ struct http_parser *hp = data_get(self);
4145
+
4146
+ HP_FL_SET(hp, HIJACK);
4147
+
4148
+ return self;
4149
+ }
4150
+
4151
+ /**
4152
+ * call-seq:
4153
+ * parser.filter_body(dst, src) => nil/src
4154
+ *
4155
+ * Takes a String of +src+, will modify data if dechunking is done.
4156
+ * Returns +nil+ if there is more data left to process. Returns
4157
+ * +src+ if body processing is complete. When returning +src+,
4158
+ * it may modify +src+ so the start of the string points to where
4159
+ * the body ended so that trailer processing can begin.
4160
+ *
4161
+ * Raises HttpParserError if there are dechunking errors.
4162
+ * Basically this is a glorified memcpy(3) that copies +src+
4163
+ * into +buf+ while filtering it through the dechunker.
4164
+ */
4165
+ static VALUE HttpParser_filter_body(VALUE self, VALUE dst, VALUE src)
4166
+ {
4167
+ struct http_parser *hp = data_get(self);
4168
+ char *srcptr;
4169
+ long srclen;
4170
+
4171
+ srcptr = RSTRING_PTR(src);
4172
+ srclen = RSTRING_LEN(src);
4173
+
4174
+ StringValue(dst);
4175
+
4176
+ if (HP_FL_TEST(hp, CHUNKED)) {
4177
+ if (!chunked_eof(hp)) {
4178
+ rb_str_modify(dst);
4179
+ rb_str_resize(dst, srclen); /* we can never copy more than srclen bytes */
4180
+
4181
+ hp->s.dest_offset = 0;
4182
+ hp->cont = dst;
4183
+ hp->buf = src;
4184
+ http_parser_execute(hp, srcptr, srclen);
4185
+ if (hp->cs == http_parser_error)
4186
+ parser_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
4187
+
4188
+ assert(hp->s.dest_offset <= hp->offset &&
4189
+ "destination buffer overflow");
4190
+ advance_str(src, hp->offset);
4191
+ rb_str_set_len(dst, hp->s.dest_offset);
4192
+
4193
+ if (RSTRING_LEN(dst) == 0 && chunked_eof(hp)) {
4194
+ assert(hp->len.chunk == 0 && "chunk at EOF but more to parse");
4195
+ } else {
4196
+ src = Qnil;
4197
+ }
4198
+ }
4199
+ } else {
4200
+ /* no need to enter the Ragel machine for unchunked transfers */
4201
+ assert(hp->len.content >= 0 && "negative Content-Length");
4202
+ if (hp->len.content > 0) {
4203
+ long nr = MIN(srclen, hp->len.content);
4204
+
4205
+ rb_str_modify(dst);
4206
+ rb_str_resize(dst, nr);
4207
+ /*
4208
+ * using rb_str_replace() to avoid memcpy() doesn't help in
4209
+ * most cases because a GC-aware programmer will pass an explicit
4210
+ * buffer to env["rack.input"].read and reuse the buffer in a loop.
4211
+ * This causes copy-on-write behavior to be triggered anyways
4212
+ * when the +src+ buffer is modified (when reading off the socket).
4213
+ */
4214
+ hp->buf = src;
4215
+ memcpy(RSTRING_PTR(dst), srcptr, nr);
4216
+ hp->len.content -= nr;
4217
+ if (hp->len.content == 0) {
4218
+ HP_FL_SET(hp, REQEOF);
4219
+ hp->cs = http_parser_first_final;
4220
+ }
4221
+ advance_str(src, nr);
4222
+ src = Qnil;
4223
+ }
4224
+ }
4225
+ hp->offset = 0; /* for trailer parsing */
4226
+ return src;
4227
+ }
4228
+
4229
+ static VALUE HttpParser_rssset(VALUE self, VALUE boolean)
4230
+ {
4231
+ struct http_parser *hp = data_get(self);
4232
+
4233
+ if (RTEST(boolean))
4234
+ HP_FL_SET(hp, RESSTART);
4235
+ else
4236
+ HP_FL_UNSET(hp, RESSTART);
4237
+
4238
+ return boolean; /* ignored by Ruby anyways */
4239
+ }
4240
+
4241
+ static VALUE HttpParser_rssget(VALUE self)
4242
+ {
4243
+ struct http_parser *hp = data_get(self);
4244
+
4245
+ return HP_FL_TEST(hp, RESSTART) ? Qtrue : Qfalse;
4246
+ }
4247
+
4248
+ #define SET_GLOBAL(var,str) do { \
4249
+ var = find_common_field(str, sizeof(str) - 1); \
4250
+ assert(!NIL_P(var) && "missed global field"); \
4251
+ } while (0)
4252
+
4253
+ void Init_pitchfork_http(void)
4254
+ {
4255
+ VALUE mPitchfork;
4256
+
4257
+ mPitchfork = rb_define_module("Pitchfork");
4258
+ cHttpParser = rb_define_class_under(mPitchfork, "HttpParser", rb_cObject);
4259
+ eHttpParserError =
4260
+ rb_define_class_under(mPitchfork, "HttpParserError", rb_eIOError);
4261
+ e413 = rb_define_class_under(mPitchfork, "RequestEntityTooLargeError",
4262
+ eHttpParserError);
4263
+ e414 = rb_define_class_under(mPitchfork, "RequestURITooLongError",
4264
+ eHttpParserError);
4265
+
4266
+ id_uminus = rb_intern("-@");
4267
+ init_globals();
4268
+ rb_define_alloc_func(cHttpParser, HttpParser_alloc);
4269
+ rb_define_method(cHttpParser, "initialize", HttpParser_init, 0);
4270
+ rb_define_method(cHttpParser, "clear", HttpParser_clear, 0);
4271
+ rb_define_method(cHttpParser, "parse", HttpParser_parse, 0);
4272
+ rb_define_method(cHttpParser, "add_parse", HttpParser_add_parse, 1);
4273
+ rb_define_method(cHttpParser, "headers", HttpParser_headers, 2);
4274
+ rb_define_method(cHttpParser, "trailers", HttpParser_headers, 2);
4275
+ rb_define_method(cHttpParser, "filter_body", HttpParser_filter_body, 2);
4276
+ rb_define_method(cHttpParser, "content_length", HttpParser_content_length, 0);
4277
+ rb_define_method(cHttpParser, "body_eof?", HttpParser_body_eof, 0);
4278
+ rb_define_method(cHttpParser, "keepalive?", HttpParser_keepalive, 0);
4279
+ rb_define_method(cHttpParser, "headers?", HttpParser_has_headers, 0);
4280
+ rb_define_method(cHttpParser, "next?", HttpParser_next, 0);
4281
+ rb_define_method(cHttpParser, "buf", HttpParser_buf, 0);
4282
+ rb_define_method(cHttpParser, "env", HttpParser_env, 0);
4283
+ rb_define_method(cHttpParser, "hijacked!", HttpParser_hijacked_bang, 0);
4284
+ rb_define_method(cHttpParser, "response_start_sent=", HttpParser_rssset, 1);
4285
+ rb_define_method(cHttpParser, "response_start_sent", HttpParser_rssget, 0);
4286
+
4287
+ /*
4288
+ * The maximum size a single chunk when using chunked transfer encoding.
4289
+ * This is only a theoretical maximum used to detect errors in clients,
4290
+ * it is highly unlikely to encounter clients that send more than
4291
+ * several kilobytes at once.
4292
+ */
4293
+ rb_define_const(cHttpParser, "CHUNK_MAX", OFFT2NUM(UH_OFF_T_MAX));
4294
+
4295
+ /*
4296
+ * The maximum size of the body as specified by Content-Length.
4297
+ * This is only a theoretical maximum, the actual limit is subject
4298
+ * to the limits of the file system used for +Dir.tmpdir+.
4299
+ */
4300
+ rb_define_const(cHttpParser, "LENGTH_MAX", OFFT2NUM(UH_OFF_T_MAX));
4301
+
4302
+ rb_define_singleton_method(cHttpParser, "max_header_len=", set_maxhdrlen, 1);
4303
+
4304
+ init_common_fields();
4305
+ SET_GLOBAL(g_http_host, "HOST");
4306
+ SET_GLOBAL(g_http_trailer, "TRAILER");
4307
+ SET_GLOBAL(g_http_transfer_encoding, "TRANSFER_ENCODING");
4308
+ SET_GLOBAL(g_content_length, "CONTENT_LENGTH");
4309
+ SET_GLOBAL(g_http_connection, "CONNECTION");
4310
+ id_set_backtrace = rb_intern("set_backtrace");
4311
+ init_pitchfork_httpdate();
4312
+
4313
+ id_is_chunked_p = rb_intern("is_chunked?");
4314
+
4315
+ init_epollexclusive(mPitchfork);
4316
+ init_child_subreaper(mPitchfork);
4317
+ }
4318
+ #undef SET_GLOBAL