unicorn 0.2.3 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/.document +1 -1
  2. data/.gitignore +1 -0
  3. data/CHANGELOG +1 -0
  4. data/DESIGN +4 -0
  5. data/GNUmakefile +30 -6
  6. data/Manifest +62 -3
  7. data/README +52 -42
  8. data/SIGNALS +17 -17
  9. data/TODO +27 -5
  10. data/bin/unicorn +15 -13
  11. data/bin/unicorn_rails +59 -22
  12. data/ext/unicorn/http11/http11.c +25 -104
  13. data/ext/unicorn/http11/http11_parser.c +24 -23
  14. data/ext/unicorn/http11/http11_parser.h +1 -3
  15. data/ext/unicorn/http11/http11_parser.rl +2 -1
  16. data/lib/unicorn.rb +58 -44
  17. data/lib/unicorn/app/old_rails.rb +23 -0
  18. data/lib/unicorn/app/old_rails/static.rb +58 -0
  19. data/lib/unicorn/cgi_wrapper.rb +151 -0
  20. data/lib/unicorn/configurator.rb +71 -31
  21. data/lib/unicorn/const.rb +9 -34
  22. data/lib/unicorn/http_request.rb +63 -66
  23. data/lib/unicorn/http_response.rb +6 -1
  24. data/lib/unicorn/socket.rb +15 -2
  25. data/test/benchmark/README +55 -0
  26. data/test/benchmark/big_request.rb +35 -0
  27. data/test/benchmark/dd.ru +18 -0
  28. data/test/benchmark/request.rb +47 -0
  29. data/test/benchmark/response.rb +29 -0
  30. data/test/exec/test_exec.rb +41 -157
  31. data/test/rails/app-1.2.3/.gitignore +2 -0
  32. data/test/rails/app-1.2.3/app/controllers/application.rb +4 -0
  33. data/test/rails/app-1.2.3/app/controllers/foo_controller.rb +34 -0
  34. data/test/rails/app-1.2.3/app/helpers/application_helper.rb +2 -0
  35. data/test/rails/app-1.2.3/config/boot.rb +9 -0
  36. data/test/rails/app-1.2.3/config/database.yml +12 -0
  37. data/test/rails/app-1.2.3/config/environment.rb +10 -0
  38. data/test/rails/app-1.2.3/config/environments/development.rb +7 -0
  39. data/test/rails/app-1.2.3/config/environments/production.rb +3 -0
  40. data/test/rails/app-1.2.3/config/routes.rb +4 -0
  41. data/test/rails/app-1.2.3/db/.gitignore +0 -0
  42. data/test/rails/app-1.2.3/public/404.html +1 -0
  43. data/test/rails/app-1.2.3/public/500.html +1 -0
  44. data/test/rails/app-2.0.2/.gitignore +2 -0
  45. data/test/rails/app-2.0.2/app/controllers/application.rb +2 -0
  46. data/test/rails/app-2.0.2/app/controllers/foo_controller.rb +34 -0
  47. data/test/rails/app-2.0.2/app/helpers/application_helper.rb +2 -0
  48. data/test/rails/app-2.0.2/config/boot.rb +9 -0
  49. data/test/rails/app-2.0.2/config/database.yml +12 -0
  50. data/test/rails/app-2.0.2/config/environment.rb +14 -0
  51. data/test/rails/app-2.0.2/config/environments/development.rb +6 -0
  52. data/test/rails/app-2.0.2/config/environments/production.rb +3 -0
  53. data/test/rails/app-2.0.2/config/routes.rb +4 -0
  54. data/test/rails/app-2.0.2/db/.gitignore +0 -0
  55. data/test/rails/app-2.0.2/public/404.html +1 -0
  56. data/test/rails/app-2.0.2/public/500.html +1 -0
  57. data/test/rails/app-2.2.2/.gitignore +2 -0
  58. data/test/rails/app-2.2.2/app/controllers/application.rb +2 -0
  59. data/test/rails/app-2.2.2/app/controllers/foo_controller.rb +34 -0
  60. data/test/rails/app-2.2.2/app/helpers/application_helper.rb +2 -0
  61. data/test/rails/app-2.2.2/config/boot.rb +109 -0
  62. data/test/rails/app-2.2.2/config/database.yml +12 -0
  63. data/test/rails/app-2.2.2/config/environment.rb +14 -0
  64. data/test/rails/app-2.2.2/config/environments/development.rb +5 -0
  65. data/test/rails/app-2.2.2/config/environments/production.rb +3 -0
  66. data/test/rails/app-2.2.2/config/routes.rb +4 -0
  67. data/test/rails/app-2.2.2/db/.gitignore +0 -0
  68. data/test/rails/app-2.2.2/public/404.html +1 -0
  69. data/test/rails/app-2.2.2/public/500.html +1 -0
  70. data/test/rails/app-2.3.2.1/.gitignore +2 -0
  71. data/test/rails/app-2.3.2.1/app/controllers/application_controller.rb +3 -0
  72. data/test/rails/app-2.3.2.1/app/controllers/foo_controller.rb +34 -0
  73. data/test/rails/app-2.3.2.1/app/helpers/application_helper.rb +2 -0
  74. data/test/rails/app-2.3.2.1/config/boot.rb +107 -0
  75. data/test/rails/app-2.3.2.1/config/database.yml +12 -0
  76. data/test/rails/app-2.3.2.1/config/environment.rb +14 -0
  77. data/test/rails/app-2.3.2.1/config/environments/development.rb +5 -0
  78. data/test/rails/app-2.3.2.1/config/environments/production.rb +4 -0
  79. data/test/rails/app-2.3.2.1/config/routes.rb +4 -0
  80. data/test/rails/app-2.3.2.1/db/.gitignore +0 -0
  81. data/test/rails/app-2.3.2.1/public/404.html +1 -0
  82. data/test/rails/app-2.3.2.1/public/500.html +1 -0
  83. data/test/rails/test_rails.rb +243 -0
  84. data/test/test_helper.rb +149 -2
  85. data/test/unit/test_configurator.rb +46 -0
  86. data/test/unit/test_http_parser.rb +77 -36
  87. data/test/unit/test_request.rb +2 -0
  88. data/test/unit/test_response.rb +20 -4
  89. data/test/unit/test_server.rb +30 -1
  90. data/test/unit/test_socket_helper.rb +159 -0
  91. data/unicorn.gemspec +5 -5
  92. metadata +68 -5
  93. data/test/benchmark/previous.rb +0 -11
  94. data/test/benchmark/simple.rb +0 -11
  95. data/test/benchmark/utils.rb +0 -82
