puma 2.0.0.b5 → 5.0.0.beta1
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 +7 -0
- data/History.md +1598 -0
- data/LICENSE +23 -20
- data/README.md +222 -62
- data/bin/puma-wild +31 -0
- data/bin/pumactl +1 -1
- data/docs/architecture.md +37 -0
- data/docs/deployment.md +113 -0
- data/docs/fork_worker.md +31 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/jungle/README.md +13 -0
- data/docs/jungle/rc.d/README.md +74 -0
- data/docs/jungle/rc.d/puma +61 -0
- data/docs/jungle/rc.d/puma.conf +10 -0
- data/docs/jungle/upstart/README.md +61 -0
- data/docs/jungle/upstart/puma-manager.conf +31 -0
- data/docs/jungle/upstart/puma.conf +69 -0
- data/docs/nginx.md +5 -10
- data/docs/plugins.md +38 -0
- data/docs/restart.md +41 -0
- data/docs/signals.md +97 -0
- data/docs/systemd.md +228 -0
- data/ext/puma_http11/PumaHttp11Service.java +2 -2
- data/ext/puma_http11/extconf.rb +23 -2
- data/ext/puma_http11/http11_parser.c +301 -482
- data/ext/puma_http11/http11_parser.h +13 -11
- data/ext/puma_http11/http11_parser.java.rl +26 -42
- data/ext/puma_http11/http11_parser.rl +22 -21
- data/ext/puma_http11/http11_parser_common.rl +5 -5
- data/ext/puma_http11/mini_ssl.c +377 -18
- data/ext/puma_http11/org/jruby/puma/Http11.java +108 -107
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +137 -170
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +265 -191
- data/ext/puma_http11/puma_http11.c +57 -81
- data/lib/puma.rb +25 -4
- data/lib/puma/accept_nonblock.rb +7 -1
- data/lib/puma/app/status.rb +61 -24
- data/lib/puma/binder.rb +212 -78
- data/lib/puma/cli.rb +149 -644
- data/lib/puma/client.rb +316 -65
- data/lib/puma/cluster.rb +659 -0
- data/lib/puma/commonlogger.rb +108 -0
- data/lib/puma/configuration.rb +279 -180
- data/lib/puma/const.rb +126 -39
- data/lib/puma/control_cli.rb +183 -96
- data/lib/puma/detect.rb +20 -1
- data/lib/puma/dsl.rb +776 -0
- data/lib/puma/events.rb +91 -23
- data/lib/puma/io_buffer.rb +9 -5
- data/lib/puma/jruby_restart.rb +9 -5
- data/lib/puma/launcher.rb +487 -0
- data/lib/puma/minissl.rb +239 -93
- data/lib/puma/minissl/context_builder.rb +76 -0
- data/lib/puma/null_io.rb +22 -12
- data/lib/puma/plugin.rb +111 -0
- data/lib/puma/plugin/tmp_restart.rb +36 -0
- data/lib/puma/rack/builder.rb +297 -0
- data/lib/puma/rack/urlmap.rb +93 -0
- data/lib/puma/rack_default.rb +9 -0
- data/lib/puma/reactor.rb +290 -43
- data/lib/puma/runner.rb +163 -0
- data/lib/puma/server.rb +493 -126
- data/lib/puma/single.rb +66 -0
- data/lib/puma/state_file.rb +34 -0
- data/lib/puma/thread_pool.rb +228 -47
- data/lib/puma/util.rb +115 -0
- data/lib/rack/handler/puma.rb +78 -31
- data/tools/Dockerfile +16 -0
- data/tools/trickletest.rb +44 -0
- metadata +60 -155
- data/COPYING +0 -55
- data/Gemfile +0 -8
- data/History.txt +0 -196
- data/Manifest.txt +0 -56
- data/Rakefile +0 -121
- data/TODO +0 -5
- data/docs/config.md +0 -0
- data/ext/puma_http11/io_buffer.c +0 -154
- data/lib/puma/capistrano.rb +0 -26
- data/lib/puma/compat.rb +0 -11
- data/lib/puma/daemon_ext.rb +0 -20
- data/lib/puma/delegation.rb +0 -11
- data/lib/puma/java_io_buffer.rb +0 -45
- data/lib/puma/rack_patch.rb +0 -25
- data/puma.gemspec +0 -45
- data/test/test_app_status.rb +0 -88
- data/test/test_cli.rb +0 -171
- data/test/test_config.rb +0 -16
- data/test/test_http10.rb +0 -27
- data/test/test_http11.rb +0 -126
- data/test/test_integration.rb +0 -150
- data/test/test_iobuffer.rb +0 -38
- data/test/test_minissl.rb +0 -22
- data/test/test_null_io.rb +0 -31
- data/test/test_persistent.rb +0 -238
- data/test/test_puma_server.rb +0 -128
- data/test/test_rack_handler.rb +0 -10
- data/test/test_rack_server.rb +0 -141
- data/test/test_thread_pool.rb +0 -146
- data/test/test_unix_socket.rb +0 -39
- data/test/test_ws.rb +0 -89
- data/tools/jungle/README.md +0 -54
- data/tools/jungle/puma +0 -332
- data/tools/jungle/run-puma +0 -3
data/test/test_puma_server.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
require "rbconfig"
|
2
|
-
require 'test/unit'
|
3
|
-
require 'socket'
|
4
|
-
require 'openssl'
|
5
|
-
|
6
|
-
require 'puma/minissl'
|
7
|
-
require 'puma/server'
|
8
|
-
|
9
|
-
require 'net/https'
|
10
|
-
|
11
|
-
class TestPumaServer < Test::Unit::TestCase
|
12
|
-
|
13
|
-
def setup
|
14
|
-
@port = 3212
|
15
|
-
@host = "127.0.0.1"
|
16
|
-
|
17
|
-
@app = lambda { |env| [200, {}, [env['rack.url_scheme']]] }
|
18
|
-
|
19
|
-
@events = Puma::Events.new STDOUT, STDERR
|
20
|
-
@server = Puma::Server.new @app, @events
|
21
|
-
|
22
|
-
if defined?(JRUBY_VERSION)
|
23
|
-
@ssl_key = File.expand_path "../../examples/puma/keystore.jks", __FILE__
|
24
|
-
@ssl_cert = @ssl_key
|
25
|
-
else
|
26
|
-
@ssl_key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
|
27
|
-
@ssl_cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def teardown
|
32
|
-
@server.stop(true)
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_url_scheme_for_https
|
36
|
-
ctx = Puma::MiniSSL::Context.new
|
37
|
-
|
38
|
-
ctx.key = @ssl_key
|
39
|
-
ctx.cert = @ssl_cert
|
40
|
-
|
41
|
-
ctx.verify_mode = Puma::MiniSSL::VERIFY_NONE
|
42
|
-
|
43
|
-
@server.add_ssl_listener @host, @port, ctx
|
44
|
-
@server.run
|
45
|
-
|
46
|
-
http = Net::HTTP.new @host, @port
|
47
|
-
http.use_ssl = true
|
48
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
49
|
-
|
50
|
-
body = nil
|
51
|
-
http.start do
|
52
|
-
req = Net::HTTP::Get.new "/", {}
|
53
|
-
|
54
|
-
http.request(req) do |rep|
|
55
|
-
body = rep.body
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
assert_equal "https", body
|
60
|
-
end unless defined? JRUBY_VERSION
|
61
|
-
|
62
|
-
def test_proper_stringio_body
|
63
|
-
data = nil
|
64
|
-
|
65
|
-
@server.app = proc do |env|
|
66
|
-
data = env['rack.input'].read
|
67
|
-
[200, {}, ["ok"]]
|
68
|
-
end
|
69
|
-
|
70
|
-
@server.add_tcp_listener @host, @port
|
71
|
-
@server.run
|
72
|
-
|
73
|
-
fifteen = "1" * 15
|
74
|
-
|
75
|
-
sock = TCPSocket.new @host, @port
|
76
|
-
sock << "PUT / HTTP/1.0\r\nContent-Length: 30\r\n\r\n#{fifteen}"
|
77
|
-
sleep 0.1 # important so that the previous data is sent as a packet
|
78
|
-
sock << fifteen
|
79
|
-
|
80
|
-
sock.read
|
81
|
-
|
82
|
-
assert_equal "#{fifteen}#{fifteen}", data
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_puma_socket
|
86
|
-
body = "HTTP/1.1 750 Upgraded to Awesome\r\nDone: Yep!\r\n"
|
87
|
-
@server.app = proc do |env|
|
88
|
-
io = env['puma.socket']
|
89
|
-
|
90
|
-
io.write body
|
91
|
-
|
92
|
-
io.close
|
93
|
-
|
94
|
-
[-1, {}, []]
|
95
|
-
end
|
96
|
-
|
97
|
-
@server.add_tcp_listener @host, @port
|
98
|
-
@server.run
|
99
|
-
|
100
|
-
sock = TCPSocket.new @host, @port
|
101
|
-
sock << "PUT / HTTP/1.0\r\n\r\nHello"
|
102
|
-
|
103
|
-
assert_equal body, sock.read
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_very_large_return
|
107
|
-
giant = "x" * 2056610
|
108
|
-
|
109
|
-
@server.app = proc do |env|
|
110
|
-
[200, {}, [giant]]
|
111
|
-
end
|
112
|
-
|
113
|
-
@server.add_tcp_listener @host, @port
|
114
|
-
@server.run
|
115
|
-
|
116
|
-
sock = TCPSocket.new @host, @port
|
117
|
-
sock << "GET / HTTP/1.0\r\n\r\n"
|
118
|
-
|
119
|
-
while true
|
120
|
-
line = sock.gets
|
121
|
-
break if line == "\r\n"
|
122
|
-
end
|
123
|
-
|
124
|
-
out = sock.read
|
125
|
-
|
126
|
-
assert_equal giant.bytesize, out.bytesize
|
127
|
-
end
|
128
|
-
end
|
data/test/test_rack_handler.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
class TestPumaUnixSocket < Test::Unit::TestCase
|
4
|
-
def test_handler
|
5
|
-
handler = Rack::Handler.get(:puma)
|
6
|
-
assert_equal Rack::Handler::Puma, handler
|
7
|
-
handler = Rack::Handler.get('Puma')
|
8
|
-
assert_equal Rack::Handler::Puma, handler
|
9
|
-
end
|
10
|
-
end
|
data/test/test_rack_server.rb
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'puma'
|
3
|
-
require 'rack/lint'
|
4
|
-
require 'test/testhelp'
|
5
|
-
require 'rack/commonlogger'
|
6
|
-
require 'puma/rack_patch'
|
7
|
-
|
8
|
-
class TestRackServer < Test::Unit::TestCase
|
9
|
-
|
10
|
-
class ErrorChecker
|
11
|
-
def initialize(app)
|
12
|
-
@app = app
|
13
|
-
@exception = nil
|
14
|
-
@env = nil
|
15
|
-
end
|
16
|
-
|
17
|
-
attr_reader :exception, :env
|
18
|
-
|
19
|
-
def call(env)
|
20
|
-
begin
|
21
|
-
@env = env
|
22
|
-
return @app.call(env)
|
23
|
-
rescue Exception => e
|
24
|
-
@exception = e
|
25
|
-
|
26
|
-
[
|
27
|
-
500,
|
28
|
-
{ "X-Exception" => e.message, "X-Exception-Class" => e.class.to_s },
|
29
|
-
["Error detected"]
|
30
|
-
]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class ServerLint < Rack::Lint
|
36
|
-
def call(env)
|
37
|
-
assert("No env given") { env }
|
38
|
-
check_env env
|
39
|
-
|
40
|
-
@app.call(env)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def setup
|
45
|
-
@valid_request = "GET / HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
|
46
|
-
|
47
|
-
@simple = lambda { |env| [200, { "X-Header" => "Works" }, ["Hello"]] }
|
48
|
-
@server = Puma::Server.new @simple
|
49
|
-
@server.add_tcp_listener "127.0.0.1", 9998
|
50
|
-
|
51
|
-
@stopped = false
|
52
|
-
end
|
53
|
-
|
54
|
-
def stop
|
55
|
-
@server.stop(true)
|
56
|
-
@stopped = true
|
57
|
-
end
|
58
|
-
|
59
|
-
def teardown
|
60
|
-
@server.stop(true) unless @stopped
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_lint
|
64
|
-
@checker = ErrorChecker.new ServerLint.new(@simple)
|
65
|
-
@server.app = @checker
|
66
|
-
|
67
|
-
@server.run
|
68
|
-
|
69
|
-
hit(['http://127.0.0.1:9998/test'])
|
70
|
-
|
71
|
-
stop
|
72
|
-
|
73
|
-
if exc = @checker.exception
|
74
|
-
raise exc
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_large_post_body
|
79
|
-
@checker = ErrorChecker.new ServerLint.new(@simple)
|
80
|
-
@server.app = @checker
|
81
|
-
|
82
|
-
@server.run
|
83
|
-
|
84
|
-
big = "x" * (1024 * 16)
|
85
|
-
|
86
|
-
Net::HTTP.post_form URI.parse('http://127.0.0.1:9998/test'),
|
87
|
-
{ "big" => big }
|
88
|
-
|
89
|
-
stop
|
90
|
-
|
91
|
-
if exc = @checker.exception
|
92
|
-
raise exc
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_path_info
|
97
|
-
input = nil
|
98
|
-
@server.app = lambda { |env| input = env; @simple.call(env) }
|
99
|
-
@server.run
|
100
|
-
|
101
|
-
hit(['http://127.0.0.1:9998/test/a/b/c'])
|
102
|
-
|
103
|
-
stop
|
104
|
-
|
105
|
-
assert_equal "/test/a/b/c", input['PATH_INFO']
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_after_reply
|
109
|
-
closed = false
|
110
|
-
|
111
|
-
@server.app = lambda do |env|
|
112
|
-
env['rack.after_reply'] << lambda { closed = true }
|
113
|
-
@simple.call(env)
|
114
|
-
end
|
115
|
-
|
116
|
-
@server.run
|
117
|
-
|
118
|
-
hit(['http://127.0.0.1:9998/test'])
|
119
|
-
|
120
|
-
stop
|
121
|
-
|
122
|
-
assert_equal true, closed
|
123
|
-
end
|
124
|
-
|
125
|
-
def test_common_logger
|
126
|
-
log = StringIO.new
|
127
|
-
|
128
|
-
logger = Rack::CommonLogger.new(@simple, log)
|
129
|
-
|
130
|
-
@server.app = logger
|
131
|
-
|
132
|
-
@server.run
|
133
|
-
|
134
|
-
hit(['http://127.0.0.1:9998/test'])
|
135
|
-
|
136
|
-
stop
|
137
|
-
|
138
|
-
assert_match %r!GET /test HTTP/1\.1!, log.string
|
139
|
-
end
|
140
|
-
|
141
|
-
end
|
data/test/test_thread_pool.rb
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
require 'puma/thread_pool'
|
4
|
-
|
5
|
-
class TestThreadPool < Test::Unit::TestCase
|
6
|
-
|
7
|
-
def teardown
|
8
|
-
@pool.shutdown if @pool
|
9
|
-
end
|
10
|
-
|
11
|
-
def new_pool(min, max, &blk)
|
12
|
-
blk = proc { } unless blk
|
13
|
-
@pool = Puma::ThreadPool.new(min, max, &blk)
|
14
|
-
end
|
15
|
-
|
16
|
-
def pause
|
17
|
-
sleep 0.2
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_append_spawns
|
21
|
-
saw = []
|
22
|
-
|
23
|
-
pool = new_pool(0, 1) do |work|
|
24
|
-
saw << work
|
25
|
-
end
|
26
|
-
|
27
|
-
pool << 1
|
28
|
-
|
29
|
-
pause
|
30
|
-
|
31
|
-
assert_equal [1], saw
|
32
|
-
assert_equal 1, pool.spawned
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_append_queues_on_max
|
36
|
-
finish = false
|
37
|
-
pool = new_pool(0, 1) { Thread.pass until finish }
|
38
|
-
|
39
|
-
pool << 1
|
40
|
-
pool << 2
|
41
|
-
pool << 3
|
42
|
-
|
43
|
-
pause
|
44
|
-
|
45
|
-
assert_equal 2, pool.backlog
|
46
|
-
|
47
|
-
finish = true
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_trim
|
51
|
-
pool = new_pool(0, 1)
|
52
|
-
|
53
|
-
pool << 1
|
54
|
-
|
55
|
-
pause
|
56
|
-
|
57
|
-
assert_equal 1, pool.spawned
|
58
|
-
pool.trim
|
59
|
-
|
60
|
-
pause
|
61
|
-
assert_equal 0, pool.spawned
|
62
|
-
end
|
63
|
-
|
64
|
-
def test_trim_leaves_min
|
65
|
-
finish = false
|
66
|
-
pool = new_pool(1, 2) { Thread.pass until finish }
|
67
|
-
|
68
|
-
pool << 1
|
69
|
-
pool << 2
|
70
|
-
|
71
|
-
finish = true
|
72
|
-
|
73
|
-
pause
|
74
|
-
|
75
|
-
assert_equal 2, pool.spawned
|
76
|
-
pool.trim
|
77
|
-
pause
|
78
|
-
|
79
|
-
assert_equal 1, pool.spawned
|
80
|
-
pool.trim
|
81
|
-
pause
|
82
|
-
|
83
|
-
assert_equal 1, pool.spawned
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_force_trim_doesnt_overtrim
|
88
|
-
finish = false
|
89
|
-
pool = new_pool(1, 2) { Thread.pass until finish }
|
90
|
-
|
91
|
-
pool << 1
|
92
|
-
pool << 2
|
93
|
-
|
94
|
-
assert_equal 2, pool.spawned
|
95
|
-
pool.trim true
|
96
|
-
pool.trim true
|
97
|
-
|
98
|
-
finish = true
|
99
|
-
|
100
|
-
pause
|
101
|
-
|
102
|
-
assert_equal 1, pool.spawned
|
103
|
-
end
|
104
|
-
|
105
|
-
def test_trim_is_ignored_if_no_waiting_threads
|
106
|
-
finish = false
|
107
|
-
pool = new_pool(1, 2) { Thread.pass until finish }
|
108
|
-
|
109
|
-
pool << 1
|
110
|
-
pool << 2
|
111
|
-
|
112
|
-
assert_equal 2, pool.spawned
|
113
|
-
pool.trim
|
114
|
-
pool.trim
|
115
|
-
|
116
|
-
assert_equal 0, pool.trim_requested
|
117
|
-
|
118
|
-
finish = true
|
119
|
-
|
120
|
-
pause
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_autotrim
|
124
|
-
finish = false
|
125
|
-
pool = new_pool(1, 2) { Thread.pass until finish }
|
126
|
-
|
127
|
-
pool << 1
|
128
|
-
pool << 2
|
129
|
-
|
130
|
-
assert_equal 2, pool.spawned
|
131
|
-
|
132
|
-
finish = true
|
133
|
-
|
134
|
-
pause
|
135
|
-
|
136
|
-
assert_equal 2, pool.spawned
|
137
|
-
|
138
|
-
pool.auto_trim! 1
|
139
|
-
|
140
|
-
sleep 1
|
141
|
-
|
142
|
-
pause
|
143
|
-
|
144
|
-
assert_equal 1, pool.spawned
|
145
|
-
end
|
146
|
-
end
|
data/test/test_unix_socket.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require "rbconfig"
|
2
|
-
require 'test/unit'
|
3
|
-
require 'puma/server'
|
4
|
-
|
5
|
-
require 'socket'
|
6
|
-
|
7
|
-
# UNIX sockets are not recommended on JRuby
|
8
|
-
# (or Windows)
|
9
|
-
unless defined?(JRUBY_VERSION) || RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
|
10
|
-
class TestPumaUnixSocket < Test::Unit::TestCase
|
11
|
-
|
12
|
-
App = lambda { |env| [200, {}, ["Works"]] }
|
13
|
-
|
14
|
-
Path = "test/puma.sock"
|
15
|
-
|
16
|
-
def setup
|
17
|
-
@server = Puma::Server.new App
|
18
|
-
@server.add_unix_listener Path
|
19
|
-
@server.run
|
20
|
-
end
|
21
|
-
|
22
|
-
def teardown
|
23
|
-
@server.stop(true)
|
24
|
-
File.unlink Path if File.exists? Path
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_server
|
28
|
-
sock = UNIXSocket.new Path
|
29
|
-
|
30
|
-
sock << "GET / HTTP/1.0\r\nHost: blah.com\r\n\r\n"
|
31
|
-
|
32
|
-
expected = "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Length: 5\r\n\r\nWorks"
|
33
|
-
|
34
|
-
assert_equal expected, sock.read(expected.size)
|
35
|
-
|
36
|
-
sock.close
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|