unicorn 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,4 @@
1
+ v0.6.0 - cleanups + optimizations, signals to {in,de}crement processes
1
2
  v0.5.4 - fix data corruption with some small uploads (not curl)
2
3
  v0.5.3 - fix 100% CPU usage when idle, small cleanups
3
4
  v0.5.2 - force Status: header for compat, small cleanups
@@ -1,6 +1,8 @@
1
1
  # use GNU Make to run tests in parallel, and without depending on Rubygems
2
2
  all:: test
3
3
  ruby = ruby
4
+ ragel = ragel
5
+ RLFLAGS = -G2
4
6
  -include local.mk
5
7
  ruby_bin := $(shell which $(ruby))
6
8
  ifeq ($(DLEXT),) # "so" for Linux
@@ -14,7 +16,8 @@ endif
14
16
  awk_slow := awk '/def test_/{print FILENAME"--"$$2".n"}' 2>/dev/null
15
17
 
16
18
  rails_vers := $(subst test/rails/app-,,$(wildcard test/rails/app-*))
17
- slow_tests := test/unit/test_server.rb test/exec/test_exec.rb
19
+ slow_tests := test/unit/test_server.rb test/exec/test_exec.rb \
20
+ test/unit/test_signals.rb test/unit/test_upload.rb
18
21
  log_suffix = .$(RUBY_VERSION).log
19
22
  T_r := $(wildcard test/rails/test*.rb)
20
23
  T := $(filter-out $(slow_tests) $(T_r), $(wildcard test/*/test*.rb))
@@ -24,32 +27,31 @@ T_n_log := $(subst .n,$(log_suffix),$(T_n))
24
27
  T_r_log := $(subst .r,$(log_suffix),$(T_r))
25
28
  test_prefix = $(CURDIR)/test/install-$(RUBY_VERSION)
26
29
 
27
- http11_deps := $(addprefix ext/unicorn/http11/, \
28
- ext_help.h http11.c http11_parser.c http11_parser.h \
29
- http11_parser.rl http11_parser_common.rl)
30
- inst_deps := $(wildcard bin/*) $(wildcard lib/*.rb) \
31
- $(wildcard lib/*/*.rb) $(http11_deps)
32
-
33
- ext/unicorn/http11/http11_parser.c: ext/unicorn/http11/http11_parser.rl
34
- cd $(@D) && ragel $(<F) -C -G2 -o $(@F)
35
- ext/unicorn/http11/Makefile: ext/unicorn/http11/extconf.rb $(http11_deps)
36
- cd $(@D) && $(ruby) $(<F)
37
- ext/unicorn/http11/http11.$(DLEXT): ext/unicorn/http11/Makefile
30
+ ext := ext/unicorn/http11
31
+ c_files := $(addprefix $(ext)/,ext_help.h http11.c http11_parser.h)
32
+ rl_files := $(addprefix $(ext)/,http11_parser.rl http11_parser_common.rl)
33
+ rb_files := $(shell grep '^\(bin\|lib\)' Manifest)
34
+ inst_deps := $(c_files) $(rb_files)
35
+
36
+ ragel: $(ext)/http11_parser.h
37
+ $(ext)/http11_parser.h: $(rl_files)
38
+ cd $(@D) && $(ragel) http11_parser.rl -C $(RLFLAGS) -o $(@F)
39
+ $(ruby) -i -p -e '$$_.gsub!(%r{[ \t]*$$},"")' $@
40
+ $(ext)/Makefile: $(ext)/extconf.rb $(c_files)
41
+ cd $(@D) && $(ruby) extconf.rb
42
+ $(ext)/http11.$(DLEXT): $(ext)/Makefile
38
43
  $(MAKE) -C $(@D)
39
- lib/unicorn/http11.$(DLEXT): ext/unicorn/http11/http11.$(DLEXT)
44
+ lib/unicorn/http11.$(DLEXT): $(ext)/http11.$(DLEXT)
40
45
  @mkdir -p lib
41
46
  install -m644 $< $@
42
47
  http11: lib/unicorn/http11.$(DLEXT)
43
48
 
44
- $(test_prefix)/.stamp: install-test
45
- > $@
46
-
47
- install-test: $(inst_deps)
48
- test -n "$(test_prefix)"
49
+ $(test_prefix)/.stamp: $(inst_deps)
49
50
  mkdir -p $(test_prefix)/.ccache
50
- tar c bin ext lib GNUmakefile | (cd $(test_prefix) && tar x)
51
+ tar c bin ext lib GNUmakefile Manifest | (cd $(test_prefix) && tar x)
51
52
  $(MAKE) -C $(test_prefix) clean
52
53
  $(MAKE) -C $(test_prefix) http11 shebang
54
+ > $@
53
55
 
54
56
  # this is only intended to be run within $(test_prefix)
55
57
  shebang: bin/unicorn bin/unicorn_rails
@@ -106,16 +108,13 @@ install: bin/unicorn bin/unicorn_rails
106
108
  $(RM) -r .install-tmp
107
109
  $(prep_setup_rb)
108
110
 
109
- clean-http11:
110
- -$(MAKE) -C ext/unicorn/http11 clean
111
- $(RM) ext/unicorn/http11/Makefile lib/unicorn/http11.$(DLEXT)
112
-
113
111
  setup_rb_files := .config InstalledFiles
114
- prep_setup_rb := @-$(RM) $(setup_rb_files);$(MAKE) -C ext/unicorn/http11 clean
112
+ prep_setup_rb := @-$(RM) $(setup_rb_files);$(MAKE) -C $(ext) clean
115
113
 
116
- clean: clean-http11
117
- $(RM) $(setup_rb_files)
118
- $(RM) $(t_log)
114
+ clean:
115
+ -$(MAKE) -C $(ext) clean
116
+ $(RM) $(ext)/Makefile lib/unicorn/http11.$(DLEXT)
117
+ $(RM) $(setup_rb_files) $(t_log)
119
118
  $(RM) -r $(test_prefix)
120
119
 
121
120
  Manifest:
data/Manifest CHANGED
@@ -16,7 +16,6 @@ bin/unicorn_rails
16
16
  ext/unicorn/http11/ext_help.h
17
17
  ext/unicorn/http11/extconf.rb
18
18
  ext/unicorn/http11/http11.c
19
- ext/unicorn/http11/http11_parser.c
20
19
  ext/unicorn/http11/http11_parser.h
21
20
  ext/unicorn/http11/http11_parser.rl
22
21
  ext/unicorn/http11/http11_parser_common.rl
@@ -30,7 +29,7 @@ lib/unicorn/const.rb
30
29
  lib/unicorn/http_request.rb
31
30
  lib/unicorn/http_response.rb
32
31
  lib/unicorn/launcher.rb
33
- lib/unicorn/socket.rb
32
+ lib/unicorn/socket_helper.rb
34
33
  lib/unicorn/util.rb
35
34
  local.mk.sample
36
35
  setup.rb
data/SIGNALS CHANGED
@@ -25,6 +25,10 @@ processes are documented here as well.
25
25
  * WINCH - gracefully stops workers but keep the master running.
26
26
  This will only work for daemonized processes.
27
27
 
28
+ * TTIN - increment the number of worker processes by one
29
+
30
+ * TTOU - decrement the number of worker processes by one
31
+
28
32
  === Worker Processes
29
33
 
30
34
  Sending signals directly to the worker processes should not normally be
data/TODO CHANGED
@@ -1,11 +1,5 @@
1
1
  == 1.0.0
2
2
 
3
- * reexec_worker_processes config option:
4
- This is the number of worker processes to startup initially
5
- when being reexecuted.
6
-
7
- Default: worker_processes/2 + 1
8
-
9
3
  * integration tests with nginx including bad client handling
10
4
 
11
5
  * tests for timeout
@@ -3,8 +3,7 @@ require 'unicorn/launcher'
3
3
  require 'optparse'
4
4
  require 'fileutils'
5
5
 
6
- rails_pid = File.join(Unicorn::HttpServer::DEFAULT_START_CTX[:cwd],
7
- "/tmp/pids/unicorn.pid")
6
+ rails_pid = "#{Unicorn::HttpServer::START_CTX[:cwd]}/tmp/pids/unicorn.pid"
8
7
  cmd = File.basename($0)
9
8
  daemonize = false
10
9
  listeners = []
@@ -115,10 +114,9 @@ end
115
114
 
116
115
  require 'pp' if $DEBUG
117
116
 
118
- # Loads Rails and the private version of Rack it bundles. Returns a
119
- # lambda of arity==0 that will return *another* lambda of arity==1
120
- # suitable for using inside Rack::Builder.new block.
121
- rails_loader = lambda do ||
117
+ # this won't run until after forking if preload_app is false
118
+ app = lambda do ||
119
+ # Load Rails and the private version of Rack it bundles.
122
120
  begin
123
121
  require 'config/boot'
124
122
  rescue LoadError => err
@@ -129,7 +127,7 @@ rails_loader = lambda do ||
129
127
  defined?(::Rails::VERSION::STRING) or
130
128
  abort "Rails::VERSION::STRING not defined by config/boot"
131
129
 
132
- case config
130
+ inner_app = case config
133
131
  when nil
134
132
  require 'config/environment'
135
133
 
@@ -155,12 +153,8 @@ rails_loader = lambda do ||
155
153
  require config
156
154
  Object.const_get(File.basename(config, '.rb').capitalize)
157
155
  end
158
- end
159
156
 
160
- # this won't run until after forking if preload_app is false
161
- app = lambda do ||
162
157
  map_path ||= '/'
163
- inner_app = rails_loader.call
164
158
  Rack::Builder.new do
165
159
  if inner_app.class.to_s == "Unicorn::App::OldRails"
166
160
  if map_path != '/'
@@ -1,9 +1,6 @@
1
1
  #ifndef ext_help_h
2
2
  #define ext_help_h
3
3
 
4
- #define RAISE_NOT_NULL(T) if(T == NULL) rb_raise(rb_eArgError, "NULL found for " # T " when shouldn't be.");
5
- #define DATA_GET(from,type,name) Data_Get_Struct(from,type,name); RAISE_NOT_NULL(name);
6
- #define REQUIRE_TYPE(V, T) if(TYPE(V) != T) rb_raise(rb_eTypeError, "Wrong argument type for " # V " required " # T);
7
4
  #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
8
5
 
9
6
  #ifdef DEBUG
@@ -9,6 +9,16 @@
9
9
  #include <string.h>
10
10
  #include "http11_parser.h"
11
11
 
12
+ static http_parser *data_get(VALUE self)
13
+ {
14
+ http_parser *http;
15
+
16
+ Data_Get_Struct(self, http_parser, http);
17
+ if (!http)
18
+ rb_raise(rb_eArgError, "NULL found for http when shouldn't be.");
19
+ return http;
20
+ }
21
+
12
22
  #ifndef RSTRING_PTR
13
23
  #define RSTRING_PTR(s) (RSTRING(s)->ptr)
14
24
  #endif
@@ -30,9 +40,8 @@ static VALUE global_request_uri;
30
40
  static VALUE global_fragment;
31
41
  static VALUE global_query_string;
32
42
  static VALUE global_http_version;
33
- static VALUE global_content_length;
34
43
  static VALUE global_request_path;
35
- static VALUE global_content_type;
44
+ static VALUE global_path_info;
36
45
  static VALUE global_server_name;
37
46
  static VALUE global_server_port;
38
47
  static VALUE global_server_protocol;
@@ -45,14 +54,25 @@ static VALUE global_localhost;
45
54
  static VALUE global_http;
46
55
 
47
56
  /** Defines common length and error messages for input length validation. */
48
- #define DEF_MAX_LENGTH(N,length) const size_t MAX_##N##_LENGTH = length; const char *MAX_##N##_LENGTH_ERR = "HTTP element " # N " is longer than the " # length " allowed length."
57
+ #define DEF_MAX_LENGTH(N, length) \
58
+ static const size_t MAX_##N##_LENGTH = length; \
59
+ static const char * const MAX_##N##_LENGTH_ERR = \
60
+ "HTTP element " # N " is longer than the " # length " allowed length."
49
61
 
50
- /** Validates the max length of given input and throws an HttpParserError exception if over. */
51
- #define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR); }
62
+ /**
63
+ * Validates the max length of given input and throws an HttpParserError
64
+ * exception if over.
65
+ */
66
+ #define VALIDATE_MAX_LENGTH(len, N) do { \
67
+ if (len > MAX_##N##_LENGTH) \
68
+ rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR); \
69
+ } while (0)
52
70
 