@@ -9,7 +9,8 @@ cmd = File.basename($0)
9
9
  daemonize = false
10
10
  listeners = []
11
11
  options = { :listeners => listeners }
12
- host, port = Unicorn::Const::DEFAULT_HOST, 3000
12
+ host, port = Unicorn::Const::DEFAULT_HOST, Unicorn::Const::DEFAULT_PORT
13
+ set_listener = false
13
14
  ENV['RAILS_ENV'] ||= "development"
14
15
  map_path = ENV['RAILS_RELATIVE_URL_ROOT']
15
16
 
@@ -49,10 +50,12 @@ opts = OptionParser.new("", 24, ' ') do |opts|
49
50
  opts.on("-o", "--host HOST",
50
51
  "listen on HOST (default: #{Unicorn::Const::DEFAULT_HOST})") do |h|
51
52
  host = h
53
+ set_listener = true
52
54
  end
53
55
 
54
56
  opts.on("-p", "--port PORT", "use PORT (default: #{port})") do |p|
55
57
  port = p.to_i
58
+ set_listener = true
56
59
  end
57
60
 
58
61
  opts.on("-E", "--env ENVIRONMENT",
@@ -78,7 +81,7 @@ opts = OptionParser.new("", 24, ' ') do |opts|
78
81
 
79
82
  opts.on("-P", "--path PATH", "Runs Rails app mounted at a specific path.",
80
83
  "(default: /") do |v|
81
- map_path = v
84
+ ENV['RAILS_RELATIVE_URL_ROOT'] = map_path = v
82
85
  end
83
86
 
84
87
  # I'm avoiding Unicorn-specific config options on the command-line.
@@ -101,6 +104,15 @@ opts = OptionParser.new("", 24, ' ') do |opts|
101
104
  opts.parse! ARGV
102
105
  end
103
106
 
107
+ config = ARGV[0] || (File.exist?('config.ru') ? 'config.ru' : nil)
108
+
109
+ if config && config =~ /\.ru$/
110
+ # parse embedded command-line options in config.ru comments
111
+ if File.open(config, "rb") { |fp| fp.sysread(fp.stat.size) } =~ /^#\\(.*)/
112
+ opts.parse! $1.split(/\s+/)
113
+ end
114
+ end
115
+
104
116
  require 'pp' if $DEBUG
105
117
 
106
118
  # Loads Rails and the private version of Rack it bundles. Returns a
@@ -113,25 +125,37 @@ rails_loader = lambda do ||
113
125
  defined?(::RAILS_ENV) or abort "RAILS_ENV not defined by config/boot"
114
126
  defined?(::Rails::VERSION::STRING) or
115
127
  abort "Rails::VERSION::STRING not defined by config/boot"
116
- rescue LoadError
117
- abort "#$0 must be run inside RAILS_ROOT (#{::RAILS_ROOT})"
128
+ rescue LoadError => err
129
+ abort "#$0 must be run inside RAILS_ROOT: #{err.inspect}"
118
130
  end
131
+ defined?(::RAILS_ROOT) or abort "RAILS_ROOT not defined by config/boot"
132
+ defined?(::RAILS_ENV) or abort "RAILS_ENV not defined by config/boot"
133
+ defined?(::Rails::VERSION::STRING) or
134
+ abort "Rails::VERSION::STRING not defined by config/boot"
119
135
 
120
- # return the lambda
121
- config = ::ARGV[0] || (File.exist?('config.ru') ? 'config.ru' : nil)
122
136
  case config
123
137
  when nil
124
138
  lambda do ||
125
139
  require 'config/environment'
126
- ActionController::Dispatcher.new
140
+
141
+ # it seems Rails >=2.2 support Rack, but only >=2.3 requires it
142
+ old_rails = case ::Rails::VERSION::MAJOR
143
+ when 0, 1 then true
144
+ when 2 then Rails::VERSION::MINOR < 3 ? true : false
145
+ else
146
+ false
147
+ end
148
+
149
+ if old_rails
150
+ require 'rack'
151
+ require 'unicorn/app/old_rails'
152
+ Unicorn::App::OldRails.new
153
+ else
154
+ ActionController::Dispatcher.new
155
+ end
127
156
  end
128
157
  when /\.ru$/
129
158
  raw = File.open(config, "rb") { |fp| fp.sysread(fp.stat.size) }
130
- # parse embedded command-line options in config.ru comments
131
- if raw[/^#\\(.*)/]
132
- opts.parse! $1.split(/\s+/)
133
- require 'pp' if $DEBUG
134
- end
135
159
  lambda { || eval("Rack::Builder.new {(#{raw}\n)}.to_app", nil, config) }
136
160
  else
137
161
  lambda do ||
@@ -146,21 +170,34 @@ app = lambda do ||
146
170
  inner_app = rails_loader.call
147
171
  require 'active_support'
148
172
  require 'action_controller'
149
- ActionController::Base.relative_url_root = map_path if map_path
173
+ map_path ||= '/'
174
+ inner_app = inner_app.call
150
175
  Rack::Builder.new do
151
- use Rails::Rack::LogTailer unless daemonize
152
- use Rails::Rack::Debugger if $DEBUG
153
- map(map_path || '/') do
154
- use Rails::Rack::Static
155
- run inner_app.call
176
+ if inner_app.class.to_s == "Unicorn::App::OldRails"
177
+ if map_path != '/'
178
+ # patches + tests welcome, but I really cbf to deal with this
179
+ # since all apps I've ever dealt with just use "/" ...
180
+ $stderr.puts "relative URL roots may not work for older Rails"
181
+ end
182
+ $stderr.puts "LogTailer not available for Rails < 2.3" unless daemonize
183
+ $stderr.puts "Debugger not available" if $DEBUG
184
+ map(map_path) do
185
+ require 'unicorn/app/old_rails/static'
186
+ use Unicorn::App::OldRails::Static
187
+ run inner_app
188
+ end
189
+ else
190
+ use Rails::Rack::LogTailer unless daemonize
191
+ use Rails::Rack::Debugger if $DEBUG
192
+ map(map_path) do
193
+ use Rails::Rack::Static
194
+ run inner_app
195
+ end
156
196
  end
157
197
  end.to_app
158
198
  end
159
199
 
160
- if listeners.empty?
161
- listener = "#{host}:#{port}"
162
- listeners << listener
163
- end
200
+ listeners << "#{host}:#{port}" if set_listener
164
201
 
165
202
  if $DEBUG
166
203
  pp({
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * Copyright (c) 2009 Eric Wong (all bugs are Eric's fault)
2
3
  * Copyright (c) 2005 Zed A. Shaw
3
4
  * You can redistribute it and/or modify it under the same terms as Ruby.
4
5
  */
@@ -18,6 +19,7 @@
18
19
  static VALUE mUnicorn;
19
20
  static VALUE cHttpParser;
20
21
  static VALUE eHttpParserError;
22
+ static VALUE sym_http_body;
21
23
 
22
24
  #define HTTP_PREFIX "HTTP_"
23
25
  #define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1)
@@ -30,7 +32,6 @@ static VALUE global_http_version;
30
32
  static VALUE global_content_length;
31
33
  static VALUE global_request_path;
32
34
  static VALUE global_content_type;
33
- static VALUE global_http_body;
34
35
  static VALUE global_server_name;
35
36
  static VALUE global_server_port;
36
37
  static VALUE global_server_protocol;
@@ -298,7 +299,7 @@ static void header_done(void *data, const char *at, size_t length)
298
299
  }
299
300
 
300
301
  /* grab the initial body and stuff it into the hash */
301
- rb_hash_aset(req, global_http_body, rb_str_new(at, length));
302
+ rb_hash_aset(req, sym_http_body, rb_str_new(at, length));
302
303
  rb_hash_aset(req, global_server_protocol, global_server_protocol_value);
303
304
  }
304
305
 
@@ -367,113 +368,37 @@ static VALUE HttpParser_reset(VALUE self)
367
368
 
368
369
  /**
369
370
  * call-seq:
370
- * parser.finish -> true/false
371
+ * parser.execute(req_hash, data) -> true/false
371
372
  *
372
- * Finishes a parser early which could put in a "good" or bad state.
373
- * You should call reset after finish it or bad things will happen.
374
- */
375
- static VALUE HttpParser_finish(VALUE self)
376
- {
377
- http_parser *http = NULL;
378
- DATA_GET(self, http_parser, http);
379
- http_parser_finish(http);
380
-
381
- return http_parser_is_finished(http) ? Qtrue : Qfalse;
382
- }
383
-
384
-
385
- /**
386
- * call-seq:
387
- * parser.execute(req_hash, data, start) -> Integer
388
- *
389
- * Takes a Hash and a String of data, parses the String of data filling in the Hash
390
- * returning an Integer to indicate how much of the data has been read. No matter
391
- * what the return value, you should call HttpParser#finished? and HttpParser#error?
392
- * to figure out if it's done parsing or there was an error.
373
+ * Takes a Hash and a String of data, parses the String of data filling
374
+ * in the Hash returning a boolean to indicate whether or not parsing
375
+ * is finished.
393
376
  *
394
- * This function now throws an exception when there is a parsing error. This makes
395
- * the logic for working with the parser much easier. You can still test for an
396
- * error, but now you need to wrap the parser with an exception handling block.
397
- *
398
- * The third argument allows for parsing a partial request and then continuing
399
- * the parsing from that position. It needs all of the original data as well
400
- * so you have to append to the data buffer as you read.
377
+ * This function now throws an exception when there is a parsing error.
378
+ * This makes the logic for working with the parser much easier. You
379
+ * will need to wrap the parser with an exception handling block.
401
380
  */
402
- static VALUE HttpParser_execute(VALUE self, VALUE req_hash,
403
- VALUE data, VALUE start)
404
- {
405
- http_parser *http = NULL;
406
- int from = 0;
407
- char *dptr = NULL;
408
- long dlen = 0;
409
-
410
- DATA_GET(self, http_parser, http);
411
-
412
- from = FIX2INT(start);
413
- dptr = RSTRING_PTR(data);
414
- dlen = RSTRING_LEN(data);
415
-
416
- if(from >= dlen) {
417
- rb_raise(eHttpParserError, "Requested start is after data buffer end.");
418
- } else {
419
- http->data = (void *)req_hash;
420
- http_parser_execute(http, dptr, dlen, from);
421
-
422
- VALIDATE_MAX_LENGTH(http_parser_nread(http), HEADER);
423
-
424
- if(http_parser_has_error(http)) {
425
- rb_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
426
- } else {
427
- return INT2FIX(http_parser_nread(http));
428
- }
429
- }
430
- }
431
-
432
381
 
433
-
434
- /**
435
- * call-seq:
436
- * parser.error? -> true/false
437
- *
438
- * Tells you whether the parser is in an error state.
439
- */
440
- static VALUE HttpParser_has_error(VALUE self)
382
+ static VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data)
441
383
  {
442
- http_parser *http = NULL;
443
- DATA_GET(self, http_parser, http);
384
+ http_parser *http;
385
+ char *dptr = RSTRING_PTR(data);
386
+ long dlen = RSTRING_LEN(data);
444
387
 
445
- return http_parser_has_error(http) ? Qtrue : Qfalse;
446
- }
447
-
448
-
449
- /**
450
- * call-seq:
451
- * parser.finished? -> true/false
452
- *
453
- * Tells you whether the parser is finished or not and in a good state.
454
- */
455
- static VALUE HttpParser_is_finished(VALUE self)
456
- {
457
- http_parser *http = NULL;
458
388
  DATA_GET(self, http_parser, http);
459
389
 
460
- return http_parser_is_finished(http) ? Qtrue : Qfalse;
461
- }
390
+ if (http->nread < dlen) {
391
+ http->data = (void *)req_hash;
392
+ http_parser_execute(http, dptr, dlen);
462
393
 
394
+ VALIDATE_MAX_LENGTH(http->nread, HEADER);
463
395
 
464
- /**
465
- * call-seq:
466
- * parser.nread -> Integer
467
- *
468
- * Returns the amount of data processed so far during this processing cycle. It is
469
- * set to 0 on initialize or reset calls and is incremented each time execute is called.
470
- */
471
- static VALUE HttpParser_nread(VALUE self)
472
- {
473
- http_parser *http = NULL;
474
- DATA_GET(self, http_parser, http);
396
+ if (!http_parser_has_error(http))
397
+ return http_parser_is_finished(http) ? Qtrue : Qfalse;
475
398
 
476
- return INT2FIX(http->nread);
399
+ rb_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
400
+ }
401
+ rb_raise(eHttpParserError, "Requested start is after data buffer end.");
477
402
  }
478
403
 
479
404
  void Init_http11()
@@ -488,7 +413,6 @@ void Init_http11()
488
413
  DEF_GLOBAL(http_version, "HTTP_VERSION");
489
414
  DEF_GLOBAL(request_path, "REQUEST_PATH");
490
415
  DEF_GLOBAL(content_length, "CONTENT_LENGTH");
491
- DEF_GLOBAL(http_body, "HTTP_BODY");
492
416
  DEF_GLOBAL(content_type, "CONTENT_TYPE");
493
417
  DEF_GLOBAL(server_name, "SERVER_NAME");
494
418
  DEF_GLOBAL(server_port, "SERVER_PORT");
@@ -504,10 +428,7 @@ void Init_http11()
504
428
  rb_define_alloc_func(cHttpParser, HttpParser_alloc);
505
429
  rb_define_method(cHttpParser, "initialize", HttpParser_init,0);
506
430
  rb_define_method(cHttpParser, "reset", HttpParser_reset,0);
507
- rb_define_method(cHttpParser, "finish", HttpParser_finish,0);
508
- rb_define_method(cHttpParser, "execute", HttpParser_execute,3);
509
- rb_define_method(cHttpParser, "error?", HttpParser_has_error,0);
510
- rb_define_method(cHttpParser, "finished?", HttpParser_is_finished,0);
511
- rb_define_method(cHttpParser, "nread", HttpParser_nread,0);
431
+ rb_define_method(cHttpParser, "execute", HttpParser_execute,2);
432
+ sym_http_body = ID2SYM(rb_intern("http_body"));
512
433
  init_common_fields();
513
434
  }
@@ -63,9 +63,10 @@ int http_parser_init(http_parser *parser) {
63
63
 
64
64
 
65
65
  /** exec **/
66
- size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len, size_t off) {
66
+ size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len) {
67
67
  const char *p, *pe;
68
68
  int cs = parser->cs;
69
+ size_t off = parser->nread;
69
70
 
70
71
  assert(off <= len && "offset past end of buffer");
71
72
 
@@ -76,7 +77,7 @@ size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len,
76
77
  assert(pe - p == len - off && "pointers aren't same distance");
77
78
 
78
79
 
79
- #line 80 "http11_parser.c"
80
+ #line 81 "http11_parser.c"
80
81
  {
81
82
  if ( p == pe )
82
83
  goto _test_eof;
@@ -107,7 +108,7 @@ st2:
107
108
  if ( ++p == pe )
108
109
  goto _test_eof2;
109
110
  case 2:
110
- #line 111 "http11_parser.c"
111
+ #line 112 "http11_parser.c"
111
112
  switch( (*p) ) {
112
113
  case 32: goto tr2;
113
114
  case 36: goto st38;
@@ -133,7 +134,7 @@ st3:
133
134
  if ( ++p == pe )
134
135
  goto _test_eof3;
135
136
  case 3:
136
- #line 137 "http11_parser.c"
137
+ #line 138 "http11_parser.c"
137
138
  switch( (*p) ) {
138
139
  case 42: goto tr4;
139
140
  case 43: goto tr5;
@@ -157,7 +158,7 @@ st4:
157
158
  if ( ++p == pe )
158
159
  goto _test_eof4;
159
160
  case 4:
160
- #line 161 "http11_parser.c"
161
+ #line 162 "http11_parser.c"
161
162
  switch( (*p) ) {
162
163
  case 32: goto tr8;
163
164
  case 35: goto tr9;
@@ -228,7 +229,7 @@ st5:
228
229
  if ( ++p == pe )
229
230
  goto _test_eof5;
230
231
  case 5:
231
- #line 232 "http11_parser.c"
232
+ #line 233 "http11_parser.c"
232
233
  if ( (*p) == 72 )
233
234
  goto tr10;
234
235
  goto st0;
@@ -240,7 +241,7 @@ st6:
240
241
  if ( ++p == pe )
241
242
  goto _test_eof6;
242
243
  case 6:
243
- #line 244 "http11_parser.c"
244
+ #line 245 "http11_parser.c"
244
245
  if ( (*p) == 84 )
245
246
  goto st7;
246
247
  goto st0;
@@ -326,7 +327,7 @@ st14:
326
327
  if ( ++p == pe )
327
328
  goto _test_eof14;
328
329
  case 14:
329
- #line 330 "http11_parser.c"
330
+ #line 331 "http11_parser.c"
330
331
  if ( (*p) == 10 )
331
332
  goto st15;
332
333
  goto st0;
@@ -378,7 +379,7 @@ st57:
378
379
  if ( ++p == pe )
379
380
  goto _test_eof57;
380
381
  case 57:
381
- #line 382 "http11_parser.c"
382
+ #line 383 "http11_parser.c"
382
383
  goto st0;
383
384
  tr21:
384
385
  #line 37 "http11_parser.rl"
@@ -394,7 +395,7 @@ st17:
394
395
  if ( ++p == pe )
395
396
  goto _test_eof17;
396
397
  case 17:
397
- #line 398 "http11_parser.c"
398
+ #line 399 "http11_parser.c"
398
399
  switch( (*p) ) {
399
400
  case 33: goto tr23;
400
401
  case 58: goto tr24;
@@ -433,7 +434,7 @@ st18:
433
434
  if ( ++p == pe )
434
435
  goto _test_eof18;
435
436
  case 18:
436
- #line 437 "http11_parser.c"
437
+ #line 438 "http11_parser.c"
437
438
  switch( (*p) ) {
438
439
  case 13: goto tr26;
439
440
  case 32: goto tr27;
@@ -447,7 +448,7 @@ st19:
447
448
  if ( ++p == pe )
448
449
  goto _test_eof19;
449
450
  case 19:
450
- #line 451 "http11_parser.c"
451
+ #line 452 "http11_parser.c"
451
452
  if ( (*p) == 13 )
452
453
  goto tr29;
453
454
  goto st19;
@@ -500,7 +501,7 @@ st20:
500
501
  if ( ++p == pe )
501
502
  goto _test_eof20;
502
503
  case 20:
503
- #line 504 "http11_parser.c"
504
+ #line 505 "http11_parser.c"
504
505
  switch( (*p) ) {
505
506
  case 32: goto tr31;
506
507
  case 35: goto st0;
@@ -518,7 +519,7 @@ st21:
518
519
  if ( ++p == pe )
519
520
  goto _test_eof21;
520
521
  case 21:
521
- #line 522 "http11_parser.c"
522
+ #line 523 "http11_parser.c"
522
523
  switch( (*p) ) {
523
524
  case 32: goto tr34;
524
525
  case 35: goto st0;
@@ -536,7 +537,7 @@ st22:
536
537
  if ( ++p == pe )
537
538
  goto _test_eof22;
538
539
  case 22:
539
- #line 540 "http11_parser.c"
540
+ #line 541 "http11_parser.c"
540
541
  if ( (*p) < 65 ) {
541
542
  if ( 48 <= (*p) && (*p) <= 57 )
542
543
  goto st23;
@@ -567,7 +568,7 @@ st24:
567
568
  if ( ++p == pe )
568
569
  goto _test_eof24;
569
570
  case 24:
570
- #line 571 "http11_parser.c"
571
+ #line 572 "http11_parser.c"
571
572
  switch( (*p) ) {
572
573
  case 43: goto st24;
573
574
  case 58: goto st25;
@@ -592,7 +593,7 @@ st25:
592
593
  if ( ++p == pe )
593
594
  goto _test_eof25;
594
595
  case 25:
595
- #line 596 "http11_parser.c"
596
+ #line 597 "http11_parser.c"
596
597
  switch( (*p) ) {
597
598
  case 32: goto tr8;
598
599
  case 35: goto tr9;
@@ -636,7 +637,7 @@ st28:
636
637
  if ( ++p == pe )
637
638
  goto _test_eof28;
638
639
  case 28:
639
- #line 640 "http11_parser.c"
640
+ #line 641 "http11_parser.c"
640
641
  switch( (*p) ) {
641
642
  case 32: goto tr42;
642
643
  case 35: goto tr43;
@@ -685,7 +686,7 @@ st31:
685
686
  if ( ++p == pe )
686
687
  goto _test_eof31;
687
688
  case 31:
688
- #line 689 "http11_parser.c"
689
+ #line 690 "http11_parser.c"
689
690
  switch( (*p) ) {
690
691
  case 32: goto tr8;
691
692
  case 35: goto tr9;
@@ -733,7 +734,7 @@ st34:
733
734
  if ( ++p == pe )
734
735
  goto _test_eof34;
735
736
  case 34:
736
- #line 737 "http11_parser.c"
737
+ #line 738 "http11_parser.c"
737
738
  switch( (*p) ) {
738
739
  case 32: goto tr53;
739
740
  case 35: goto tr54;
@@ -751,7 +752,7 @@ st35:
751
752
  if ( ++p == pe )
752
753
  goto _test_eof35;
753
754
  case 35:
754
- #line 755 "http11_parser.c"
755
+ #line 756 "http11_parser.c"
755
756
  switch( (*p) ) {
756
757
  case 32: goto tr57;
757
758
  case 35: goto tr58;
@@ -769,7 +770,7 @@ st36:
769
770
  if ( ++p == pe )
770
771
  goto _test_eof36;
771
772
  case 36:
772
- #line 773 "http11_parser.c"
773
+ #line 774 "http11_parser.c"
773
774
  if ( (*p) < 65 ) {
774
775
  if ( 48 <= (*p) && (*p) <= 57 )
775
776
  goto st37;
@@ -1184,7 +1185,7 @@ case 56:
1184
1185
  _test_eof: {}
1185
1186
  _out: {}
1186
1187
  }
1187
- #line 121 "http11_parser.rl"
1188
+ #line 122 "http11_parser.rl"
1188
1189
 
1189
1190
  if (!http_parser_has_error(parser))
1190
1191
  parser->cs = cs;