thin 0.5.4-x86-mswin32-60 → 0.6.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of thin might be problematic. Click here for more details.

data/CHANGELOG CHANGED
@@ -1,9 +1,46 @@
1
+ == 0.6.0 Big Pony release
2
+ * Add support for connection through UNIX domain socket.
3
+ Use the --socket (-S) option w/ the thin script to configure the socket filename.
4
+ Nginx support binding to a UNIX socket like this:
5
+
6
+ upstream backend {
7
+ server unix:/tmp/thin.0.sock;
8
+ server unix:/tmp/thin.1.sock;
9
+ server unix:/tmp/thin.2.sock;
10
+ }
11
+
12
+ Start your servers like this:
13
+
14
+ thin start -s3 -S/tmp/thin.sock
15
+
16
+ * Remove Server#listen! method. Use Server#start instead.
17
+ * Server can now yield a Rack::Builder to allow building an app in one call:
18
+
19
+ Server.start '0.0.0.0', 3000 do
20
+ use Rack::CommonLogger
21
+ use Rack::ShowExceptions
22
+ map "/lobster" do
23
+ use Rack::Lint
24
+ run Rack::Lobster.new
25
+ end
26
+ end
27
+
28
+ * Add a very basic stats page through Stats adapter, load w/ --stats and browse to /stats.
29
+ * Add --trace (-V) option to trace request/response and get backtrace w/out all Ruby debug stuff.
30
+ * Add --config (-C) option to load options from a config file in thin script [Matt Todd].
31
+ * Alter response headers to output directly to a string.
32
+ * Improve specs stability.
33
+ * Move request body to a Tempfile if too big (> 112 MB)
34
+ * Remove useless check for max header size in Request (already done in the parser)
35
+
1
36
  == 0.5.4 Flying Mustard release
2
37
  * Don't read the full body, use direct streaming when sending response.
3
38
  See: Response#each
4
- As a result, the Content-Length can not be calculated any more.
5
- You have to do set it in your adapter. All frameworks do it anyway.
6
- * Add Server response header
39
+ As a result, the Content-Length can not be calculated anymore.
40
+ You have to do set this in your adapter. All frameworks do it anyway.
41
+ It improve memory usage and boost speed for low concurrency.
42
+ Thanks to Kent Sibilev and Ezra for their help on that one.
43
+ * Add 'Server' response header
7
44
  * Fix --user and --group option not changing daemon process privileges
8
45
 
9
46
  == 0.5.3 Purple Yogurt release
data/README CHANGED
@@ -13,13 +13,13 @@ For the latest stable version:
13
13
 
14
14
  sudo gem install thin
15
15
 
16
- or using my mirror (might be more recent):
16
+ or using my mirror (might be more recent and unstable):
17
17
 
18
18
  sudo gem install thin --source http://code.macournoyer.com
19
19
 
20
20
  Or from source:
21
21
 
22
- git clone git://repo.or.cz/thin.git
22
+ git clone git://github.com/macournoyer/thin.git
23
23
  cd thin
24
24
  rake install
25
25
 
@@ -36,7 +36,14 @@ You need to setup a config.ru file and require thin in it:
36
36
  require 'thin'
37
37
 
38
38
  app = proc do |env|
39
- [200, {'Content-Type'=>'text/html'}, ['hi']]
39
+ [
40
+ 200,
41
+ {
42
+ 'Content-Type' => 'text/html',
43
+ 'Content-Length' => '2'
44
+ },
45
+ ['hi']
46
+ ]
40
47
  end
41
48
 
42
49
  run app
@@ -56,5 +63,6 @@ either the terms of the GPL.
56
63
 
57
64
  Thin is copyright Marc-Andre Cournoyer <macournoyer@gmail.com>
58
65
 