53
71
  /** Defines global strings in the init method. */
54
- #define DEF_GLOBAL(N, val) global_##N = rb_obj_freeze(rb_str_new2(val)); rb_global_variable(&global_##N)
55
-
72
+ #define DEF_GLOBAL(N, val) do { \
73
+ global_##N = rb_obj_freeze(rb_str_new(val, sizeof(val) - 1)); \
74
+ rb_global_variable(&global_##N); \
75
+ } while (0)
56
76
 
57
77
  /* Defines the maximum allowed lengths for various input elements.*/
58
78
  DEF_MAX_LENGTH(FIELD_NAME, 256);
@@ -153,14 +173,11 @@ static void http_field(void *data, const char *field,
153
173
  size_t flen, const char *value, size_t vlen)
154
174
  {
155
175
  VALUE req = (VALUE)data;
156
- VALUE v = Qnil;
157
176
  VALUE f = Qnil;
158
177
 
159
178
  VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
160
179
  VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE);
161
180
 
162
- v = rb_str_new(value, vlen);
163
-
164
181
  f = find_common_field_value(field, flen);
165
182
 
166
183
  if (f == Qnil) {
@@ -179,9 +196,11 @@ static void http_field(void *data, const char *field,
179
196
  memcpy(RSTRING_PTR(f) + HTTP_PREFIX_LEN, field, flen);
180
197
  assert(*(RSTRING_PTR(f) + RSTRING_LEN(f)) == '\0'); /* paranoia */
181
198
  /* fprintf(stderr, "UNKNOWN HEADER <%s>\n", RSTRING_PTR(f)); */
199
+ } else if (f == global_http_host && rb_hash_aref(req, f) != Qnil) {
200
+ return;
182
201
  }
183
202
 
184
- rb_hash_aset(req, f, v);
203
+ rb_hash_aset(req, f, rb_str_new(value, vlen));
185
204
  }
186
205
 
187
206
  static void request_method(void *data, const char *at, size_t length)
@@ -193,6 +212,16 @@ static void request_method(void *data, const char *at, size_t length)
193
212
  rb_hash_aset(req, global_request_method, val);
194
213
  }
195
214
 
215
+ static void scheme(void *data, const char *at, size_t length)
216
+ {
217
+ rb_hash_aset((VALUE)data, global_rack_url_scheme, rb_str_new(at, length));
218
+ }
219
+
220
+ static void host(void *data, const char *at, size_t length)
221
+ {
222
+ rb_hash_aset((VALUE)data, global_http_host, rb_str_new(at, length));
223
+ }
224
+
196
225
  static void request_uri(void *data, const char *at, size_t length)
197
226
  {
198
227
  VALUE req = (VALUE)data;
@@ -202,6 +231,13 @@ static void request_uri(void *data, const char *at, size_t length)
202
231
 
203
232
  val = rb_str_new(at, length);
204
233
  rb_hash_aset(req, global_request_uri, val);
234
+
235
+ /* "OPTIONS * HTTP/1.1\r\n" is a valid request */
236
+ if (length == 1 && *at == '*') {
237
+ val = rb_str_new(NULL, 0);
238
+ rb_hash_aset(req, global_request_path, val);
239
+ rb_hash_aset(req, global_path_info, val);
240
+ }
205
241
  }
206
242
 
207
243
  static void fragment(void *data, const char *at, size_t length)
@@ -224,6 +260,10 @@ static void request_path(void *data, const char *at, size_t length)
224
260
 
225
261
  val = rb_str_new(at, length);
226
262
  rb_hash_aset(req, global_request_path, val);
263
+
264
+ /* rack says PATH_INFO must start with "/" or be empty */
265
+ if (!(length == 1 && *at == '*'))
266
+ rb_hash_aset(req, global_path_info, val);
227
267
  }
228
268
 
229
269
  static void query_string(void *data, const char *at, size_t length)
@@ -252,22 +292,32 @@ static void header_done(void *data, const char *at, size_t length)
252
292
  VALUE server_port = global_port_80;
253
293
  VALUE temp;
254
294
 
295
+ /* rack requires QUERY_STRING */
296
+ if (rb_hash_aref(req, global_query_string) == Qnil)
297
+ rb_hash_aset(req, global_query_string, rb_str_new(NULL, 0));
298
+
255
299
  /* set rack.url_scheme to "https" or "http", no others are allowed by Rack */
256
- if ((temp = rb_hash_aref(req, global_http_x_forwarded_proto)) != Qnil &&
257
- RSTRING_LEN(temp) == 5 &&
258
- !memcmp("https", RSTRING_PTR(temp), 5))
300
+ if ((temp = rb_hash_aref(req, global_rack_url_scheme)) == Qnil) {
301
+ if ((temp = rb_hash_aref(req, global_http_x_forwarded_proto)) != Qnil &&
302
+ RSTRING_LEN(temp) == 5 &&
303
+ !memcmp("https", RSTRING_PTR(temp), 5))
304
+ server_port = global_port_443;
305
+ else
306
+ temp = global_http;
307
+ rb_hash_aset(req, global_rack_url_scheme, temp);
308
+ } else if (RSTRING_LEN(temp) == 5 && !memcmp("https", RSTRING_PTR(temp), 5)) {
259
309
  server_port = global_port_443;
260
- else
261
- temp = global_http;
262
- rb_hash_aset(req, global_rack_url_scheme, temp);
310
+ }
263
311
 
