puma 1.4.0 → 1.5.0

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

Potentially problematic release.


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

@@ -1,3 +1,8 @@
1
+ language: ruby
2
+
3
+ jdk:
4
+ - oraclejdk7
5
+
1
6
  rvm:
2
7
  - 1.8.7
3
8
  - 1.9.3
@@ -1,3 +1,27 @@
1
+ === 1.5.0 / 2012-07-19
2
+
3
+ * 7 contributers to this release:
4
+ * Christian Mayer
5
+ * Darío Javier Cravero
6
+ * Dirkjan Bussink
7
+ * Gianluca Padovani
8
+ * Santiago Pastorino
9
+ * Thibault Jouan
10
+ * tomykaira
11
+
12
+ * 6 bug fixes:
13
+ * Define RSTRING_NOT_MODIFIED for Rubinius
14
+ * Convert status to integer. Fixes #123
15
+ * Delete pidfile when stopping the server
16
+ * Allow compilation with -Werror=format-security option
17
+ * Fix wrong HTTP version for a HTTP/1.0 request
18
+ * Use String#bytesize instead of String#length
19
+
20
+ * 3 minor features:
21
+ * Added support for setting RACK_ENV via the CLI, config file, and rack app
22
+ * Allow Server#run to run sync. Fixes #111
23
+ * Puma can now run on windows
24
+
1
25
  === 1.4.0 / 2012-06-04
2
26
 
3
27
  * 1 bug fix:
data/README.md CHANGED
@@ -45,7 +45,7 @@ First, make sure Puma is in your Gemfile:
45
45
 
46
46
  Then start your server with the `rails` command:
47
47
 
48
- $ rails s puma
48
+ $ rails s Puma
49
49
 
50
50
  ### Rackup
51
51
 
data/Rakefile CHANGED
@@ -30,7 +30,7 @@ HOE.spec.files -= [".gemtest"]
30
30
 
31
31
  # puma.gemspec
32
32
 
33
- file "#{HOE.spec.name}.gemspec" => ['Rakefile'] do |t|
33
+ file "#{HOE.spec.name}.gemspec" => ['Rakefile', "lib/puma/const.rb"] do |t|
34
34
  puts "Generating #{t.name}"
35
35
  File.open(t.name, 'wb') { |f| f.write HOE.spec.to_ruby }
36
36
  end
@@ -1,9 +1,9 @@
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.");
4
+ #define RAISE_NOT_NULL(T) if(T == NULL) rb_raise(rb_eArgError, "%s", "NULL found for " # T " when shouldn't be.");
5
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);
6
+ #define REQUIRE_TYPE(V, T) if(TYPE(V) != T) rb_raise(rb_eTypeError, "%s", "Wrong argument type for " # V " required " # T);
7
7
  #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
8
8
 
9
9
  #ifdef DEBUG
@@ -2,6 +2,9 @@
2
2
  * Copyright (c) 2005 Zed A. Shaw
3
3
  * You can redistribute it and/or modify it under the same terms as Ruby.
4
4
  */
5
+
6
+ #define RSTRING_NOT_MODIFIED 1
7
+
5
8
  #include "ruby.h"
6
9
  #include "ext_help.h"
7
10
  #include <assert.h>
@@ -38,7 +41,7 @@ static VALUE global_request_path;
38
41
  #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."
39
42
 
40
43
  /** Validates the max length of given input and throws an HttpParserError exception if over. */
41
- #define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR); }
44
+ #define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, "%s", MAX_##N##_LENGTH_ERR); }
42
45
 
43
46
  /** Defines global strings in the init method. */
44
47
  #define DEF_GLOBAL(N, val) global_##N = rb_str_new2(val); rb_global_variable(&global_##N)
@@ -377,7 +380,7 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
377
380
 
