unicorn-heroku-wait 4.8.0.1.g0ed2.dirty

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