264
312
  /* parse and set the SERVER_NAME and SERVER_PORT variables */
265
313
  if ((temp = rb_hash_aref(req, global_http_host)) != Qnil) {
266
314
  char *colon = memchr(RSTRING_PTR(temp), ':', RSTRING_LEN(temp));
267
315
  if (colon) {
316
+ long port_start = colon - RSTRING_PTR(temp) + 1;
317
+
268
318
  server_name = rb_str_substr(temp, 0, colon - RSTRING_PTR(temp));
269
- server_port = rb_str_substr(temp, colon - RSTRING_PTR(temp)+1,
270
- RSTRING_LEN(temp));
319
+ if ((RSTRING_LEN(temp) - port_start) > 0)
320
+ server_port = rb_str_substr(temp, port_start, RSTRING_LEN(temp));
271
321
  } else {
272
322
  server_name = temp;
273
323
  }
@@ -294,14 +344,6 @@ static VALUE HttpParser_alloc(VALUE klass)
294
344
  VALUE obj;
295
345
  http_parser *hp = ALLOC_N(http_parser, 1);
296
346
  TRACE();
297
- hp->http_field = http_field;
298
- hp->request_method = request_method;
299
- hp->request_uri = request_uri;
300
- hp->fragment = fragment;
301
- hp->request_path = request_path;
302
- hp->query_string = query_string;
303
- hp->http_version = http_version;
304
- hp->header_done = header_done;
305
347
  http_parser_init(hp);
306
348
 
307
349
  obj = Data_Wrap_Struct(klass, NULL, HttpParser_free, hp);
@@ -318,9 +360,7 @@ static VALUE HttpParser_alloc(VALUE klass)
318
360
  */
319
361
  static VALUE HttpParser_init(VALUE self)
320
362
  {
321
- http_parser *http = NULL;
322
- DATA_GET(self, http_parser, http);
323
- http_parser_init(http);
363
+ http_parser_init(data_get(self));
324
364
 
325
365
  return self;
326
366
  }
@@ -335,9 +375,7 @@ static VALUE HttpParser_init(VALUE self)
335
375
  */
336
376
  static VALUE HttpParser_reset(VALUE self)
337
377
  {
338
- http_parser *http = NULL;
339
- DATA_GET(self, http_parser, http);
340
- http_parser_init(http);
378
+ http_parser_init(data_get(self));
341
379
 
342
380
  return Qnil;
343
381
  }
@@ -358,12 +396,10 @@ static VALUE HttpParser_reset(VALUE self)
358
396
 
359
397
  static VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data)
360
398
  {
361
- http_parser *http;
399
+ http_parser *http = data_get(self);
362
400
  char *dptr = RSTRING_PTR(data);
363
401
  long dlen = RSTRING_LEN(data);
364
402
 
365
- DATA_GET(self, http_parser, http);
366
-
367
403
  if (http->nread < dlen) {
368
404
  http->data = (void *)req_hash;
369
405
  http_parser_execute(http, dptr, dlen);
@@ -378,9 +414,8 @@ static VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data)
378
414
  rb_raise(eHttpParserError, "Requested start is after data buffer end.");
379
415
  }
380
416
 
381
- void Init_http11()
417
+ void Init_http11(void)
382
418
  {
383
-
384
419
  mUnicorn = rb_define_module("Unicorn");
385
420
 
386
421
  DEF_GLOBAL(rack_url_scheme, "rack.url_scheme");
@@ -390,13 +425,11 @@ void Init_http11()
390
425
  DEF_GLOBAL(query_string, "QUERY_STRING");
391
426
  DEF_GLOBAL(http_version, "HTTP_VERSION");
392
427
  DEF_GLOBAL(request_path, "REQUEST_PATH");
393
- DEF_GLOBAL(content_length, "CONTENT_LENGTH");
394
- DEF_GLOBAL(content_type, "CONTENT_TYPE");
428
+ DEF_GLOBAL(path_info, "PATH_INFO");
395
429
  DEF_GLOBAL(server_name, "SERVER_NAME");
396
430
  DEF_GLOBAL(server_port, "SERVER_PORT");
397
431
  DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
398
432
  DEF_GLOBAL(server_protocol_value, "HTTP/1.1");
399
- DEF_GLOBAL(http_host, "HTTP_HOST");
400
433
  DEF_GLOBAL(http_x_forwarded_proto, "HTTP_X_FORWARDED_PROTO");
401
434
  DEF_GLOBAL(port_80, "80");
402
435
  DEF_GLOBAL(port_443, "443");
@@ -412,4 +445,6 @@ void Init_http11()
412
445
  rb_define_method(cHttpParser, "execute", HttpParser_execute,2);
413
446
  sym_http_body = ID2SYM(rb_intern("http_body"));
414
447
  init_common_fields();
448
+ global_http_host = find_common_field_value("HOST", 4);
449
+ assert(global_http_host != Qnil);
415
450
  }
@@ -1,20 +1,29 @@
1
+
2
+ #line 1 "http11_parser.rl"
1
3
  /**
2
4
  * Copyright (c) 2005 Zed A. Shaw
3
5
  * You can redistribute it and/or modify it under the same terms as Ruby.
4
6
  */
5
-
6
7
  #ifndef http11_parser_h
7
8
  #define http11_parser_h
8
9
 
9
10
  #include <sys/types.h>
10
11
 
11
- typedef void (*element_cb)(void *data, const char *at, size_t length);
12
- typedef void (*field_cb)(void *data, const char *field, size_t flen, const char *value, size_t vlen);
12
+ static void http_field(void *data, const char *field,
13
+ size_t flen, const char *value, size_t vlen);
14
+ static void request_method(void *data, const char *at, size_t length);
15
+ static void scheme(void *data, const char *at, size_t length);
16
+ static void host(void *data, const char *at, size_t length);
17
+ static void request_uri(void *data, const char *at, size_t length);
18
+ static void fragment(void *data, const char *at, size_t length);
19
+ static void request_path(void *data, const char *at, size_t length);
20
+ static void query_string(void *data, const char *at, size_t length);
21
+ static void http_version(void *data, const char *at, size_t length);
22
+ static void header_done(void *data, const char *at, size_t length);
13
23
 