59
- Please report any bug at http://groups.google.com/group/thin-ruby/
60
- and major security issues directly to me at macournoyer@gmail.com.
66
+ Get help at http://groups.google.com/group/thin-ruby/
67
+ Report bugs at http://thin.lighthouseapp.com/projects/7212-thin
68
+ and major security issues directly to a team member (see COMMITTERS)
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  RUBY_1_9 = RUBY_VERSION =~ /^1\.9/
2
- WIN = (PLATFORM =~ /mswin|cygwin/)
2
+ WIN = (RUBY_PLATFORM =~ /mswin|cygwin/)
3
3
  SUDO = (WIN ? "" : "sudo")
4
4
 
5
5
  require 'rake'
@@ -8,4 +8,4 @@ require 'lib/thin'
8
8
 
9
9
  Dir['tasks/**/*.rake'].each { |rake| load rake }
10
10
 
11
- task :default => [:compile, :spec]
11
+ task :default => :spec
data/bin/thin CHANGED
@@ -3,8 +3,9 @@
3
3
  # Run <tt>thin -h</tt> to get more usage.
4
4
  require File.dirname(__FILE__) + '/../lib/thin'
5
5
  require 'optparse'
6
+ require 'yaml'
6
7
 
7
- COMMANDS = %w(start stop restart)
8
+ COMMANDS = %w(start stop restart config)
8
9
 
9
10
  # Default options values
