puma 2.11.1 → 2.11.2
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.
- checksums.yaml +4 -4
- data/History.txt +23 -0
- data/Manifest.txt +1 -0
- data/lib/puma/cli.rb +269 -303
- data/lib/puma/cluster.rb +1 -0
- data/lib/puma/configuration.rb +62 -328
- data/lib/puma/const.rb +1 -1
- data/lib/puma/dsl.rb +280 -0
- data/lib/puma/server.rb +24 -7
- data/puma.gemspec +1 -1
- metadata +4 -39
- data/test/test_app_status.rb +0 -92
- data/test/test_cli.rb +0 -173
- data/test/test_config.rb +0 -26
- data/test/test_http10.rb +0 -27
- data/test/test_http11.rb +0 -144
- data/test/test_integration.rb +0 -206
- data/test/test_iobuffer.rb +0 -38
- data/test/test_minissl.rb +0 -29
- data/test/test_null_io.rb +0 -31
- data/test/test_persistent.rb +0 -238
- data/test/test_puma_server.rb +0 -288
- data/test/test_puma_server_ssl.rb +0 -137
- data/test/test_rack_handler.rb +0 -10
- data/test/test_rack_server.rb +0 -141
- data/test/test_tcp_rack.rb +0 -42
- data/test/test_thread_pool.rb +0 -182
- data/test/test_unix_socket.rb +0 -39
- data/test/test_ws.rb +0 -89
data/test/test_cli.rb
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
require "rbconfig"
|
2
|
-
require 'test/unit'
|
3
|
-
require 'puma/cli'
|
4
|
-
require 'tempfile'
|
5
|
-
|
6
|
-
class TestCLI < Test::Unit::TestCase
|
7
|
-
def setup
|
8
|
-
@environment = 'production'
|
9
|
-
@tmp_file = Tempfile.new("puma-test")
|
10
|
-
@tmp_path = @tmp_file.path
|
11
|
-
@tmp_file.close!
|
12
|
-
|
13
|
-
@tmp_path2 = "#{@tmp_path}2"
|
14
|
-
|
15
|
-
File.unlink @tmp_path if File.exist? @tmp_path
|
16
|
-
File.unlink @tmp_path2 if File.exist? @tmp_path2
|
17
|
-
|
18
|
-
@wait, @ready = IO.pipe
|
19
|
-
|
20
|
-
@events = Events.strings
|
21
|
-
@events.on_booted { @ready << "!" }
|
22
|
-
end
|
23
|
-
|
24
|
-
def wait_booted
|
25
|
-
@wait.sysread 1
|
26
|
-
end
|
27
|
-
|
28
|
-
def teardown
|
29
|
-
File.unlink @tmp_path if File.exist? @tmp_path
|
30
|
-
File.unlink @tmp_path2 if File.exist? @tmp_path2
|
31
|
-
|
32
|
-
@wait.close
|
33
|
-
@ready.close
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_pid_file
|
37
|
-
cli = Puma::CLI.new ["--pidfile", @tmp_path]
|
38
|
-
cli.parse_options
|
39
|
-
cli.write_pid
|
40
|
-
|
41
|
-
assert_equal File.read(@tmp_path).strip.to_i, Process.pid
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_control_for_tcp
|
45
|
-
url = "tcp://127.0.0.1:9877/"
|
46
|
-
cli = Puma::CLI.new ["-b", "tcp://127.0.0.1:9876",
|
47
|
-
"--control", url,
|
48
|
-
"--control-token", "",
|
49
|
-
"test/lobster.ru"], @events
|
50
|
-
|
51
|
-
cli.parse_options
|
52
|
-
|
53
|
-
thread_exception = nil
|
54
|
-
t = Thread.new do
|
55
|
-
begin
|
56
|
-
cli.run
|
57
|
-
rescue Exception => e
|
58
|
-
thread_exception = e
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
wait_booted
|
63
|
-
|
64
|
-
s = TCPSocket.new "127.0.0.1", 9877
|
65
|
-
s << "GET /stats HTTP/1.0\r\n\r\n"
|
66
|
-
body = s.read
|
67
|
-
assert_equal '{ "backlog": 0, "running": 0 }', body.split("\r\n").last
|
68
|
-
|
69
|
-
cli.stop
|
70
|
-
t.join
|
71
|
-
assert_equal nil, thread_exception
|
72
|
-
end
|
73
|
-
|
74
|
-
unless defined?(JRUBY_VERSION) || RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
|
75
|
-
def test_control
|
76
|
-
url = "unix://#{@tmp_path}"
|
77
|
-
|
78
|
-
cli = Puma::CLI.new ["-b", "unix://#{@tmp_path2}",
|
79
|
-
"--control", url,
|
80
|
-
"--control-token", "",
|
81
|
-
"test/lobster.ru"], @events
|
82
|
-
cli.parse_options
|
83
|
-
|
84
|
-
t = Thread.new { cli.run }
|
85
|
-
|
86
|
-
wait_booted
|
87
|
-
|
88
|
-
s = UNIXSocket.new @tmp_path
|
89
|
-
s << "GET /stats HTTP/1.0\r\n\r\n"
|
90
|
-
body = s.read
|
91
|
-
|
92
|
-
assert_equal '{ "backlog": 0, "running": 0 }', body.split("\r\n").last
|
93
|
-
|
94
|
-
cli.stop
|
95
|
-
t.join
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_control_stop
|
99
|
-
url = "unix://#{@tmp_path}"
|
100
|
-
|
101
|
-
cli = Puma::CLI.new ["-b", "unix://#{@tmp_path2}",
|
102
|
-
"--control", url,
|
103
|
-
"--control-token", "",
|
104
|
-
"test/lobster.ru"], @events
|
105
|
-
cli.parse_options
|
106
|
-
|
107
|
-
t = Thread.new { cli.run }
|
108
|
-
|
109
|
-
wait_booted
|
110
|
-
|
111
|
-
s = UNIXSocket.new @tmp_path
|
112
|
-
s << "GET /stop HTTP/1.0\r\n\r\n"
|
113
|
-
body = s.read
|
114
|
-
|
115
|
-
assert_equal '{ "status": "ok" }', body.split("\r\n").last
|
116
|
-
|
117
|
-
t.join
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_tmp_control
|
121
|
-
url = "tcp://127.0.0.1:8232"
|
122
|
-
cli = Puma::CLI.new ["--state", @tmp_path, "--control", "auto"]
|
123
|
-
cli.parse_options
|
124
|
-
cli.write_state
|
125
|
-
|
126
|
-
data = YAML.load File.read(@tmp_path)
|
127
|
-
|
128
|
-
assert_equal Process.pid, data["pid"]
|
129
|
-
|
130
|
-
url = data["config"].options[:control_url]
|
131
|
-
|
132
|
-
m = %r!unix://(.*)!.match(url)
|
133
|
-
|
134
|
-
assert m, "'#{url}' is not a URL"
|
135
|
-
end
|
136
|
-
end # JRUBY or Windows
|
137
|
-
|
138
|
-
def test_state
|
139
|
-
url = "tcp://127.0.0.1:8232"
|
140
|
-
cli = Puma::CLI.new ["--state", @tmp_path, "--control", url]
|
141
|
-
cli.parse_options
|
142
|
-
cli.write_state
|
143
|
-
|
144
|
-
data = YAML.load File.read(@tmp_path)
|
145
|
-
|
146
|
-
assert_equal Process.pid, data["pid"]
|
147
|
-
assert_equal url, data["config"].options[:control_url]
|
148
|
-
end
|
149
|
-
|
150
|
-
def test_load_path
|
151
|
-
cli = Puma::CLI.new ["--include", 'foo/bar']
|
152
|
-
cli.parse_options
|
153
|
-
|
154
|
-
assert_equal 'foo/bar', $LOAD_PATH[0]
|
155
|
-
$LOAD_PATH.shift
|
156
|
-
|
157
|
-
cli = Puma::CLI.new ["--include", 'foo/bar:baz/qux']
|
158
|
-
cli.parse_options
|
159
|
-
|
160
|
-
assert_equal 'foo/bar', $LOAD_PATH[0]
|
161
|
-
$LOAD_PATH.shift
|
162
|
-
assert_equal 'baz/qux', $LOAD_PATH[0]
|
163
|
-
$LOAD_PATH.shift
|
164
|
-
end
|
165
|
-
|
166
|
-
def test_environment
|
167
|
-
cli = Puma::CLI.new ["--environment", @environment]
|
168
|
-
cli.parse_options
|
169
|
-
cli.set_rack_environment
|
170
|
-
|
171
|
-
assert_equal ENV['RACK_ENV'], @environment
|
172
|
-
end
|
173
|
-
end
|
data/test/test_config.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
require 'puma'
|
4
|
-
require 'puma/configuration'
|
5
|
-
|
6
|
-
class TestConfigFile < Test::Unit::TestCase
|
7
|
-
def test_app_from_app_DSL
|
8
|
-
opts = { :config_file => "test/config/app.rb" }
|
9
|
-
conf = Puma::Configuration.new opts
|
10
|
-
conf.load
|
11
|
-
|
12
|
-
app = conf.app
|
13
|
-
|
14
|
-
assert_equal [200, {}, ["embedded app"]], app.call({})
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_lowleve_error_handler_DSL
|
18
|
-
opts = { :config_file => "test/config/app.rb" }
|
19
|
-
conf = Puma::Configuration.new opts
|
20
|
-
conf.load
|
21
|
-
|
22
|
-
app = conf.options[:lowlevel_error_handler]
|
23
|
-
|
24
|
-
assert_equal [200, {}, ["error page"]], app.call({})
|
25
|
-
end
|
26
|
-
end
|
data/test/test_http10.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'test/testhelp'
|
2
|
-
|
3
|
-
class Http10ParserTest < Test::Unit::TestCase
|
4
|
-
include Puma
|
5
|
-
|
6
|
-
def test_parse_simple
|
7
|
-
parser = HttpParser.new
|
8
|
-
req = {}
|
9
|
-
http = "GET / HTTP/1.0\r\n\r\n"
|
10
|
-
nread = parser.execute(req, http, 0)
|
11
|
-
|
12
|
-
assert nread == http.length, "Failed to parse the full HTTP request"
|
13
|
-
assert parser.finished?, "Parser didn't finish"
|
14
|
-
assert !parser.error?, "Parser had error"
|
15
|
-
assert nread == parser.nread, "Number read returned from execute does not match"
|
16
|
-
|
17
|
-
assert_equal '/', req['REQUEST_PATH']
|
18
|
-
assert_equal 'HTTP/1.0', req['HTTP_VERSION']
|
19
|
-
assert_equal '/', req['REQUEST_URI']
|
20
|
-
assert_equal 'GET', req['REQUEST_METHOD']
|
21
|
-
assert_nil req['FRAGMENT']
|
22
|
-
assert_nil req['QUERY_STRING']
|
23
|
-
|
24
|
-
parser.reset
|
25
|
-
assert parser.nread == 0, "Number read after reset should be 0"
|
26
|
-
end
|
27
|
-
end
|
data/test/test_http11.rb
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
# Copyright (c) 2011 Evan Phoenix
|
2
|
-
# Copyright (c) 2005 Zed A. Shaw
|
3
|
-
|
4
|
-
require 'testhelp'
|
5
|
-
|
6
|
-
include Puma
|
7
|
-
|
8
|
-
class Http11ParserTest < Test::Unit::TestCase
|
9
|
-
|
10
|
-
def test_parse_simple
|
11
|
-
parser = HttpParser.new
|
12
|
-
req = {}
|
13
|
-
http = "GET / HTTP/1.1\r\n\r\n"
|
14
|
-
nread = parser.execute(req, http, 0)
|
15
|
-
|
16
|
-
assert nread == http.length, "Failed to parse the full HTTP request"
|
17
|
-
assert parser.finished?, "Parser didn't finish"
|
18
|
-
assert !parser.error?, "Parser had error"
|
19
|
-
assert nread == parser.nread, "Number read returned from execute does not match"
|
20
|
-
|
21
|
-
assert_equal '/', req['REQUEST_PATH']
|
22
|
-
assert_equal 'HTTP/1.1', req['HTTP_VERSION']
|
23
|
-
assert_equal '/', req['REQUEST_URI']
|
24
|
-
assert_equal 'GET', req['REQUEST_METHOD']
|
25
|
-
assert_nil req['FRAGMENT']
|
26
|
-
assert_nil req['QUERY_STRING']
|
27
|
-
|
28
|
-
parser.reset
|
29
|
-
assert parser.nread == 0, "Number read after reset should be 0"
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_parse_dumbfuck_headers
|
33
|
-
parser = HttpParser.new
|
34
|
-
req = {}
|
35
|
-
should_be_good = "GET / HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n"
|
36
|
-
nread = parser.execute(req, should_be_good, 0)
|
37
|
-
assert_equal should_be_good.length, nread
|
38
|
-
assert parser.finished?
|
39
|
-
assert !parser.error?
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_parse_error
|
43
|
-
parser = HttpParser.new
|
44
|
-
req = {}
|
45
|
-
bad_http = "GET / SsUTF/1.1"
|
46
|
-
|
47
|
-
error = false
|
48
|
-
begin
|
49
|
-
parser.execute(req, bad_http, 0)
|
50
|
-
rescue
|
51
|
-
error = true
|
52
|
-
end
|
53
|
-
|
54
|
-
assert error, "failed to throw exception"
|
55
|
-
assert !parser.finished?, "Parser shouldn't be finished"
|
56
|
-
assert parser.error?, "Parser SHOULD have error"
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_fragment_in_uri
|
60
|
-
parser = HttpParser.new
|
61
|
-
req = {}
|
62
|
-
get = "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n"
|
63
|
-
assert_nothing_raised do
|
64
|
-
parser.execute(req, get, 0)
|
65
|
-
end
|
66
|
-
assert parser.finished?
|
67
|
-
assert_equal '/forums/1/topics/2375?page=1', req['REQUEST_URI']
|
68
|
-
assert_equal 'posts-17408', req['FRAGMENT']
|
69
|
-
end
|
70
|
-
|
71
|
-
# lame random garbage maker
|
72
|
-
def rand_data(min, max, readable=true)
|
73
|
-
count = min + ((rand(max)+1) *10).to_i
|
74
|
-
res = count.to_s + "/"
|
75
|
-
|
76
|
-
if readable
|
77
|
-
res << Digest::SHA1.hexdigest(rand(count * 100).to_s) * (count / 40)
|
78
|
-
else
|
79
|
-
res << Digest::SHA1.digest(rand(count * 100).to_s) * (count / 20)
|
80
|
-
end
|
81
|
-
|
82
|
-
return res
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_max_uri_path_length
|
86
|
-
parser = HttpParser.new
|
87
|
-
req = {}
|
88
|
-
|
89
|
-
# Support URI path length to a max of 2048
|
90
|
-
path = "/" + rand_data(1000, 100)
|
91
|
-
http = "GET #{path} HTTP/1.1\r\n\r\n"
|
92
|
-
parser.execute(req, http, 0)
|
93
|
-
assert_equal path, req['REQUEST_PATH']
|
94
|
-
parser.reset
|
95
|
-
|
96
|
-
# Raise exception if URI path length > 2048
|
97
|
-
path = "/" + rand_data(2049, 100)
|
98
|
-
http = "GET #{path} HTTP/1.1\r\n\r\n"
|
99
|
-
assert_raises Puma::HttpParserError do
|
100
|
-
parser.execute(req, http, 0)
|
101
|
-
parser.reset
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def test_horrible_queries
|
106
|
-
parser = HttpParser.new
|
107
|
-
|
108
|
-
# then that large header names are caught
|
109
|
-
10.times do |c|
|
110
|
-
get = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-#{rand_data(1024, 1024+(c*1024))}: Test\r\n\r\n"
|
111
|
-
assert_raises Puma::HttpParserError do
|
112
|
-
parser.execute({}, get, 0)
|
113
|
-
parser.reset
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
# then that large mangled field values are caught
|
118
|
-
10.times do |c|
|
119
|
-
get = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-Test: #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
|
120
|
-
assert_raises Puma::HttpParserError do
|
121
|
-
parser.execute({}, get, 0)
|
122
|
-
parser.reset
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
# then large headers are rejected too
|
127
|
-
get = "GET /#{rand_data(10,120)} HTTP/1.1\r\n"
|
128
|
-
get << "X-Test: test\r\n" * (80 * 1024)
|
129
|
-
assert_raises Puma::HttpParserError do
|
130
|
-
parser.execute({}, get, 0)
|
131
|
-
parser.reset
|
132
|
-
end
|
133
|
-
|
134
|
-
# finally just that random garbage gets blocked all the time
|
135
|
-
10.times do |c|
|
136
|
-
get = "GET #{rand_data(1024, 1024+(c*1024), false)} #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
|
137
|
-
assert_raises Puma::HttpParserError do
|
138
|
-
parser.execute({}, get, 0)
|
139
|
-
parser.reset
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
end
|
144
|
-
end
|
data/test/test_integration.rb
DELETED
@@ -1,206 +0,0 @@
|
|
1
|
-
require "rbconfig"
|
2
|
-
require 'test/unit'
|
3
|
-
require 'socket'
|
4
|
-
require 'timeout'
|
5
|
-
require 'net/http'
|
6
|
-
require 'tempfile'
|
7
|
-
|
8
|
-
require 'puma/cli'
|
9
|
-
require 'puma/control_cli'
|
10
|
-
|
11
|
-
# These don't run on travis because they're too fragile
|
12
|
-
|
13
|
-
class TestIntegration < Test::Unit::TestCase
|
14
|
-
def setup
|
15
|
-
@state_path = "test/test_puma.state"
|
16
|
-
@bind_path = "test/test_server.sock"
|
17
|
-
@control_path = "test/test_control.sock"
|
18
|
-
@tcp_port = 9998
|
19
|
-
|
20
|
-
@server = nil
|
21
|
-
@script = nil
|
22
|
-
|
23
|
-
@wait, @ready = IO.pipe
|
24
|
-
|
25
|
-
@events = Puma::Events.strings
|
26
|
-
@events.on_booted { @ready << "!" }
|
27
|
-
end
|
28
|
-
|
29
|
-
def teardown
|
30
|
-
File.unlink @state_path rescue nil
|
31
|
-
File.unlink @bind_path rescue nil
|
32
|
-
File.unlink @control_path rescue nil
|
33
|
-
|
34
|
-
@wait.close
|
35
|
-
@ready.close
|
36
|
-
|
37
|
-
if @server
|
38
|
-
Process.kill "INT", @server.pid
|
39
|
-
begin
|
40
|
-
Process.wait @server.pid
|
41
|
-
rescue Errno::ECHILD
|
42
|
-
end
|
43
|
-
|
44
|
-
@server.close
|
45
|
-
end
|
46
|
-
|
47
|
-
if @script
|
48
|
-
@script.close!
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def server(opts)
|
53
|
-
core = "#{Gem.ruby} -rubygems -Ilib bin/puma"
|
54
|
-
cmd = "#{core} --restart-cmd '#{core}' -b tcp://127.0.0.1:#{@tcp_port} #{opts}"
|
55
|
-
tf = Tempfile.new "puma-test"
|
56
|
-
tf.puts "exec #{cmd}"
|
57
|
-
tf.close
|
58
|
-
|
59
|
-
@script = tf
|
60
|
-
|
61
|
-
@server = IO.popen("sh #{tf.path}", "r")
|
62
|
-
|
63
|
-
true while @server.gets =~ /Ctrl-C/
|
64
|
-
|
65
|
-
sleep 1
|
66
|
-
|
67
|
-
@server
|
68
|
-
end
|
69
|
-
|
70
|
-
def signal(which)
|
71
|
-
Process.kill which, @server.pid
|
72
|
-
end
|
73
|
-
|
74
|
-
def wait_booted
|
75
|
-
@wait.sysread 1
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_stop_via_pumactl
|
79
|
-
if defined?(JRUBY_VERSION) || RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
|
80
|
-
assert true
|
81
|
-
return
|
82
|
-
end
|
83
|
-
|
84
|
-
cli = Puma::CLI.new %W!-q -S #{@state_path} -b unix://#{@bind_path} --control unix://#{@control_path} test/hello.ru!, @events
|
85
|
-
|
86
|
-
t = Thread.new do
|
87
|
-
cli.run
|
88
|
-
end
|
89
|
-
|
90
|
-
wait_booted
|
91
|
-
|
92
|
-
s = UNIXSocket.new @bind_path
|
93
|
-
s << "GET / HTTP/1.0\r\n\r\n"
|
94
|
-
assert_equal "Hello World", s.read.split("\r\n").last
|
95
|
-
|
96
|
-
sout = StringIO.new
|
97
|
-
|
98
|
-
ccli = Puma::ControlCLI.new %W!-S #{@state_path} stop!, sout
|
99
|
-
|
100
|
-
ccli.run
|
101
|
-
|
102
|
-
assert_kind_of Thread, t.join(1), "server didn't stop"
|
103
|
-
end
|
104
|
-
|
105
|
-
def notest_phased_restart_via_pumactl
|
106
|
-
if defined?(JRUBY_VERSION) || RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
|
107
|
-
assert true
|
108
|
-
return
|
109
|
-
end
|
110
|
-
|
111
|
-
cli = Puma::CLI.new %W!-q -S #{@state_path} -b unix://#{@bind_path} --control unix://#{@control_path} -w 2 test/hello-stuck.ru!, @events
|
112
|
-
cli.options[:worker_shutdown_timeout] = 1
|
113
|
-
|
114
|
-
t = Thread.new do
|
115
|
-
cli.run
|
116
|
-
end
|
117
|
-
|
118
|
-
wait_booted
|
119
|
-
|
120
|
-
# Make both workers stuck
|
121
|
-
s1 = UNIXSocket.new @bind_path
|
122
|
-
s1 << "GET / HTTP/1.0\r\n\r\n"
|
123
|
-
s2 = UNIXSocket.new @bind_path
|
124
|
-
s2 << "GET / HTTP/1.0\r\n\r\n"
|
125
|
-
|
126
|
-
sout = StringIO.new
|
127
|
-
|
128
|
-
# Phased restart
|
129
|
-
ccli = Puma::ControlCLI.new %W!-S #{@state_path} phased-restart!, sout
|
130
|
-
ccli.run
|
131
|
-
sleep 20
|
132
|
-
@events.stdout.rewind
|
133
|
-
log = @events.stdout.readlines.join("")
|
134
|
-
assert_match(/TERM sent/, log)
|
135
|
-
assert_match(/KILL sent/, log)
|
136
|
-
assert_match(/Worker 0 \(pid: \d+\) booted, phase: 1/, log)
|
137
|
-
assert_match(/Worker 1 \(pid: \d+\) booted, phase: 1/, log)
|
138
|
-
|
139
|
-
# Stop
|
140
|
-
ccli = Puma::ControlCLI.new %W!-S #{@state_path} stop!, sout
|
141
|
-
ccli.run
|
142
|
-
|
143
|
-
assert_kind_of Thread, t.join(5), "server didn't stop"
|
144
|
-
end
|
145
|
-
|
146
|
-
def notest_restart_closes_keepalive_sockets
|
147
|
-
server("-q test/hello.ru")
|
148
|
-
|
149
|
-
s = TCPSocket.new "localhost", @tcp_port
|
150
|
-
s << "GET / HTTP/1.1\r\n\r\n"
|
151
|
-
true until s.gets == "\r\n"
|
152
|
-
|
153
|
-
s.readpartial(20)
|
154
|
-
signal :USR2
|
155
|
-
|
156
|
-
true while @server.gets =~ /Ctrl-C/
|
157
|
-
sleep 1
|
158
|
-
|
159
|
-
s.write "GET / HTTP/1.1\r\n\r\n"
|
160
|
-
|
161
|
-
assert_raises Errno::ECONNRESET do
|
162
|
-
Timeout.timeout(2) do
|
163
|
-
raise Errno::ECONNRESET unless s.read(2)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
s = TCPSocket.new "localhost", @tcp_port
|
168
|
-
s << "GET / HTTP/1.0\r\n\r\n"
|
169
|
-
assert_equal "Hello World", s.read.split("\r\n").last
|
170
|
-
end
|
171
|
-
|
172
|
-
def notest_restart_closes_keepalive_sockets_workers
|
173
|
-
server("-q -w 2 test/hello.ru")
|
174
|
-
|
175
|
-
s = TCPSocket.new "localhost", @tcp_port
|
176
|
-
s << "GET / HTTP/1.1\r\n\r\n"
|
177
|
-
true until s.gets == "\r\n"
|
178
|
-
|
179
|
-
s.readpartial(20)
|
180
|
-
signal :USR2
|
181
|
-
|
182
|
-
true while @server.gets =~ /Ctrl-C/
|
183
|
-
sleep 1
|
184
|
-
|
185
|
-
s.write "GET / HTTP/1.1\r\n\r\n"
|
186
|
-
|
187
|
-
assert_raises Errno::ECONNRESET do
|
188
|
-
Timeout.timeout(2) do
|
189
|
-
raise Errno::ECONNRESET unless s.read(2)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
s = TCPSocket.new "localhost", @tcp_port
|
194
|
-
s << "GET / HTTP/1.0\r\n\r\n"
|
195
|
-
assert_equal "Hello World", s.read.split("\r\n").last
|
196
|
-
end
|
197
|
-
|
198
|
-
def test_bad_query_string_outputs_400
|
199
|
-
server "-q test/hello.ru 2>&1"
|
200
|
-
|
201
|
-
s = TCPSocket.new "localhost", @tcp_port
|
202
|
-
s << "GET /?h=% HTTP/1.0\r\n\r\n"
|
203
|
-
data = s.read
|
204
|
-
assert_equal "HTTP/1.1 400 Bad Request\r\n\r\n", data
|
205
|
-
end
|
206
|
-
end unless ENV['TRAVIS']
|