unicorn-rupcio 6.1.0

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