14
- typedef struct http_parser {
24
+ typedef struct http_parser {
15
25
  int cs;
16
26
  size_t body_start;
17
- int content_len;
18
27
  size_t nread;
19
28
  size_t mark;
20
29
  size_t field_start;
@@ -22,22 +31,1259 @@ typedef struct http_parser {
22
31
  size_t query_start;
23
32
 
24
33
  void *data;
25
-
26
- field_cb http_field;
27
- element_cb request_method;
28
- element_cb request_uri;
29
- element_cb fragment;
30
- element_cb request_path;
31
- element_cb query_string;
32
- element_cb http_version;
33
- element_cb header_done;
34
-
35
34
  } http_parser;
36
35
 
37
- int http_parser_init(http_parser *parser);
38
- int http_parser_finish(http_parser *parser);
39
- size_t http_parser_execute(http_parser *parser, const char *data, size_t len);
40
- int http_parser_has_error(http_parser *parser);
41
- int http_parser_is_finished(http_parser *parser);
36
+ static int http_parser_has_error(http_parser *parser);
37
+ static int http_parser_is_finished(http_parser *parser);
38
+
39
+ /*
40
+ * capitalizes all lower-case ASCII characters,
41
+ * converts dashes to underscores.
42
+ */
43
+ static void snake_upcase_char(char *c)
44
+ {
45
+ if (*c >= 'a' && *c <= 'z')
46
+ *c &= ~0x20;
47
+ else if (*c == '-')
48
+ *c = '_';
49
+ }
50
+
51
+ static void downcase_char(char *c)
52
+ {
53
+ if (*c >= 'A' && *c <= 'Z')
54
+ *c |= 0x20;
55
+ }
56
+
57
+ #define LEN(AT, FPC) (FPC - buffer - parser->AT)
58
+ #define MARK(M,FPC) (parser->M = (FPC) - buffer)
59
+ #define PTR_TO(F) (buffer + parser->F)
60
+
61
+ /** Machine **/
62
+
63
+
64
+ #line 109 "http11_parser.rl"
65
+
66
+
67
+ /** Data **/
68
+
69
+ #line 70 "http11_parser.h"
70
+ static const int http_parser_start = 1;
71
+ static const int http_parser_first_final = 63;
72
+ static const int http_parser_error = 0;
73
+
74
+ static const int http_parser_en_main = 1;
75
+
76
+
77
+ #line 113 "http11_parser.rl"
78
+
79
+ static void http_parser_init(http_parser *parser) {
80
+ int cs = 0;
81
+ memset(parser, 0, sizeof(*parser));
82
+
83
+ #line 84 "http11_parser.h"
84
+ {
85
+ cs = http_parser_start;
86
+ }
87
+
88
+ #line 118 "http11_parser.rl"
89
+ parser->cs = cs;
90
+ }
91
+
92
+ /** exec **/
93
+ static void http_parser_execute(
94
+ http_parser *parser, const char *buffer, size_t len)
95
+ {
96
+ const char *p, *pe;
97
+ int cs = parser->cs;
98
+ size_t off = parser->nread;
99
+
100
+ assert(off <= len && "offset past end of buffer");
101
+
102
+ p = buffer+off;
103
+ pe = buffer+len;
104
+
105
+ assert(*pe == '\0' && "pointer does not end on NUL");
106
+ assert(pe - p == len - off && "pointers aren't same distance");
107
+
108
+
109
+ #line 110 "http11_parser.h"
110
+ {
111
+ if ( p == pe )
112
+ goto _test_eof;
113
+ switch ( cs )
114
+ {
115
+ case 1:
116
+ switch( (*p) ) {
117
+ case 36: goto tr0;
118
+ case 95: goto tr0;
119
+ }
120
+ if ( (*p) < 48 ) {
121
+ if ( 45 <= (*p) && (*p) <= 46 )
122
+ goto tr0;
123
+ } else if ( (*p) > 57 ) {
124
+ if ( 65 <= (*p) && (*p) <= 90 )
125
+ goto tr0;
126
+ } else
127
+ goto tr0;
128
+ goto st0;
129
+ st0:
130
+ cs = 0;
131
+ goto _out;
132
+ tr0:
133
+ #line 64 "http11_parser.rl"
134
+ {MARK(mark, p); }
135
+ goto st2;
136
+ st2:
137
+ if ( ++p == pe )
138
+ goto _test_eof2;
139
+ case 2:
140
+ #line 141 "http11_parser.h"
141
+ switch( (*p) ) {
142
+ case 32: goto tr2;
143
+ case 36: goto st44;
144
+ case 95: goto st44;
145
+ }
146
+ if ( (*p) < 48 ) {
147
+ if ( 45 <= (*p) && (*p) <= 46 )
148
+ goto st44;
149
+ } else if ( (*p) > 57 ) {
150
+ if ( 65 <= (*p) && (*p) <= 90 )
151
+ goto st44;
152
+ } else
153
+ goto st44;
154
+ goto st0;
155
+ tr2:
156
+ #line 77 "http11_parser.rl"
157
+ {
158
+ request_method(parser->data, PTR_TO(mark), LEN(mark, p));
159
+ }
160
+ goto st3;
161
+ st3:
162
+ if ( ++p == pe )
163
+ goto _test_eof3;
164
+ case 3:
165
+ #line 166 "http11_parser.h"
166
+ switch( (*p) ) {
167
+ case 42: goto tr4;
168
+ case 47: goto tr5;
169
+ case 72: goto tr6;
170
+ case 104: goto tr6;
171
+ }
172
+ goto st0;
173
+ tr4:
174
+ #line 64 "http11_parser.rl"
175
+ {MARK(mark, p); }
176
+ goto st4;
177
+ st4:
178
+ if ( ++p == pe )
179
+ goto _test_eof4;
180
+ case 4:
181
+ #line 182 "http11_parser.h"
182
+ switch( (*p) ) {
183
+ case 32: goto tr7;
184
+ case 35: goto tr8;
185
+ }
186
+ goto st0;
187
+ tr7:
188
+ #line 82 "http11_parser.rl"
189
+ {
190
+ request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
191
+ }
192
+ goto st5;
193
+ tr30:
194
+ #line 64 "http11_parser.rl"
195
+ {MARK(mark, p); }
196
+ #line 85 "http11_parser.rl"
197
+ {
198
+ fragment(parser->data, PTR_TO(mark), LEN(mark, p));
199
+ }
200
+ goto st5;
201
+ tr33:
202
+ #line 85 "http11_parser.rl"
203
+ {
204
+ fragment(parser->data, PTR_TO(mark), LEN(mark, p));
205
+ }
206
+ goto st5;
207
+ tr37:
208
+ #line 98 "http11_parser.rl"
209
+ {
210
+ request_path(parser->data, PTR_TO(mark), LEN(mark,p));
211
+ }
212
+ #line 82 "http11_parser.rl"
213
+ {
214
+ request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
215
+ }
216
+ goto st5;
217
+ tr48:
218
+ #line 89 "http11_parser.rl"
219
+ {MARK(query_start, p); }
220
+ #line 90 "http11_parser.rl"
221
+ {
222
+ query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
223
+ }
224
+ #line 82 "http11_parser.rl"
225
+ {
226
+ request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
227
+ }
228
+ goto st5;
229
+ tr52:
230
+ #line 90 "http11_parser.rl"
231
+ {
232
+ query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
233
+ }
234
+ #line 82 "http11_parser.rl"
235
+ {
236
+ request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
237
+ }
238
+ goto st5;
239
+ st5:
240
+ if ( ++p == pe )
241
+ goto _test_eof5;
242
+ case 5:
243
+ #line 244 "http11_parser.h"
244
+ if ( (*p) == 72 )
245
+ goto tr9;
246
+ goto st0;
247
+ tr9:
248
+ #line 64 "http11_parser.rl"
249
+ {MARK(mark, p); }
250
+ goto st6;
251
+ st6:
252
+ if ( ++p == pe )
253
+ goto _test_eof6;
254
+ case 6:
255
+ #line 256 "http11_parser.h"
256
+ if ( (*p) == 84 )
257
+ goto st7;
258
+ goto st0;
259
+ st7:
260
+ if ( ++p == pe )
261
+ goto _test_eof7;
262
+ case 7:
263
+ if ( (*p) == 84 )
264
+ goto st8;
265
+ goto st0;
266
+ st8:
267
+ if ( ++p == pe )
268
+ goto _test_eof8;
269
+ case 8:
270
+ if ( (*p) == 80 )
271
+ goto st9;
272
+ goto st0;
273
+ st9:
274
+ if ( ++p == pe )
275
+ goto _test_eof9;
276
+ case 9:
277
+ if ( (*p) == 47 )
278
+ goto st10;
279
+ goto st0;
280
+ st10:
281
+ if ( ++p == pe )
282
+ goto _test_eof10;
283
+ case 10:
284
+ if ( 48 <= (*p) && (*p) <= 57 )
285
+ goto st11;
286
+ goto st0;
287
+ st11:
288
+ if ( ++p == pe )
289
+ goto _test_eof11;
290
+ case 11:
291
+ if ( (*p) == 46 )
292
+ goto st12;
293
+ if ( 48 <= (*p) && (*p) <= 57 )
294
+ goto st11;
295
+ goto st0;
296
+ st12:
297
+ if ( ++p == pe )
298
+ goto _test_eof12;
299
+ case 12:
300
+ if ( 48 <= (*p) && (*p) <= 57 )
301
+ goto st13;
302
+ goto st0;
303
+ st13:
304
+ if ( ++p == pe )
305
+ goto _test_eof13;
306
+ case 13:
307
+ if ( (*p) == 13 )
308
+ goto tr17;
309
+ if ( 48 <= (*p) && (*p) <= 57 )
310
+ goto st13;
311
+ goto st0;
312
+ tr17:
313
+ #line 94 "http11_parser.rl"
314
+ {
315
+ http_version(parser->data, PTR_TO(mark), LEN(mark, p));
316
+ }
317
+ goto st14;
318
+ tr25:
319
+ #line 73 "http11_parser.rl"
320
+ { MARK(mark, p); }
321
+ #line 74 "http11_parser.rl"
322
+ {
323
+ http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
324
+ }
325
+ goto st14;
326
+ tr28:
327
+ #line 74 "http11_parser.rl"
328
+ {
329
+ http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
330
+ }
331
+ goto st14;
332
+ st14:
333
+ if ( ++p == pe )
334
+ goto _test_eof14;
335
+ case 14:
336
+ #line 337 "http11_parser.h"
337
+ if ( (*p) == 10 )
338
+ goto st15;
339
+ goto st0;
340
+ st15:
341
+ if ( ++p == pe )
342
+ goto _test_eof15;
343
+ case 15:
344
+ switch( (*p) ) {
345
+ case 13: goto st16;
346
+ case 33: goto tr20;
347
+ case 124: goto tr20;
348
+ case 126: goto tr20;
349
+ }
350
+ if ( (*p) < 45 ) {
351
+ if ( (*p) > 39 ) {
352
+ if ( 42 <= (*p) && (*p) <= 43 )
353
+ goto tr20;
354
+ } else if ( (*p) >= 35 )
355
+ goto tr20;
356
+ } else if ( (*p) > 46 ) {
357
+ if ( (*p) < 65 ) {
358
+ if ( 48 <= (*p) && (*p) <= 57 )
359
+ goto tr20;
360
+ } else if ( (*p) > 90 ) {
361
+ if ( 94 <= (*p) && (*p) <= 122 )
362
+ goto tr20;
363
+ } else
364
+ goto tr20;
365
+ } else
366
+ goto tr20;
367
+ goto st0;
368
+ st16:
369
+ if ( ++p == pe )
370
+ goto _test_eof16;
371
+ case 16:
372
+ if ( (*p) == 10 )
373
+ goto tr21;
374
+ goto st0;
375
+ tr21:
376
+ #line 102 "http11_parser.rl"
377
+ {
378
+ parser->body_start = p - buffer + 1;
379
+ header_done(parser->data, p + 1, pe - p - 1);
380
+ {p++; cs = 63; goto _out;}
381
+ }
382
+ goto st63;
383
+ st63:
384
+ if ( ++p == pe )
385
+ goto _test_eof63;
386
+ case 63:
387
+ #line 388 "http11_parser.h"
388
+ goto st0;
389
+ tr20:
390
+ #line 66 "http11_parser.rl"
391
+ { MARK(field_start, p); }
392
+ #line 67 "http11_parser.rl"
393
+ { snake_upcase_char((char *)p); }
394
+ goto st17;
395
+ tr22:
396
+ #line 67 "http11_parser.rl"
397
+ { snake_upcase_char((char *)p); }
398
+ goto st17;
399
+ st17:
400
+ if ( ++p == pe )
401
+ goto _test_eof17;
402
+ case 17:
403
+ #line 404 "http11_parser.h"
404
+ switch( (*p) ) {
405
+ case 33: goto tr22;
406
+ case 58: goto tr23;
407
+ case 124: goto tr22;
408
+ case 126: goto tr22;
409
+ }
410
+ if ( (*p) < 45 ) {
411
+ if ( (*p) > 39 ) {
412
+ if ( 42 <= (*p) && (*p) <= 43 )
413
+ goto tr22;
414
+ } else if ( (*p) >= 35 )
415
+ goto tr22;
416
+ } else if ( (*p) > 46 ) {
417
+ if ( (*p) < 65 ) {
418
+ if ( 48 <= (*p) && (*p) <= 57 )
419
+ goto tr22;
420
+ } else if ( (*p) > 90 ) {
421
+ if ( 94 <= (*p) && (*p) <= 122 )
422
+ goto tr22;
423
+ } else
424
+ goto tr22;
425
+ } else
426
+ goto tr22;
427
+ goto st0;
428
+ tr23:
429
+ #line 69 "http11_parser.rl"
430
+ {
431
+ parser->field_len = LEN(field_start, p);
432
+ }
433
+ goto st18;
434
+ tr26:
435
+ #line 73 "http11_parser.rl"
436
+ { MARK(mark, p); }
437
+ goto st18;
438
+ st18:
439
+ if ( ++p == pe )
440
+ goto _test_eof18;
441
+ case 18:
442
+ #line 443 "http11_parser.h"
443
+ switch( (*p) ) {
444
+ case 13: goto tr25;
445
+ case 32: goto tr26;
446
+ }
447
+ goto tr24;
448
+ tr24:
449
+ #line 73 "http11_parser.rl"
450
+ { MARK(mark, p); }
451
+ goto st19;
452
+ st19:
453
+ if ( ++p == pe )
454
+ goto _test_eof19;
455
+ case 19:
456
+ #line 457 "http11_parser.h"
457
+ if ( (*p) == 13 )
458
+ goto tr28;
459
+ goto st19;
460
+ tr8:
461
+ #line 82 "http11_parser.rl"
462
+ {
463
+ request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
464
+ }
465
+ goto st20;
466
+ tr38:
467
+ #line 98 "http11_parser.rl"
468
+ {
469
+ request_path(parser->data, PTR_TO(mark), LEN(mark,p));
470
+ }
471
+ #line 82 "http11_parser.rl"
472
+ {
473
+ request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
474
+ }
475
+ goto st20;
476
+ tr49:
477
+ #line 89 "http11_parser.rl"
478
+ {MARK(query_start, p); }
479
+ #line 90 "http11_parser.rl"
480
+ {
481
+ query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
482
+ }
483
+ #line 82 "http11_parser.rl"
484
+ {
485
+ request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
486
+ }
487
+ goto st20;
488
+ tr53:
489
+ #line 90 "http11_parser.rl"
490
+ {
491
+ query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
492
+ }
493
+ #line 82 "http11_parser.rl"
494
+ {
495
+ request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
496
+ }
497
+ goto st20;
498
+ st20:
499
+ if ( ++p == pe )
500
+ goto _test_eof20;
501
+ case 20:
502
+ #line 503 "http11_parser.h"
503
+ switch( (*p) ) {
504
+ case 32: goto tr30;
505
+ case 35: goto st0;
506
+ case 37: goto tr31;
507
+ case 127: goto st0;
508
+ }
509
+ if ( 0 <= (*p) && (*p) <= 31 )
510
+ goto st0;
511
+ goto tr29;
512
+ tr29:
513
+ #line 64 "http11_parser.rl"
514
+ {MARK(mark, p); }
515
+ goto st21;
516
+ st21:
517
+ if ( ++p == pe )
518
+ goto _test_eof21;
519
+ case 21:
520
+ #line 521 "http11_parser.h"
521
+ switch( (*p) ) {
522
+ case 32: goto tr33;
523
+ case 35: goto st0;
524
+ case 37: goto st22;
525
+ case 127: goto st0;
526
+ }
527
+ if ( 0 <= (*p) && (*p) <= 31 )
528
+ goto st0;
529
+ goto st21;
530
+ tr31:
531
+ #line 64 "http11_parser.rl"
532
+ {MARK(mark, p); }
533
+ goto st22;
534
+ st22:
535
+ if ( ++p == pe )
536
+ goto _test_eof22;
537
+ case 22:
538
+ #line 539 "http11_parser.h"
539
+ if ( (*p) < 65 ) {
540
+ if ( 48 <= (*p) && (*p) <= 57 )
541
+ goto st23;
542
+ } else if ( (*p) > 70 ) {
543
+ if ( 97 <= (*p) && (*p) <= 102 )
544
+ goto st23;
545
+ } else
546
+ goto st23;
547
+ goto st0;
548
+ st23:
549
+ if ( ++p == pe )
550
+ goto _test_eof23;
551
+ case 23:
552
+ if ( (*p) < 65 ) {
553
+ if ( 48 <= (*p) && (*p) <= 57 )
554
+ goto st21;
555
+ } else if ( (*p) > 70 ) {
556
+ if ( 97 <= (*p) && (*p) <= 102 )
557
+ goto st21;
558
+ } else
559
+ goto st21;
560
+ goto st0;
561
+ tr5:
562
+ #line 64 "http11_parser.rl"
563
+ {MARK(mark, p); }
564
+ goto st24;
565
+ tr65:
566
+ #line 81 "http11_parser.rl"
567
+ { host(parser->data, PTR_TO(mark), LEN(mark, p)); }
568
+ #line 64 "http11_parser.rl"
569
+ {MARK(mark, p); }
570
+ goto st24;
571
+ st24:
572
+ if ( ++p == pe )
573
+ goto _test_eof24;
574
+ case 24:
575
+ #line 576 "http11_parser.h"
576
+ switch( (*p) ) {
577
+ case 32: goto tr37;
578
+ case 35: goto tr38;
579
+ case 37: goto st25;
580
+ case 59: goto tr40;
581
+ case 63: goto tr41;
582
+ case 127: goto st0;
583
+ }
584
+ if ( 0 <= (*p) && (*p) <= 31 )
585
+ goto st0;
586
+ goto st24;
587
+ st25:
588
+ if ( ++p == pe )
589
+ goto _test_eof25;
590
+ case 25:
591
+ if ( (*p) < 65 ) {
592
+ if ( 48 <= (*p) && (*p) <= 57 )
593
+ goto st26;
594
+ } else if ( (*p) > 70 ) {
595
+ if ( 97 <= (*p) && (*p) <= 102 )
596
+ goto st26;
597
+ } else
598
+ goto st26;
599
+ goto st0;
600
+ st26:
601
+ if ( ++p == pe )
602
+ goto _test_eof26;
603
+ case 26:
604
+ if ( (*p) < 65 ) {
605
+ if ( 48 <= (*p) && (*p) <= 57 )
606
+ goto st24;
607
+ } else if ( (*p) > 70 ) {
608
+ if ( 97 <= (*p) && (*p) <= 102 )
609
+ goto st24;
610
+ } else
611
+ goto st24;
612
+ goto st0;
613
+ tr40:
614
+ #line 98 "http11_parser.rl"
615
+ {
616
+ request_path(parser->data, PTR_TO(mark), LEN(mark,p));
617
+ }
618
+ goto st27;
619
+ st27:
620
+ if ( ++p == pe )
621
+ goto _test_eof27;
622
+ case 27:
623
+ #line 624 "http11_parser.h"
624
+ switch( (*p) ) {
625
+ case 32: goto tr7;
626
+ case 35: goto tr8;
627
+ case 37: goto st28;
628
+ case 63: goto st30;
629
+ case 127: goto st0;
630
+ }
631
+ if ( 0 <= (*p) && (*p) <= 31 )
632
+ goto st0;
633
+ goto st27;
634
+ st28:
635
+ if ( ++p == pe )
636
+ goto _test_eof28;
637
+ case 28:
638
+ if ( (*p) < 65 ) {
639
+ if ( 48 <= (*p) && (*p) <= 57 )
640
+ goto st29;
641
+ } else if ( (*p) > 70 ) {
642
+ if ( 97 <= (*p) && (*p) <= 102 )
643
+ goto st29;
644
+ } else
645
+ goto st29;
646
+ goto st0;
647
+ st29:
648
+ if ( ++p == pe )
649
+ goto _test_eof29;
650
+ case 29:
651
+ if ( (*p) < 65 ) {
652
+ if ( 48 <= (*p) && (*p) <= 57 )
653
+ goto st27;
654
+ } else if ( (*p) > 70 ) {
655
+ if ( 97 <= (*p) && (*p) <= 102 )
656
+ goto st27;
657
+ } else
658
+ goto st27;
659
+ goto st0;
660
+ tr41:
661
+ #line 98 "http11_parser.rl"
662
+ {
663
+ request_path(parser->data, PTR_TO(mark), LEN(mark,p));
664
+ }
665
+ goto st30;
666
+ st30:
667
+ if ( ++p == pe )
668
+ goto _test_eof30;
669
+ case 30:
670
+ #line 671 "http11_parser.h"
671
+ switch( (*p) ) {
672
+ case 32: goto tr48;
673
+ case 35: goto tr49;
674
+ case 37: goto tr50;
675
+ case 127: goto st0;
676
+ }
677
+ if ( 0 <= (*p) && (*p) <= 31 )
678
+ goto st0;
679
+ goto tr47;
680
+ tr47:
681
+ #line 89 "http11_parser.rl"
682
+ {MARK(query_start, p); }
683
+ goto st31;
684
+ st31:
685
+ if ( ++p == pe )
686
+ goto _test_eof31;
687
+ case 31:
688
+ #line 689 "http11_parser.h"
689
+ switch( (*p) ) {
690
+ case 32: goto tr52;
691
+ case 35: goto tr53;
692
+ case 37: goto st32;
693
+ case 127: goto st0;
694
+ }
695
+ if ( 0 <= (*p) && (*p) <= 31 )
696
+ goto st0;
697
+ goto st31;
698
+ tr50:
699
+ #line 89 "http11_parser.rl"
700
+ {MARK(query_start, p); }
701
+ goto st32;
702
+ st32:
703
+ if ( ++p == pe )
704
+ goto _test_eof32;
705
+ case 32:
706
+ #line 707 "http11_parser.h"
707
+ if ( (*p) < 65 ) {
708
+ if ( 48 <= (*p) && (*p) <= 57 )
709
+ goto st33;
710
+ } else if ( (*p) > 70 ) {
711
+ if ( 97 <= (*p) && (*p) <= 102 )
712
+ goto st33;
713
+ } else
714
+ goto st33;
715
+ goto st0;
716
+ st33:
717
+ if ( ++p == pe )
718
+ goto _test_eof33;
719
+ case 33:
720
+ if ( (*p) < 65 ) {
721
+ if ( 48 <= (*p) && (*p) <= 57 )
722
+ goto st31;
723
+ } else if ( (*p) > 70 ) {
724
+ if ( 97 <= (*p) && (*p) <= 102 )
725
+ goto st31;
726
+ } else
727
+ goto st31;
728
+ goto st0;
729
+ tr6:
730
+ #line 64 "http11_parser.rl"
731
+ {MARK(mark, p); }
732
+ #line 68 "http11_parser.rl"
733
+ { downcase_char((char *)p); }
734
+ goto st34;
735
+ st34:
736
+ if ( ++p == pe )
737
+ goto _test_eof34;
738
+ case 34:
739
+ #line 740 "http11_parser.h"
740
+ switch( (*p) ) {
741
+ case 84: goto tr56;
742
+ case 116: goto tr56;
743
+ }
744
+ goto st0;
745
+ tr56:
746
+ #line 68 "http11_parser.rl"
747
+ { downcase_char((char *)p); }
748
+ goto st35;
749
+ st35:
750
+ if ( ++p == pe )
751
+ goto _test_eof35;
752
+ case 35:
753
+ #line 754 "http11_parser.h"
754
+ switch( (*p) ) {
755
+ case 84: goto tr57;
756
+ case 116: goto tr57;
757
+ }
758
+ goto st0;
759
+ tr57:
760
+ #line 68 "http11_parser.rl"
761
+ { downcase_char((char *)p); }
762
+ goto st36;
763
+ st36:
764
+ if ( ++p == pe )
765
+ goto _test_eof36;
766
+ case 36:
767
+ #line 768 "http11_parser.h"
768
+ switch( (*p) ) {
769
+ case 80: goto tr58;
770
+ case 112: goto tr58;
771
+ }
772
+ goto st0;
773
+ tr58:
774
+ #line 68 "http11_parser.rl"
775
+ { downcase_char((char *)p); }
776
+ goto st37;
777
+ st37:
778
+ if ( ++p == pe )
779
+ goto _test_eof37;
780
+ case 37:
781
+ #line 782 "http11_parser.h"
782
+ switch( (*p) ) {
783
+ case 58: goto tr59;
784
+ case 83: goto tr60;
785
+ case 115: goto tr60;
786
+ }
787
+ goto st0;
788
+ tr59:
789
+ #line 80 "http11_parser.rl"
790
+ { scheme(parser->data, PTR_TO(mark), LEN(mark, p)); }
791
+ goto st38;
792
+ st38:
793
+ if ( ++p == pe )
794
+ goto _test_eof38;
795
+ case 38:
796
+ #line 797 "http11_parser.h"
797
+ if ( (*p) == 47 )
798
+ goto st39;
799
+ goto st0;
800
+ st39:
801
+ if ( ++p == pe )
802
+ goto _test_eof39;
803
+ case 39:
804
+ if ( (*p) == 47 )
805
+ goto st40;
806
+ goto st0;
807
+ st40:
808
+ if ( ++p == pe )
809
+ goto _test_eof40;
810
+ case 40:
811
+ if ( (*p) == 95 )
812
+ goto tr63;
813
+ if ( (*p) < 48 ) {
814
+ if ( 45 <= (*p) && (*p) <= 46 )
815
+ goto tr63;
816
+ } else if ( (*p) > 57 ) {
817
+ if ( (*p) > 90 ) {
818
+ if ( 97 <= (*p) && (*p) <= 122 )
819
+ goto tr63;
820
+ } else if ( (*p) >= 65 )
821
+ goto tr63;
822
+ } else
823
+ goto tr63;
824
+ goto st0;
825
+ tr63:
826
+ #line 64 "http11_parser.rl"
827
+ {MARK(mark, p); }
828
+ goto st41;
829
+ st41:
830
+ if ( ++p == pe )
831
+ goto _test_eof41;
832
+ case 41:
833
+ #line 834 "http11_parser.h"
834
+ switch( (*p) ) {
835
+ case 47: goto tr65;
836
+ case 58: goto st42;
837
+ case 95: goto st41;
838
+ }
839
+ if ( (*p) < 65 ) {
840
+ if ( 45 <= (*p) && (*p) <= 57 )
841
+ goto st41;
842
+ } else if ( (*p) > 90 ) {
843
+ if ( 97 <= (*p) && (*p) <= 122 )
844
+ goto st41;
845
+ } else
846
+ goto st41;
847
+ goto st0;
848
+ st42:
849
+ if ( ++p == pe )
850
+ goto _test_eof42;
851
+ case 42:
852
+ if ( (*p) == 47 )
853
+ goto tr65;
854
+ if ( 48 <= (*p) && (*p) <= 57 )
855
+ goto st42;
856
+ goto st0;
857
+ tr60:
858
+ #line 68 "http11_parser.rl"
859
+ { downcase_char((char *)p); }
860
+ goto st43;
861
+ st43:
862
+ if ( ++p == pe )
863
+ goto _test_eof43;
864
+ case 43:
865
+ #line 866 "http11_parser.h"
866
+ if ( (*p) == 58 )
867
+ goto tr59;
868
+ goto st0;
869
+ st44:
870
+ if ( ++p == pe )
871
+ goto _test_eof44;
872
+ case 44:
873
+ switch( (*p) ) {
874
+ case 32: goto tr2;
875
+ case 36: goto st45;
876
+ case 95: goto st45;
877
+ }
878
+ if ( (*p) < 48 ) {
879
+ if ( 45 <= (*p) && (*p) <= 46 )
880
+ goto st45;
881
+ } else if ( (*p) > 57 ) {
882
+ if ( 65 <= (*p) && (*p) <= 90 )
883
+ goto st45;
884
+ } else
885
+ goto st45;
886
+ goto st0;
887
+ st45:
888
+ if ( ++p == pe )
889
+ goto _test_eof45;
890
+ case 45:
891
+ switch( (*p) ) {
892
+ case 32: goto tr2;
893
+ case 36: goto st46;
894
+ case 95: goto st46;
895
+ }
896
+ if ( (*p) < 48 ) {
897
+ if ( 45 <= (*p) && (*p) <= 46 )
898
+ goto st46;
899
+ } else if ( (*p) > 57 ) {
900
+ if ( 65 <= (*p) && (*p) <= 90 )
901
+ goto st46;
902
+ } else
903
+ goto st46;
904
+ goto st0;
905
+ st46:
906
+ if ( ++p == pe )
907
+ goto _test_eof46;
908
+ case 46:
909
+ switch( (*p) ) {
910
+ case 32: goto tr2;
911
+ case 36: goto st47;
912
+ case 95: goto st47;
913
+ }
914
+ if ( (*p) < 48 ) {
915
+ if ( 45 <= (*p) && (*p) <= 46 )
916
+ goto st47;
917
+ } else if ( (*p) > 57 ) {
918
+ if ( 65 <= (*p) && (*p) <= 90 )
919
+ goto st47;
920
+ } else
921
+ goto st47;
922
+ goto st0;
923
+ st47:
924
+ if ( ++p == pe )
925
+ goto _test_eof47;
926
+ case 47:
927
+ switch( (*p) ) {
928
+ case 32: goto tr2;
929
+ case 36: goto st48;
930
+ case 95: goto st48;
931
+ }
932
+ if ( (*p) < 48 ) {
933
+ if ( 45 <= (*p) && (*p) <= 46 )
934
+ goto st48;
935
+ } else if ( (*p) > 57 ) {
936
+ if ( 65 <= (*p) && (*p) <= 90 )
937
+ goto st48;
938
+ } else
939
+ goto st48;
940
+ goto st0;
941
+ st48:
942
+ if ( ++p == pe )
943
+ goto _test_eof48;
944
+ case 48:
945
+ switch( (*p) ) {
946
+ case 32: goto tr2;
947
+ case 36: goto st49;
948
+ case 95: goto st49;
949
+ }
950
+ if ( (*p) < 48 ) {
951
+ if ( 45 <= (*p) && (*p) <= 46 )
952
+ goto st49;
953
+ } else if ( (*p) > 57 ) {
954
+ if ( 65 <= (*p) && (*p) <= 90 )
955
+ goto st49;
956
+ } else
957
+ goto st49;
958
+ goto st0;
959
+ st49:
960
+ if ( ++p == pe )
961
+ goto _test_eof49;
962
+ case 49:
963
+ switch( (*p) ) {
964
+ case 32: goto tr2;
965
+ case 36: goto st50;
966
+ case 95: goto st50;
967
+ }
968
+ if ( (*p) < 48 ) {
969
+ if ( 45 <= (*p) && (*p) <= 46 )
970
+ goto st50;
971
+ } else if ( (*p) > 57 ) {
972
+ if ( 65 <= (*p) && (*p) <= 90 )
973
+ goto st50;
974
+ } else
975
+ goto st50;
976
+ goto st0;
977
+ st50:
978
+ if ( ++p == pe )
979
+ goto _test_eof50;
980
+ case 50:
981
+ switch( (*p) ) {
982
+ case 32: goto tr2;
983
+ case 36: goto st51;
984
+ case 95: goto st51;
985
+ }
986
+ if ( (*p) < 48 ) {
987
+ if ( 45 <= (*p) && (*p) <= 46 )
988
+ goto st51;
989
+ } else if ( (*p) > 57 ) {
990
+ if ( 65 <= (*p) && (*p) <= 90 )
991
+ goto st51;
992
+ } else
993
+ goto st51;
994
+ goto st0;
995
+ st51:
996
+ if ( ++p == pe )
997
+ goto _test_eof51;
998
+ case 51:
999
+ switch( (*p) ) {
1000
+ case 32: goto tr2;
1001
+ case 36: goto st52;
1002
+ case 95: goto st52;
1003
+ }
1004
+ if ( (*p) < 48 ) {
1005
+ if ( 45 <= (*p) && (*p) <= 46 )
1006
+ goto st52;
1007
+ } else if ( (*p) > 57 ) {
1008
+ if ( 65 <= (*p) && (*p) <= 90 )
1009
+ goto st52;
1010
+ } else
1011
+ goto st52;
1012
+ goto st0;
1013
+ st52:
1014
+ if ( ++p == pe )
1015
+ goto _test_eof52;
1016
+ case 52:
1017
+ switch( (*p) ) {
1018
+ case 32: goto tr2;
1019
+ case 36: goto st53;
1020
+ case 95: goto st53;
1021
+ }
1022
+ if ( (*p) < 48 ) {
1023
+ if ( 45 <= (*p) && (*p) <= 46 )
1024
+ goto st53;
1025
+ } else if ( (*p) > 57 ) {
1026
+ if ( 65 <= (*p) && (*p) <= 90 )
1027
+ goto st53;
1028
+ } else
1029
+ goto st53;
1030
+ goto st0;
1031
+ st53:
1032
+ if ( ++p == pe )
1033
+ goto _test_eof53;
1034
+ case 53:
1035
+ switch( (*p) ) {
1036
+ case 32: goto tr2;
1037
+ case 36: goto st54;
1038
+ case 95: goto st54;
1039
+ }
1040
+ if ( (*p) < 48 ) {
1041
+ if ( 45 <= (*p) && (*p) <= 46 )
1042
+ goto st54;
1043
+ } else if ( (*p) > 57 ) {
1044
+ if ( 65 <= (*p) && (*p) <= 90 )
1045
+ goto st54;
1046
+ } else
1047
+ goto st54;
1048
+ goto st0;
1049
+ st54:
1050
+ if ( ++p == pe )
1051
+ goto _test_eof54;
1052
+ case 54:
1053
+ switch( (*p) ) {
1054
+ case 32: goto tr2;
1055
+ case 36: goto st55;
1056
+ case 95: goto st55;
1057
+ }
1058
+ if ( (*p) < 48 ) {
1059
+ if ( 45 <= (*p) && (*p) <= 46 )
1060
+ goto st55;
1061
+ } else if ( (*p) > 57 ) {
1062
+ if ( 65 <= (*p) && (*p) <= 90 )
1063
+ goto st55;
1064
+ } else
1065
+ goto st55;
1066
+ goto st0;
1067
+ st55:
1068
+ if ( ++p == pe )
1069
+ goto _test_eof55;
1070
+ case 55:
1071
+ switch( (*p) ) {
1072
+ case 32: goto tr2;
1073
+ case 36: goto st56;
1074
+ case 95: goto st56;
1075
+ }
1076
+ if ( (*p) < 48 ) {
1077
+ if ( 45 <= (*p) && (*p) <= 46 )
1078
+ goto st56;
1079
+ } else if ( (*p) > 57 ) {
1080
+ if ( 65 <= (*p) && (*p) <= 90 )
1081
+ goto st56;
1082
+ } else
1083
+ goto st56;
1084
+ goto st0;
1085
+ st56:
1086
+ if ( ++p == pe )
1087
+ goto _test_eof56;
1088
+ case 56:
1089
+ switch( (*p) ) {
1090
+ case 32: goto tr2;
1091
+ case 36: goto st57;
1092
+ case 95: goto st57;
1093
+ }
1094
+ if ( (*p) < 48 ) {
1095
+ if ( 45 <= (*p) && (*p) <= 46 )
1096
+ goto st57;
1097
+ } else if ( (*p) > 57 ) {
1098
+ if ( 65 <= (*p) && (*p) <= 90 )
1099
+ goto st57;
1100
+ } else
1101
+ goto st57;
1102
+ goto st0;
1103
+ st57:
1104
+ if ( ++p == pe )
1105
+ goto _test_eof57;
1106
+ case 57:
1107
+ switch( (*p) ) {
1108
+ case 32: goto tr2;
1109
+ case 36: goto st58;
1110
+ case 95: goto st58;
1111
+ }
1112
+ if ( (*p) < 48 ) {
1113
+ if ( 45 <= (*p) && (*p) <= 46 )
1114
+ goto st58;
1115
+ } else if ( (*p) > 57 ) {
1116
+ if ( 65 <= (*p) && (*p) <= 90 )
1117
+ goto st58;
1118
+ } else
1119
+ goto st58;
1120
+ goto st0;
1121
+ st58:
1122
+ if ( ++p == pe )
1123
+ goto _test_eof58;
1124
+ case 58:
1125
+ switch( (*p) ) {
1126
+ case 32: goto tr2;
1127
+ case 36: goto st59;
1128
+ case 95: goto st59;
1129
+ }
1130
+ if ( (*p) < 48 ) {
1131
+ if ( 45 <= (*p) && (*p) <= 46 )
1132
+ goto st59;
1133
+ } else if ( (*p) > 57 ) {
1134
+ if ( 65 <= (*p) && (*p) <= 90 )
1135
+ goto st59;
1136
+ } else
1137
+ goto st59;
1138
+ goto st0;
1139
+ st59:
1140
+ if ( ++p == pe )
1141
+ goto _test_eof59;
1142
+ case 59:
1143
+ switch( (*p) ) {
1144
+ case 32: goto tr2;
1145
+ case 36: goto st60;
1146
+ case 95: goto st60;
1147
+ }
1148
+ if ( (*p) < 48 ) {
1149
+ if ( 45 <= (*p) && (*p) <= 46 )
1150
+ goto st60;
1151
+ } else if ( (*p) > 57 ) {
1152
+ if ( 65 <= (*p) && (*p) <= 90 )
1153
+ goto st60;
1154
+ } else
1155
+ goto st60;
1156
+ goto st0;
1157
+ st60:
1158
+ if ( ++p == pe )
1159
+ goto _test_eof60;
1160
+ case 60:
1161
+ switch( (*p) ) {
1162
+ case 32: goto tr2;
1163
+ case 36: goto st61;
1164
+ case 95: goto st61;
1165
+ }
1166
+ if ( (*p) < 48 ) {
1167
+ if ( 45 <= (*p) && (*p) <= 46 )
1168
+ goto st61;
1169
+ } else if ( (*p) > 57 ) {
1170
+ if ( 65 <= (*p) && (*p) <= 90 )
1171
+ goto st61;
1172
+ } else
1173
+ goto st61;
1174
+ goto st0;
1175
+ st61:
1176
+ if ( ++p == pe )
1177
+ goto _test_eof61;
1178
+ case 61:
1179
+ switch( (*p) ) {
1180
+ case 32: goto tr2;
1181
+ case 36: goto st62;
1182
+ case 95: goto st62;
1183
+ }
1184
+ if ( (*p) < 48 ) {
1185
+ if ( 45 <= (*p) && (*p) <= 46 )
1186
+ goto st62;
1187
+ } else if ( (*p) > 57 ) {
1188
+ if ( 65 <= (*p) && (*p) <= 90 )
1189
+ goto st62;
1190
+ } else
1191
+ goto st62;
1192
+ goto st0;
1193
+ st62:
1194
+ if ( ++p == pe )
1195
+ goto _test_eof62;
1196
+ case 62:
1197
+ if ( (*p) == 32 )
1198
+ goto tr2;
1199
+ goto st0;
1200
+ }
1201
+ _test_eof2: cs = 2; goto _test_eof;
1202
+ _test_eof3: cs = 3; goto _test_eof;
1203
+ _test_eof4: cs = 4; goto _test_eof;
1204
+ _test_eof5: cs = 5; goto _test_eof;
1205
+ _test_eof6: cs = 6; goto _test_eof;
1206
+ _test_eof7: cs = 7; goto _test_eof;
1207
+ _test_eof8: cs = 8; goto _test_eof;
1208
+ _test_eof9: cs = 9; goto _test_eof;
1209
+ _test_eof10: cs = 10; goto _test_eof;
1210
+ _test_eof11: cs = 11; goto _test_eof;
1211
+ _test_eof12: cs = 12; goto _test_eof;
1212
+ _test_eof13: cs = 13; goto _test_eof;
1213
+ _test_eof14: cs = 14; goto _test_eof;
1214
+ _test_eof15: cs = 15; goto _test_eof;
1215
+ _test_eof16: cs = 16; goto _test_eof;
1216
+ _test_eof63: cs = 63; goto _test_eof;
1217
+ _test_eof17: cs = 17; goto _test_eof;
1218
+ _test_eof18: cs = 18; goto _test_eof;
1219
+ _test_eof19: cs = 19; goto _test_eof;
1220
+ _test_eof20: cs = 20; goto _test_eof;
1221
+ _test_eof21: cs = 21; goto _test_eof;
1222
+ _test_eof22: cs = 22; goto _test_eof;
1223
+ _test_eof23: cs = 23; goto _test_eof;
1224
+ _test_eof24: cs = 24; goto _test_eof;
1225
+ _test_eof25: cs = 25; goto _test_eof;
1226
+ _test_eof26: cs = 26; goto _test_eof;
1227
+ _test_eof27: cs = 27; goto _test_eof;
1228
+ _test_eof28: cs = 28; goto _test_eof;
1229
+ _test_eof29: cs = 29; goto _test_eof;
1230
+ _test_eof30: cs = 30; goto _test_eof;
1231
+ _test_eof31: cs = 31; goto _test_eof;
1232
+ _test_eof32: cs = 32; goto _test_eof;
1233
+ _test_eof33: cs = 33; goto _test_eof;
1234
+ _test_eof34: cs = 34; goto _test_eof;
1235
+ _test_eof35: cs = 35; goto _test_eof;
1236
+ _test_eof36: cs = 36; goto _test_eof;
1237
+ _test_eof37: cs = 37; goto _test_eof;
1238
+ _test_eof38: cs = 38; goto _test_eof;
1239
+ _test_eof39: cs = 39; goto _test_eof;
1240
+ _test_eof40: cs = 40; goto _test_eof;
1241
+ _test_eof41: cs = 41; goto _test_eof;
1242
+ _test_eof42: cs = 42; goto _test_eof;
1243
+ _test_eof43: cs = 43; goto _test_eof;
1244
+ _test_eof44: cs = 44; goto _test_eof;
1245
+ _test_eof45: cs = 45; goto _test_eof;
1246
+ _test_eof46: cs = 46; goto _test_eof;
1247
+ _test_eof47: cs = 47; goto _test_eof;
1248
+ _test_eof48: cs = 48; goto _test_eof;
1249
+ _test_eof49: cs = 49; goto _test_eof;
1250
+ _test_eof50: cs = 50; goto _test_eof;
1251
+ _test_eof51: cs = 51; goto _test_eof;
1252
+ _test_eof52: cs = 52; goto _test_eof;
1253
+ _test_eof53: cs = 53; goto _test_eof;
1254
+ _test_eof54: cs = 54; goto _test_eof;
1255
+ _test_eof55: cs = 55; goto _test_eof;
1256
+ _test_eof56: cs = 56; goto _test_eof;
1257
+ _test_eof57: cs = 57; goto _test_eof;
1258
+ _test_eof58: cs = 58; goto _test_eof;
1259
+ _test_eof59: cs = 59; goto _test_eof;
1260
+ _test_eof60: cs = 60; goto _test_eof;
1261
+ _test_eof61: cs = 61; goto _test_eof;
1262
+ _test_eof62: cs = 62; goto _test_eof;
1263
+
1264
+ _test_eof: {}
1265
+ _out: {}
1266
+ }
1267
+
1268
+ #line 138 "http11_parser.rl"
1269
+
1270
+ if (!http_parser_has_error(parser))
1271
+ parser->cs = cs;
1272
+ parser->nread += p - (buffer + off);
1273
+
1274
+ assert(p <= pe && "buffer overflow after parsing execute");
1275
+ assert(parser->nread <= len && "nread longer than length");
1276
+ assert(parser->body_start <= len && "body starts after buffer end");
1277
+ assert(parser->mark < len && "mark is after buffer end");
1278
+ assert(parser->field_len <= len && "field has length longer than whole buffer");
1279
+ assert(parser->field_start < len && "field starts after buffer end");
1280
+ }
1281
+
1282
+ static int http_parser_has_error(http_parser *parser) {
1283
+ return parser->cs == http_parser_error;
1284
+ }
42
1285
 
43
- #endif
1286
+ static int http_parser_is_finished(http_parser *parser) {
1287
+ return parser->cs == http_parser_first_final;
1288
+ }
1289
+ #endif /* http11_parser_h */