378
381
  if(from >= dlen) {
379
382
  rb_free_chars(dptr);
380
- rb_raise(eHttpParserError, "Requested start is after data buffer end.");
383
+ rb_raise(eHttpParserError, "%s", "Requested start is after data buffer end.");
381
384
  } else {
382
385
  http->request = req_hash;
383
386
  http_parser_execute(http, dptr, dlen, from);
@@ -386,7 +389,7 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
386
389
  VALIDATE_MAX_LENGTH(http_parser_nread(http), HEADER);
387
390
 
388
391
  if(http_parser_has_error(http)) {
389
- rb_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
392
+ rb_raise(eHttpParserError, "%s", "Invalid HTTP format, parsing fails.");
390
393
  } else {
391
394
  return INT2FIX(http_parser_nread(http));
392
395
  }
@@ -41,7 +41,7 @@ module Puma
41
41
  when "/stats"
42
42
  b = @server.backlog
43
43
  r = @server.running
44
- return rack_response(200, %Q!{ "backlog": #{b}, "running": #{r} }!)
44
+ return rack_response(200, %Q!{ "backlog": #{b}, "running": #{r} }!)
45
45
  end
46
46
 
47
47
  rack_response 404, "Unsupported action", 'text/plain'
@@ -31,7 +31,6 @@ module Puma
31
31
  @status = nil
32
32
 
33
33
  @restart = false
34
- @temp_status_path = nil
35
34
 
36
35
  @listeners = []
37
36
 
@@ -53,17 +52,10 @@ module Puma
53
52
  remove.each do |k|
54
53
  ENV.delete k
55
54
  end
56
-
57
- ENV['RACK_ENV'] ||= "development"
58
55
  end
59
56
 
60
57
  def restart_on_stop!
61
- if @restart_argv
62
- @restart = true
63
- return true
64
- else
65
- return false
66
- end
58
+ @restart = true
67
59
  end
68
60
 
69
61
  def generate_restart_data
@@ -137,17 +129,16 @@ module Puma
137
129
  end
138
130
  end
139
131
 
140
- # Write +str+ to +@stdout+
132
+ # Delegate +log+ to +@events+
141
133
  #
142
134
  def log(str)
143
- @stdout.puts str
135
+ @events.log str
144
136
  end
145
137
 
146
- # Write +str+ to +@stderr+
138
+ # Delegate +error+ to +@events+
147
139
  #
148
140
  def error(str)
149
- @stderr.puts "ERROR: #{str}"
150
- exit 1
141
+ @events.error str
151
142
  end
152
143
 
153
144
  # Build the OptionParser object to handle the available options.
@@ -220,6 +211,11 @@ module Puma
220
211
  "Default: inferred" do |cmd|
221
212
  @options[:restart_cmd] = cmd
222
213
  end
214
+
215
+ o.on "-e", "--environment ENVIRONMENT",
216
+ "The environment to run the Rack app on (default development)" do |arg|
217
+ @options[:environment] = arg
218
+ end
223
219
  end
224
220
 
225
221
  @parser.banner = "puma <options> <rackup file>"
@@ -241,6 +237,21 @@ module Puma
241
237
  end
242
238
  end
243
239
 
240
+ def set_rack_environment
241
+ # Try the user option first, then the environment variable,
242
+ # finally default to development
243
+
244
+ ENV['RACK_ENV'] = @options[:environment] ||
245
+ ENV['RACK_ENV'] ||
246
+ 'development'
247
+ end
248
+
249
+ def delete_pidfile
250
+ if path = @options[:pidfile]
251
+ File.unlink path
252
+ end
253
+ end
254
+
244
255
  def write_state
245
256
  require 'yaml'
246
257
 
@@ -268,13 +279,12 @@ module Puma
268
279
 
269
280
  @config = Puma::Configuration.new @options
270
281
  @config.load
271
-
272
- @temp_status_path = @options[:control_path_temp]
273
282
  end
274
283
 
275
284
  def graceful_stop(server)
276
285
  log " - Gracefully stopping, waiting for requests to finish"
277
286
  server.stop(true)
287
+ delete_pidfile
278
288
  log " - Goodbye!"
279
289
  end
280
290
 
@@ -284,6 +294,8 @@ module Puma
284
294
  def run
285
295
  parse_options
286
296
 
297
+ set_rack_environment
298
+
287
299
  app = @config.app
288
300
 
289
301
  write_pid
@@ -298,6 +310,7 @@ module Puma
298
310
 
299
311
  log "Puma #{Puma::Const::PUMA_VERSION} starting..."
300
312
  log "* Min threads: #{min_t}, max threads: #{max_t}"
313
+ log "* Environment: #{ENV['RACK_ENV']}"
301
314
 
302
315
  @options[:binds].each do |str|
303
316
  uri = URI.parse str
@@ -419,14 +432,22 @@ module Puma
419
432
  @status = status
420
433
  end
421
434
 
422
- Signal.trap "SIGUSR2" do
423
- @restart = true
424
- server.begin_restart
435
+ begin
436
+ Signal.trap "SIGUSR2" do
437
+ @restart = true
438
+ server.begin_restart
439
+ end
440
+ rescue Exception
441
+ log "*** Sorry signal SIGUSR2 not implemented, restart feature disabled!"
425
442
  end
426
443
 
427
- Signal.trap "SIGTERM" do
428
- log " - Gracefully stopping, waiting for requests to finish"
429
- server.stop false
444
+ begin
445
+ Signal.trap "SIGTERM" do
446
+ log " - Gracefully stopping, waiting for requests to finish"
447
+ server.stop false
448
+ end
449
+ rescue Exception
450
+ log "*** Sorry signal SIGTERM not implemented, gracefully stopping feature disabled!"
430
451
  end
431
452
 
432
453
  log "Use Ctrl-C to stop"
@@ -437,8 +458,6 @@ module Puma
437
458
  graceful_stop server
438
459
  end
439
460
 
440
- File.unlink @temp_status_path if @temp_status_path
441
-
442
461
  if @restart
443
462
  log "* Restarting..."
444
463
  @status.stop true if @status
@@ -448,6 +467,7 @@ module Puma
448
467
 
449
468
  def stop
450
469
  @server.stop(true) if @server
470
+ delete_pidfile
451
471
  end
452
472
  end
453
473
  end
@@ -208,6 +208,11 @@ module Puma
208
208
  def state_path(path)
209
209
  @options[:state] = path.to_s
210
210
  end
211
+
212
+ # Set the environment in which the Rack's app will run.
213
+ def environment(environment)
214
+ @options[:environment] = environment
215
+ end
211
216
  end
212
217
  end
213
218
  end
@@ -25,7 +25,7 @@ module Puma
25
25
  # too taxing on performance.
26
26
  module Const
27
27
 
28
- PUMA_VERSION = VERSION = "1.4.0".freeze
28
+ PUMA_VERSION = VERSION = "1.5.0".freeze
29
29
 
30
30
  # The default number of seconds for another request within a persistent
31
31
  # session.
@@ -20,6 +20,19 @@ module Puma
20
20
 
21
21
  attr_reader :stdout, :stderr
22
22
 
23
+ # Write +str+ to +@stdout+
24
+ #
25
+ def log(str)
26
+ @stdout.puts str
27
+ end
28
+
29
+ # Write +str+ to +@stderr+
30
+ #
31
+ def error(str)
32
+ @stderr.puts "ERROR: #{str}"
33
+ exit 1
34
+ end
35
+
23
36
  # An HTTP parse error has occured.
24
37
  # +server+ is the Server object, +env+ the request, and +error+ a
25
38
  # parsing exception.
@@ -185,10 +185,13 @@ module Puma
185
185
  @thread_pool and @thread_pool.spawned
186
186
  end
187
187
 
188
- # Runs the server. It returns the thread used so you can join it.
189
- # The thread is always available via #thread to be join'd
188
+ # Runs the server.
190
189
  #
191
- def run
190
+ # If +background+ is true (the default) then a thread is spun
191
+ # up in the background to handle requests. Otherwise requests
192
+ # are handled synchronously.
193
+ #
194
+ def run(background=true)
192
195
  BasicSocket.do_not_reverse_lookup = true
193
196
 
194
197
  @status = :run
@@ -201,40 +204,45 @@ module Puma
201
204
  @thread_pool.auto_trim!(@auto_trim_time)
202
205
  end
203
206
 
204
- @thread = Thread.new do
205
- begin
206
- check = @check
207
- sockets = @ios
208
- pool = @thread_pool
209
-
210
- while @status == :run
211
- begin
212
- ios = IO.select sockets
213
- ios.first.each do |sock|
214
- if sock == check
215
- break if handle_check
216
- else
217
- pool << [sock.accept, @envs.fetch(sock, @proto_env)]
218
- end
207
+ if background
208
+ @thread = Thread.new { handle_servers }
209
+ return @thread
210
+ else
211
+ handle_servers
212
+ end
213
+ end
214
+
215
+ def handle_servers
216
+ begin
217
+ check = @check
218
+ sockets = @ios
219
+ pool = @thread_pool
220
+
221
+ while @status == :run
222
+ begin
223
+ ios = IO.select sockets
224
+ ios.first.each do |sock|
225
+ if sock == check
226
+ break if handle_check
227
+ else
228
+ pool << [sock.accept, @envs.fetch(sock, @proto_env)]
219
229
  end
220
- rescue Errno::ECONNABORTED
221
- # client closed the socket even before accept
222
- client.close rescue nil
223
- rescue Object => e
224
- @events.unknown_error self, e, "Listen loop"
225
230
  end
231
+ rescue Errno::ECONNABORTED
232
+ # client closed the socket even before accept
233
+ client.close rescue nil
234
+ rescue Object => e
235
+ @events.unknown_error self, e, "Listen loop"
226
236
  end
237
+ end
227
238
 
228
- graceful_shutdown if @status == :stop
229
- ensure
230
- unless @status == :restart
231
- @ios.each { |i| i.close }
232
- @unix_paths.each { |i| File.unlink i }
233
- end
239
+ graceful_shutdown if @status == :stop
240
+ ensure
241
+ unless @status == :restart
242
+ @ios.each { |i| i.close }
243
+ @unix_paths.each { |i| File.unlink i }
234
244
  end
235
245
  end
236
-
237
- return @thread
238
246
  end
239
247
 
240
248
  # :nodoc:
@@ -279,7 +287,7 @@ module Puma
279
287
  # a problem with the read operation on the client socket.
280
288
  # Effect is to stop processing when the socket can't fill the buffer
281
289
  # for further parsing.
282
- while nparsed < data.length
290
+ while nparsed < data.bytesize
283
291
  nparsed = parser.execute(env, data, nparsed)
284
292
 
285
293
  if parser.finished?
@@ -313,7 +321,7 @@ module Puma
313
321
  return if !chunk or chunk.length == 0 # read failed, stop processing
314
322
 
315
323
  data << chunk
316
- if data.length >= MAX_HEADER
324
+ if data.bytesize >= MAX_HEADER
317
325
  raise HttpParserError,
318
326
  "HEADER is longer than allowed, aborting client early."
319
327
  end
@@ -418,6 +426,7 @@ module Puma
418
426
  begin
419
427
  begin
420
428
  status, headers, res_body = @app.call(env)
429
+ status = status.to_i
421
430
 
422
431
  if status == -1
423
432
  unless headers.empty? and res_body == []
@@ -471,7 +480,7 @@ module Puma
471
480
  if status == 200
472
481
  client.write HTTP_10_200
473
482
  else
474
- client.write "HTTP/1.1 "
483
+ client.write "HTTP/1.0 "
475
484
  client.write status.to_s
476
485
  client.write " "
477
486
  client.write HTTP_STATUS_CODES[status]
@@ -53,15 +53,17 @@ module Puma
53
53
  @spawned += 1
54
54
 
55
55
  th = Thread.new do
56
- todo = @todo
56
+ todo = @todo
57
57
  block = @block
58
+ mutex = @mutex
59
+ cond = @cond
58
60
 
59
61
  while true
60
62
  work = nil
61
63
 
62
64
  continue = true
63
65
 
64
- @mutex.synchronize do
66
+ mutex.synchronize do
65
67
  while todo.empty?
66
68
  if @trim_requested > 0
67
69
  @trim_requested -= 1
@@ -75,7 +77,7 @@ module Puma
75
77
  end
76
78
 
77
79
  @waiting += 1
78
- @cond.wait @mutex
80
+ cond.wait mutex
79
81
  @waiting -= 1
80
82
 
81
83
  if @shutdown
@@ -92,7 +94,7 @@ module Puma
92
94
  block.call work
93
95
  end
94
96
 
95
- @mutex.synchronize do
97
+ mutex.synchronize do
96
98
  @spawned -= 1
97
99
  @workers.delete th
98
100
  end
@@ -18,11 +18,16 @@ module Rack
18
18
  app = Rack::CommonLogger.new(app, STDOUT)
19
19
  end
20
20
 
21
+ if options[:environment]
22
+ ENV['RACK_ENV'] = options[:environment].to_s
23
+ end
24
+
21
25
  server = ::Puma::Server.new(app)
22
26
  min, max = options[:Threads].split(':', 2)
23
27
 
24
28
  puts "Puma #{::Puma::Const::PUMA_VERSION} starting..."
25
29
  puts "* Min threads: #{min}, max threads: #{max}"
30
+ puts "* Environment: #{ENV['RACK_ENV']}"
26
31
  puts "* Listening on tcp://#{options[:Host]}:#{options[:Port]}"
27
32
 
28
33
  server.add_tcp_listener options[:Host], options[:Port]
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "puma"
5
- s.version = "1.3.1"
5
+ s.version = "1.5.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Evan Phoenix"]
9
- s.date = "2012-05-16"
9
+ s.date = "2012-07-19"
10
10
  s.description = "Puma is a simple, fast, and highly concurrent HTTP 1.1 server for Ruby web applications. It can be used with any application that supports Rack, and is considered the replacement for Webrick and Mongrel. It was designed to be the go-to server for [Rubinius](http://rubini.us), but also works well with JRuby and MRI. Puma is intended for use in both development and production environments.\n\nUnder the hood, Puma processes requests using a C-optimized Ragel extension (inherited from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable way. Puma then serves the request in a thread from an internal thread pool (which you can control). This allows Puma to provide real concurrency for your web application!\n\nWith Rubinius 2.0, Puma will utilize all cores on your CPU with real threads, meaning you won't have to spawn multiple processes to increase throughput. You can expect to see a similar benefit from JRuby.\n\nOn MRI, there is a Global Interpreter Lock (GIL) that ensures only one thread can be run at a time. But if you're doing a lot of blocking IO (such as HTTP calls to external APIs like Twitter), Puma still improves MRI's throughput by allowing blocking IO to be run concurrently (EventMachine-based servers such as Thin turn off this ability, requiring you to use special libraries). Your mileage may vary. In order to get the best throughput, it is highly recommended that you use a Ruby implementation with real threads like [Rubinius](http://rubini.us) or [JRuby](http://jruby.org)."
11
11
  s.email = ["evan@phx.io"]
12
12
  s.executables = ["puma", "pumactl"]
@@ -28,79 +28,57 @@ class TestAppStatus < Test::Unit::TestCase
28
28
  @app.auth_token = nil
29
29
  end
30
30
 
31
- def lint(env)
31
+ def lint(uri)
32
32
  app = Rack::Lint.new @app
33
- mock_env = Rack::MockRequest.env_for env['PATH_INFO']
33
+ mock_env = Rack::MockRequest.env_for uri
34
34
  app.call mock_env
35
35
  end
36
36
 
37
37
  def test_bad_token
38
38
  @app.auth_token = "abcdef"
39
39
 
40
- env = { 'PATH_INFO' => "/whatever" }
41
-
42
- status, _, _ = @app.call env
40
+ status, _, _ = lint('/whatever')
43
41
 
44
42
  assert_equal 403, status
45
- lint(env)
46
43
  end
47
44
 
48
45
  def test_good_token
49
46
  @app.auth_token = "abcdef"
50
47
 
51
- env = {
52
- 'PATH_INFO' => "/whatever",
53
- 'QUERY_STRING' => "token=abcdef"
54
- }
55
-
56
- status, _, _ = @app.call env
48
+ status, _, _ = lint('/whatever?token=abcdef')
57
49
 
58
50
  assert_equal 404, status
59
- lint(env)
60
51
  end
61
52
 
62
53
  def test_unsupported
63
- env = { 'PATH_INFO' => "/not-real" }
64
-
65
- status, _, _ = @app.call env
54
+ status, _, _ = lint('/not-real')
66
55
 
67
56
  assert_equal 404, status
68
- lint(env)
69
57
  end
70
58
 
71
59
  def test_stop
72
- env = { 'PATH_INFO' => "/stop" }
73
-
74
- status, _ , body = @app.call env
60
+ status, _ , app = lint('/stop')
75
61
 
76
62
  assert_equal :stop, @server.status
77
63
  assert_equal 200, status
78
- assert_equal ['{ "status": "ok" }'], body
79
- lint(env)
64
+ assert_equal ['{ "status": "ok" }'], app.enum_for.to_a
80
65
  end
81
66
 
82
67
  def test_halt
83
- env = { 'PATH_INFO' => "/halt" }
84
-
85
- status, _ , body = @app.call env
68
+ status, _ , app = lint('/halt')
86
69
 
87
70
  assert_equal :halt, @server.status
88
71
  assert_equal 200, status
89
- assert_equal ['{ "status": "ok" }'], body
90
- lint(env)
72
+ assert_equal ['{ "status": "ok" }'], app.enum_for.to_a
91
73
  end
92
74
 
93
75
  def test_stats
94
- env = { 'PATH_INFO' => "/stats" }
95
-
96
76
  @server.backlog = 1
97
77
  @server.running = 9
98
78
 
99
- status, _ , body = @app.call env
79
+ status, _ , app = lint('/stats')
100
80
 
101
81
  assert_equal 200, status
102
- assert_equal ['{ "backlog": 1, "running": 9 }'], body
103
- lint(env)
82
+ assert_equal ['{ "backlog": 1, "running": 9 }'], app.enum_for.to_a
104
83
  end
105
-
106
84
  end
@@ -5,6 +5,7 @@ require 'tempfile'
5
5
 
6
6
  class TestCLI < Test::Unit::TestCase
7
7
  def setup
8
+ @environment = 'production'
8
9
  @tmp_file = Tempfile.new("puma-test")
9
10
  @tmp_path = @tmp_file.path
10
11
  @tmp_file.close!
@@ -26,6 +27,40 @@ class TestCLI < Test::Unit::TestCase
26
27
  cli.write_pid
27
28
 
28
29
  assert_equal File.read(@tmp_path).strip.to_i, Process.pid
30
+
31
+ cli.stop
32
+ assert !File.exist?(@tmp_path), "Pid file shouldn't exist anymore"
33
+ end
34
+
35
+ def test_control_for_tcp
36
+ url = "tcp://127.0.0.1:9877/"
37
+ sin = StringIO.new
38
+ sout = StringIO.new
39
+ cli = Puma::CLI.new ["-b", "tcp://127.0.0.1:9876",
40
+ "--control", url,
41
+ "--control-token", "",
42
+ "test/lobster.ru"], sin, sout
43
+ cli.parse_options
44
+
45
+ thread_exception = nil
46
+ t = Thread.new do
47
+ begin
48
+ cli.run
49
+ rescue Exception => e
50
+ thread_exception = e
51
+ end
52
+ end
53
+
54
+ sleep 1
55
+
56
+ s = TCPSocket.new "127.0.0.1", 9877
57
+ s << "GET /stats HTTP/1.0\r\n\r\n"
58
+ body = s.read
59
+ assert_equal '{ "backlog": 0, "running": 0 }', body.split("\r\n").last
60
+
61
+ cli.stop
62
+ t.join
63
+ assert_equal nil, thread_exception
29
64
  end
30
65
 
31
66
  unless defined?(JRUBY_VERSION) || RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
@@ -125,4 +160,12 @@ class TestCLI < Test::Unit::TestCase
125
160
  assert_equal 'baz/qux', $LOAD_PATH[0]
126
161
  $LOAD_PATH.shift
127
162
  end
163
+
164
+ def test_environment
165
+ cli = Puma::CLI.new ["--environment", @environment]
166
+ cli.parse_options
167
+ cli.set_rack_environment
168
+
169
+ assert_equal ENV['RACK_ENV'], @environment
170
+ end
128
171
  end
@@ -66,7 +66,7 @@ class TestRackServer < Test::Unit::TestCase
66
66
 
67
67
  @server.run
68
68
 
69
- hit(['http://localhost:9998/test'])
69
+ hit(['http://127.0.0.1:9998/test'])
70
70
 
71
71
  stop
72
72
 
@@ -83,7 +83,7 @@ class TestRackServer < Test::Unit::TestCase
83
83
 
84
84
  big = "x" * (1024 * 16)
85
85
 
86
- Net::HTTP.post_form URI.parse('http://localhost:9998/test'),
86
+ Net::HTTP.post_form URI.parse('http://127.0.0.1:9998/test'),
87
87
  { "big" => big }
88
88
 
89
89
  stop
@@ -98,7 +98,7 @@ class TestRackServer < Test::Unit::TestCase
98
98
  @server.app = lambda { |env| input = env; @simple.call(env) }
99
99
  @server.run
100
100
 
101
- hit(['http://localhost:9998/test/a/b/c'])
101
+ hit(['http://127.0.0.1:9998/test/a/b/c'])
102
102
 
103
103
  stop
104
104
 
@@ -115,7 +115,7 @@ class TestRackServer < Test::Unit::TestCase
115
115
 
116
116
  @server.run
117
117
 
118
- hit(['http://localhost:9998/test'])
118
+ hit(['http://127.0.0.1:9998/test'])
119
119
 
120
120
  stop
121
121
 
@@ -131,7 +131,7 @@ class TestRackServer < Test::Unit::TestCase
131
131
 
132
132
  @server.run
133
133
 
134
- hit(['http://localhost:9998/test'])
134
+ hit(['http://127.0.0.1:9998/test'])
135
135
 
136
136
  stop
137
137
 
@@ -25,19 +25,15 @@ class WebServerTest < Test::Unit::TestCase
25
25
  @server = Server.new @tester, Events.strings
26
26
  @server.add_tcp_listener "127.0.0.1", 9998
27
27
 
28
- redirect_test_io do
29
- @server.run
30
- end
28
+ @server.run
31
29
  end
32
30
 
33
31
  def teardown
34
- redirect_test_io do
35
- @server.stop(true)
36
- end
32
+ @server.stop(true)
37
33
  end
38
34
 
39
35
  def test_simple_server
40
- hit(['http://localhost:9998/test'])
36
+ hit(['http://127.0.0.1:9998/test'])
41
37
  assert @tester.ran_test, "Handler didn't really run"
42
38
  end
43
39
 
@@ -73,17 +69,13 @@ class WebServerTest < Test::Unit::TestCase
73
69
  end
74
70
 
75
71
  def test_bad_client
76
- redirect_test_io do
77
- do_test("GET /test HTTP/BAD", 3)
78
- end
72
+ do_test("GET /test HTTP/BAD", 3)
79
73
  end
80
74
 
81
75
  def test_header_is_too_long
82
- redirect_test_io do
83
- long = "GET /test HTTP/1.1\r\n" + ("X-Big: stuff\r\n" * 15000) + "\r\n"
84
- assert_raises Errno::ECONNRESET, Errno::EPIPE, Errno::ECONNABORTED, Errno::EINVAL, IOError do
85
- do_test(long, long.length/2, 10)
86
- end
76
+ long = "GET /test HTTP/1.1\r\n" + ("X-Big: stuff\r\n" * 15000) + "\r\n"
77
+ assert_raises Errno::ECONNRESET, Errno::EPIPE, Errno::ECONNABORTED, Errno::EINVAL, IOError do
78
+ do_test(long, long.length/2, 10)
87
79
  end
88
80
  end
89
81
 
@@ -16,10 +16,6 @@ require 'stringio'
16
16
 
17
17
  require 'puma'
18
18
 
19
- def redirect_test_io
20
- yield
21
- end
22
-
23
19
  # Either takes a string to do a get request against, or a tuple of [URI, HTTP] where
24
20
  # HTTP is some kind of Net::HTTP request object (POST, HEAD, etc.)
25
21
  def hit(uris)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 4
8
+ - 5
9
9
  - 0
10
- version: 1.4.0
10
+ version: 1.5.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Evan Phoenix
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-06-04 00:00:00 Z
18
+ date: 2012-07-19 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rack
@@ -198,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
198
  requirements: []
199
199
 
200
200
  rubyforge_project: puma
201
- rubygems_version: 1.8.22
201
+ rubygems_version: 1.8.18
202
202
  signing_key:
203
203
  specification_version: 3
204
204
  summary: Puma is a simple, fast, and highly concurrent HTTP 1.1 server for Ruby web applications