10
11
  options = {
@@ -30,6 +31,7 @@ opts = OptionParser.new do |opts|
30
31
 
31
32
  opts.on("-a", "--address HOST", "bind to HOST address (default: 0.0.0.0)") { |host| options[:address] = host }
32
33
  opts.on("-p", "--port PORT", "use PORT (default: 3000)") { |port| options[:port] = port.to_i }
34
+ opts.on("-S", "--socket PATH", "bind to unix domain socket") { |file| options[:socket] = file }
33
35
  opts.on("-e", "--environment ENV", "Rails environment (default: development)") { |env| options[:environment] = env }
34
36
  opts.on("-c", "--chdir PATH", "Change to dir before starting") { |dir| options[:chdir] = File.expand_path(dir) }
35
37
  opts.on("-s", "--servers NUM", "Number of servers to start",
@@ -44,29 +46,45 @@ opts = OptionParser.new do |opts|
44
46
  opts.on("-u", "--user NAME", "User to run daemon as (use with -g)") { |user| options[:user] = user }
45
47
  opts.on("-g", "--group NAME", "Group to run daemon as (use with -u)") { |group| options[:group] = group }
46
48
  opts.on( "--prefix PATH", "Mount the app under PATH (start with /)") { |path| options[:prefix] = path }
49
+ opts.on("-C", "--config PATH", "Load option from a config file") { |file| options[:config] = file }
50
+ opts.on( "--stats", "Install the Stats adapter at /stats") { options[:stats] = true }
47
51
 
48
52
  opts.separator ""
49
53
  opts.separator "Common options:"
50
54
 
51
- opts.on_tail("-D", "--debug", "Set debbuging on") { $DEBUG = true }
52
- opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
53
- opts.on_tail('-v', '--version', "Show version") { puts Thin::SERVER; exit }
54
-
55
- opts.parse! ARGV
55
+ opts.on_tail("-D", "--debug", "Set debbuging on") { $DEBUG = true }
56
+ opts.on_tail("-V", "--trace", "Set tracing on") { $TRACE = true }
57
+ opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
58
+ opts.on_tail('-v', '--version', "Show version") { puts Thin::SERVER; exit }
56
59
  end
57
60
 
58
61
 
59
- # == Commands definitions
62
+ # == Utilities
60
63
 
61
64
  def cluster?(options)
62
65
  options[:servers] && options[:servers] > 1
63
66
  end
64
67
 
68
+ def load_options_from_config_file!(options)
69
+ if file = options.delete(:config)
70
+ YAML.load_file(file).each { |key, value| options[key.to_sym] = value }
71
+ end
72
+ end
73
+
74
+
75
+ # == Commands definitions
76
+
65
77
  def start(options)
78
+ load_options_from_config_file! options
79
+
66
80
  if cluster?(options)
67
81
  Thin::Cluster.new(options).start
68
82
  else
69
- server = Thin::Server.new(options[:address], options[:port])
83
+ if options[:socket]
84
+ server = Thin::Server.new(options[:socket])
85
+ else
86
+ server = Thin::Server.new(options[:address], options[:port])
87
+ end
70
88
 
71
89
  server.pid_file = options[:pid]
72
90
  server.log_file = options[:log]
@@ -82,11 +100,16 @@ def start(options)
82
100
  # If a prefix is required, wrap in Rack URL mapper
83
101
  server.app = Rack::URLMap.new(options[:prefix] => server.app) if options[:prefix]
84
102
 
103
+ # If a stats are required, wrap in Stats adapter
104
+ server.app = Thin::Stats::Adapter.new(server.app) if options[:stats]
105
+
85
106
  server.start!
86
107
  end
87
108
  end
88
109
 
89
110
  def stop(options)
111
+ load_options_from_config_file! options
112
+
90
113
  if cluster?(options)
91
114
  Thin::Cluster.new(options).stop
92
115
  else
@@ -95,6 +118,8 @@ def stop(options)
95
118
  end
96
119
 
97
120
  def restart(options)
121
+ load_options_from_config_file! options
122
+
98
123
  if cluster?(options)
99
124
  Thin::Cluster.new(options).restart
100
125
  else
@@ -106,12 +131,24 @@ def restart(options)
106
131
  end
107
132
  end
108
133
 
134
+ def config(options)
135
+ config_file = options.delete(:config) || abort('config option required')
136
+
137
+ # Stringify keys
138
+ options.keys.each { |o| options[o.to_s] = options.delete(o) }
139
+
140
+ File.open(config_file, 'w') { |f| f << options.to_yaml }
141
+ puts "Wrote configuration to #{config_file}"
142
+ end
143
+
109
144
 
110
145
  # == Runs the command
111
146
 
112
- Dir.chdir(options[:chdir])
147
+ opts.parse! ARGV
113
148
  command = ARGV[0]
114
149
 
150
+ Dir.chdir(options[:chdir])
151
+
115
152
  if COMMANDS.include?(command)
116
153
  send(command, options)
117
154
  elsif command.nil?
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'thin'
3
+
4
+ class SimpleAdapter
5
+ def call(env)
6
+ [
7
+ 200,
8
+ { 'Content-Type' => 'text/plain' },
9
+ ["hello!\n"]
10
+ ]
11
+ end
12
+ end
13
+
14
+ app = Rack::URLMap.new('/test' => SimpleAdapter.new,
15
+ '/files' => Rack::File.new('.'))
16
+
17
+ Thin::Server.new('0.0.0.0', 3000, app).start!
@@ -6,10 +6,17 @@
6
6
  require File.dirname(__FILE__) + '/../lib/thin'
7
7
 
8
8
  app = proc do |env|
9
+ # Response body has to respond to each and yield strings
10
+ # See Rack specs for more info: http://rack.rubyforge.org/doc/files/SPEC.html
11
+ body = ['hi!']
12
+
9
13
  [
10
- 200,
11
- {'Content-Type' => 'text/html'},
12
- ['hi!']
14
+ 200, # Status code
15
+ {
16
+ 'Content-Type' => 'text/html', # Reponse headers
17
+ 'Content-Length' => body.join.size.to_s
18
+ },
19
+ body # Body of the response
13
20
  ]
14
21
  end
15
22
 
@@ -16,7 +16,7 @@
16
16
 
17
17
  /** Machine **/
18
18
 
19
- #line 65 "parser.rl"
19
+ #line 81 "parser.rl"
20
20
 
21
21
 
22
22
  /** Data **/
@@ -28,7 +28,7 @@ static const int http_parser_error = 0;
28
28
 
29
29
  static const int http_parser_en_main = 1;
30
30
 
31
- #line 69 "parser.rl"
31
+ #line 85 "parser.rl"
32
32
 
33
33
  int http_parser_init(http_parser *parser) {
34
34
  int cs = 0;
@@ -37,7 +37,7 @@ int http_parser_init(http_parser *parser) {
37
37
  {
38
38
  cs = http_parser_start;
39
39
  }
40
- #line 73 "parser.rl"
40
+ #line 89 "parser.rl"
41
41
  parser->cs = cs;
42
42
  parser->body_start = 0;
43
43
  parser->content_len = 0;
@@ -111,16 +111,18 @@ case 2:
111
111
  goto st38;
112
112
  goto st0;
113
113
  tr2:
114
- #line 34 "parser.rl"
114
+ #line 36 "parser.rl"
115
115
  {
116
- parser->request_method(parser->data, PTR_TO(mark), LEN(mark, p));
116
+ if (parser->request_method != NULL) {
117
+ parser->request_method(parser->data, PTR_TO(mark), LEN(mark, p));
118
+ }
117
119
  }
118
120
  goto st3;
119
121
  st3:
120
122
  if ( ++p == pe )
121
123
  goto _out3;
122
124
  case 3:
123
- #line 124 "parser.c"
125
+ #line 126 "parser.c"
124
126
  switch( (*p) ) {
125
127
  case 42: goto tr4;
126
128
  case 43: goto tr5;
@@ -144,61 +146,77 @@ st4:
144
146
  if ( ++p == pe )
145
147
  goto _out4;
146
148
  case 4:
147
- #line 148 "parser.c"
149
+ #line 150 "parser.c"
148
150
  switch( (*p) ) {
149
151
  case 32: goto tr8;
150
152
  case 35: goto tr9;
151
153
  }
152
154
  goto st0;
153
155
  tr8:
154
- #line 37 "parser.rl"
155
- {
156
- parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
156
+ #line 41 "parser.rl"
157
+ {
158
+ if (parser->request_uri != NULL) {
159
+ parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
160
+ }
157
161
  }
158
162
  goto st5;
159
163
  tr30:
160
- #line 40 "parser.rl"
164
+ #line 46 "parser.rl"
161
165
  {
162
- parser->fragment(parser->data, PTR_TO(mark), LEN(mark, p));
166
+ if (parser->fragment != NULL) {
167
+ parser->fragment(parser->data, PTR_TO(mark), LEN(mark, p));
168
+ }
163
169
  }
164
170
  goto st5;
165
171
  tr40:
166
- #line 53 "parser.rl"
172
+ #line 65 "parser.rl"
167
173
  {
168
- parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
174
+ if (parser->request_path != NULL) {
175
+ parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
176
+ }
169
177
  }
170
- #line 37 "parser.rl"
171
- {
172
- parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
178
+ #line 41 "parser.rl"
179
+ {
180
+ if (parser->request_uri != NULL) {
181
+ parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
182
+ }
173
183
  }
174
184
  goto st5;
175
185
  tr51:
176
- #line 44 "parser.rl"
186
+ #line 52 "parser.rl"
177
187
  {MARK(query_start, p); }
178
- #line 45 "parser.rl"
188
+ #line 53 "parser.rl"
179
189
  {
180
- parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
190
+ if (parser->query_string != NULL) {
191
+ parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
192
+ }
181
193
  }
182
- #line 37 "parser.rl"
183
- {
184
- parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
194
+ #line 41 "parser.rl"
195
+ {
196
+ if (parser->request_uri != NULL) {
197
+ parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
198
+ }
185
199
  }
186
200
  goto st5;
187
201
  tr55:
188
- #line 45 "parser.rl"
202
+ #line 53 "parser.rl"
189
203
  {
190
- parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
204
+ if (parser->query_string != NULL) {
205
+ parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
206
+ }
191
207
  }
192
- #line 37 "parser.rl"
193
- {
194
- parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
208
+ #line 41 "parser.rl"
209
+ {
210
+ if (parser->request_uri != NULL) {
211
+ parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
212
+ }
195
213
  }
196
214
  goto st5;
197
215
  st5:
198
216
  if ( ++p == pe )
199
217
  goto _out5;
200
218
  case 5:
201
- #line 202 "parser.c"
219
+ #line 220 "parser.c"
202
220
  if ( (*p) == 72 )
203
221
  goto tr10;
204
222
  goto st0;
@@ -210,7 +228,7 @@ st6:
210
228
  if ( ++p == pe )
211
229
  goto _out6;
212
230
  case 6:
213
- #line 214 "parser.c"
231
+ #line 232 "parser.c"
214
232
  if ( (*p) == 84 )
215
233
  goto st7;
216
234
  goto st0;
@@ -268,22 +286,26 @@ case 13:
268
286
  goto st13;
269
287
  goto st0;
270
288
  tr18:
271
- #line 49 "parser.rl"
289
+ #line 59 "parser.rl"
272
290
  {
273
- parser->http_version(parser->data, PTR_TO(mark), LEN(mark, p));
291
+ if (parser->http_version != NULL) {
292
+ parser->http_version(parser->data, PTR_TO(mark), LEN(mark, p));
293
+ }
274
294
  }
275
295
  goto st14;
276
296
  tr26:
277
297
  #line 31 "parser.rl"
278
298
  {
279
- parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
299
+ if (parser->http_field != NULL) {
300
+ parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
301
+ }
280
302
  }
281
303
  goto st14;
282
304
  st14:
283
305
  if ( ++p == pe )
284
306
  goto _out14;
285
307
  case 14:
286
- #line 287 "parser.c"
308
+ #line 309 "parser.c"
287
309
  if ( (*p) == 10 )
288
310
  goto st15;
289
311
  goto st0;
@@ -323,10 +345,12 @@ case 16:
323
345
  goto tr22;
324
346
  goto st0;
325
347
  tr22:
326
- #line 57 "parser.rl"
348
+ #line 71 "parser.rl"
327
349
  {
328
350
  parser->body_start = p - buffer + 1;
329
- parser->header_done(parser->data, p + 1, pe - p - 1);
351
+ if (parser->header_done != NULL) {
352
+ parser->header_done(parser->data, p + 1, pe - p - 1);
353
+ }
330
354
  goto _out57;
331
355
  }
332
356
  goto st57;
@@ -334,7 +358,7 @@ st57:
334
358
  if ( ++p == pe )
335
359
  goto _out57;
336
360
  case 57:
337
- #line 338 "parser.c"
361
+ #line 362 "parser.c"
338
362
  goto st0;
339
363
  tr21:
340
364
  #line 25 "parser.rl"
@@ -344,7 +368,7 @@ st17:
344
368
  if ( ++p == pe )
345
369
  goto _out17;
346
370
  case 17:
347
- #line 348 "parser.c"
371
+ #line 372 "parser.c"
348
372
  switch( (*p) ) {
349
373
  case 33: goto st17;
350
374
  case 58: goto tr24;
@@ -383,7 +407,7 @@ st18:
383
407
  if ( ++p == pe )
384
408
  goto _out18;
385
409
  case 18:
386
- #line 387 "parser.c"
410
+ #line 411 "parser.c"
387
411
  switch( (*p) ) {
388
412
  case 13: goto tr26;
389
413
  case 32: goto tr27;
@@ -397,53 +421,67 @@ st19:
397
421
  if ( ++p == pe )
398
422
  goto _out19;
399
423
  case 19:
400
- #line 401 "parser.c"
424
+ #line 425 "parser.c"
401
425
  if ( (*p) == 13 )
402
426
  goto tr26;
403
427
  goto st19;
404
428
  tr9:
405
- #line 37 "parser.rl"
406
- {
407
- parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
429
+ #line 41 "parser.rl"
430
+ {
431
+ if (parser->request_uri != NULL) {
432
+ parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
433
+ }
408
434
  }
409
435
  goto st20;
410
436
  tr41:
411
- #line 53 "parser.rl"
437
+ #line 65 "parser.rl"
412
438
  {
413
- parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
439
+ if (parser->request_path != NULL) {
440
+ parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
441
+ }
414
442
  }
415
- #line 37 "parser.rl"
416
- {
417
- parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
443
+ #line 41 "parser.rl"
444
+ {
445
+ if (parser->request_uri != NULL) {
446
+ parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
447
+ }
418
448
  }
419
449
  goto st20;
420
450
  tr52:
421
- #line 44 "parser.rl"
451
+ #line 52 "parser.rl"
422
452
  {MARK(query_start, p); }
423
- #line 45 "parser.rl"
453
+ #line 53 "parser.rl"
424
454
  {
425
- parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
455
+ if (parser->query_string != NULL) {
456
+ parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
457
+ }
426
458
  }
427
- #line 37 "parser.rl"
428
- {
429
- parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
459
+ #line 41 "parser.rl"
460
+ {
461
+ if (parser->request_uri != NULL) {
462
+ parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
463
+ }
430
464
  }
431
465
  goto st20;
432
466
  tr56:
433
- #line 45 "parser.rl"
467
+ #line 53 "parser.rl"
434
468
  {
435
- parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
469
+ if (parser->query_string != NULL) {
470
+ parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
471
+ }
436
472
  }
437
- #line 37 "parser.rl"
438
- {
439
- parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
473
+ #line 41 "parser.rl"
474
+ {
475
+ if (parser->request_uri != NULL) {
476
+ parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
477
+ }
440
478
  }
441
479
  goto st20;
442
480
  st20:
443
481
  if ( ++p == pe )
444
482
  goto _out20;
445
483
  case 20:
446
- #line 447 "parser.c"
484
+ #line 485 "parser.c"
447
485
  switch( (*p) ) {
448
486
  case 32: goto tr30;
449
487
  case 37: goto tr31;
@@ -465,7 +503,7 @@ st21:
465
503
  if ( ++p == pe )
466
504
  goto _out21;
467
505
  case 21:
468
- #line 469 "parser.c"
506
+ #line 507 "parser.c"
469
507
  switch( (*p) ) {
470
508
  case 32: goto tr30;
471
509
  case 37: goto st22;
@@ -487,7 +525,7 @@ st22:
487
525
  if ( ++p == pe )
488
526
  goto _out22;
489
527
  case 22:
490
- #line 491 "parser.c"
528
+ #line 529 "parser.c"
491
529
  if ( (*p) < 65 ) {
492
530
  if ( 48 <= (*p) && (*p) <= 57 )
493
531
  goto st23;
@@ -518,7 +556,7 @@ st24:
518
556
  if ( ++p == pe )
519
557
  goto _out24;
520
558
  case 24:
521
- #line 522 "parser.c"
559
+ #line 560 "parser.c"
522
560
  switch( (*p) ) {
523
561
  case 43: goto st24;
524
562
  case 58: goto st25;
@@ -543,7 +581,7 @@ st25:
543
581
  if ( ++p == pe )
544
582
  goto _out25;
545
583
  case 25:
546
- #line 547 "parser.c"
584
+ #line 585 "parser.c"
547
585
  switch( (*p) ) {
548
586
  case 32: goto tr8;
549
587
  case 34: goto st0;
@@ -590,7 +628,7 @@ st28:
590
628
  if ( ++p == pe )
591
629
  goto _out28;
592
630
  case 28:
593
- #line 594 "parser.c"
631
+ #line 632 "parser.c"
594
632
  switch( (*p) ) {
595
633
  case 32: goto tr40;
596
634
  case 34: goto st0;
@@ -632,16 +670,18 @@ case 30:
632
670
  goto st28;
633
671
  goto st0;
634
672
  tr43:
635
- #line 53 "parser.rl"
673
+ #line 65 "parser.rl"
636
674
  {
637
- parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
675
+ if (parser->request_path != NULL) {
676
+ parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
677
+ }
638
678
  }
639
679
  goto st31;
640
680
  st31:
641
681
  if ( ++p == pe )
642
682
  goto _out31;
643
683
  case 31:
644
- #line 645 "parser.c"
684
+ #line 685 "parser.c"
645
685
  switch( (*p) ) {
646
686
  case 32: goto tr8;
647
687
  case 34: goto st0;
@@ -682,16 +722,18 @@ case 33:
682
722
  goto st31;
683
723
  goto st0;
684
724
  tr44:
685
- #line 53 "parser.rl"
725
+ #line 65 "parser.rl"
686
726
  {
687
- parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
727
+ if (parser->request_path != NULL) {
728
+ parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
729
+ }
688
730
  }
689
731
  goto st34;
690
732
  st34:
691
733
  if ( ++p == pe )
692
734
  goto _out34;
693
735
  case 34:
694
- #line 695 "parser.c"
736
+ #line 737 "parser.c"
695
737
  switch( (*p) ) {
696
738
  case 32: goto tr51;
697
739
  case 34: goto st0;
@@ -705,14 +747,14 @@ case 34:
705
747
  goto st0;
706
748
  goto tr50;
707
749
  tr50:
708
- #line 44 "parser.rl"
750
+ #line 52 "parser.rl"
709
751
  {MARK(query_start, p); }
710
752
  goto st35;
711
753
  st35:
712
754
  if ( ++p == pe )
713
755
  goto _out35;
714
756
  case 35:
715
- #line 716 "parser.c"
757
+ #line 758 "parser.c"
716
758
  switch( (*p) ) {
717
759
  case 32: goto tr55;
718
760
  case 34: goto st0;
@@ -726,14 +768,14 @@ case 35:
726
768
  goto st0;
727
769
  goto st35;
728
770
  tr53:
729
- #line 44 "parser.rl"
771
+ #line 52 "parser.rl"
730
772
  {MARK(query_start, p); }
731
773
  goto st36;
732
774
  st36:
733
775
  if ( ++p == pe )
734
776
  goto _out36;
735
777
  case 36:
736
- #line 737 "parser.c"
778
+ #line 779 "parser.c"
737
779
  if ( (*p) < 65 ) {
738
780
  if ( 48 <= (*p) && (*p) <= 57 )
739
781
  goto st37;
@@ -1148,7 +1190,7 @@ case 56:
1148
1190
 
1149
1191
  _out: {}
1150
1192
  }
1151
- #line 100 "parser.rl"
1193
+ #line 116 "parser.rl"
1152
1194
 
1153
1195
  parser->cs = cs;
1154
1196
  parser->nread += p - (buffer + off);
@@ -1163,8 +1205,8 @@ case 56:
1163
1205
  if(parser->body_start) {
1164
1206
  /* final \r\n combo encountered so stop right here */
1165
1207
 
1166
- #line 1167 "parser.c"
1167
- #line 114 "parser.rl"
1208
+ #line 1209 "parser.c"
1209
+ #line 130 "parser.rl"
1168
1210
  parser->nread++;
1169
1211
  }
1170
1212
 
@@ -1176,8 +1218,8 @@ int http_parser_finish(http_parser *parser)
1176
1218
  int cs = parser->cs;
1177
1219
 
1178
1220
 
1179
- #line 1180 "parser.c"
1180
- #line 125 "parser.rl"
1221
+ #line 1222 "parser.c"
1222
+ #line 141 "parser.rl"
1181
1223
 
1182
1224
  parser->cs = cs;
1183
1225