unicorn-simon 0.0.1

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