puma 2.2.0 → 8.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +3334 -0
  3. data/LICENSE +23 -20
  4. data/README.md +387 -100
  5. data/bin/puma-wild +25 -0
  6. data/bin/pumactl +1 -1
  7. data/docs/5.0-Upgrade.md +98 -0
  8. data/docs/6.0-Upgrade.md +56 -0
  9. data/docs/7.0-Upgrade.md +52 -0
  10. data/docs/8.0-Upgrade.md +100 -0
  11. data/docs/architecture.md +74 -0
  12. data/docs/compile_options.md +55 -0
  13. data/docs/deployment.md +137 -0
  14. data/docs/fork_worker.md +41 -0
  15. data/docs/grpc.md +62 -0
  16. data/docs/images/favicon.svg +1 -0
  17. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  18. data/docs/images/puma-connection-flow.png +0 -0
  19. data/docs/images/puma-general-arch.png +0 -0
  20. data/docs/images/running-puma.svg +1 -0
  21. data/docs/images/standard-logo.svg +1 -0
  22. data/docs/java_options.md +54 -0
  23. data/docs/jungle/README.md +9 -0
  24. data/docs/jungle/rc.d/README.md +74 -0
  25. data/docs/jungle/rc.d/puma +61 -0
  26. data/docs/jungle/rc.d/puma.conf +10 -0
  27. data/docs/kubernetes.md +73 -0
  28. data/docs/nginx.md +5 -5
  29. data/docs/plugins.md +42 -0
  30. data/docs/rails_dev_mode.md +28 -0
  31. data/docs/restart.md +65 -0
  32. data/docs/signals.md +98 -0
  33. data/docs/stats.md +148 -0
  34. data/docs/systemd.md +253 -0
  35. data/docs/testing_benchmarks_local_files.md +150 -0
  36. data/docs/testing_test_rackup_ci_files.md +36 -0
  37. data/ext/puma_http11/PumaHttp11Service.java +2 -2
  38. data/ext/puma_http11/extconf.rb +59 -2
  39. data/ext/puma_http11/http11_parser.c +319 -487
  40. data/ext/puma_http11/http11_parser.h +15 -13
  41. data/ext/puma_http11/http11_parser.java.rl +64 -94
  42. data/ext/puma_http11/http11_parser.rl +27 -24
  43. data/ext/puma_http11/http11_parser_common.rl +8 -8
  44. data/ext/puma_http11/mini_ssl.c +696 -38
  45. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  46. data/ext/puma_http11/org/jruby/puma/EnvKey.java +241 -0
  47. data/ext/puma_http11/org/jruby/puma/Http11.java +241 -145
  48. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +174 -221
  49. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +413 -193
  50. data/ext/puma_http11/puma_http11.c +183 -175
  51. data/lib/puma/app/status.rb +77 -29
  52. data/lib/puma/binder.rb +349 -119
  53. data/lib/puma/cli.rb +163 -801
  54. data/lib/puma/client.rb +627 -144
  55. data/lib/puma/client_env.rb +171 -0
  56. data/lib/puma/cluster/worker.rb +183 -0
  57. data/lib/puma/cluster/worker_handle.rb +127 -0
  58. data/lib/puma/cluster.rb +634 -0
  59. data/lib/puma/cluster_accept_loop_delay.rb +91 -0
  60. data/lib/puma/commonlogger.rb +115 -0
  61. data/lib/puma/configuration.rb +420 -198
  62. data/lib/puma/const.rb +266 -115
  63. data/lib/puma/control_cli.rb +219 -120
  64. data/lib/puma/detect.rb +56 -2
  65. data/lib/puma/dsl.rb +1562 -0
  66. data/lib/puma/error_logger.rb +115 -0
  67. data/lib/puma/events.rb +44 -60
  68. data/lib/puma/io_buffer.rb +48 -5
  69. data/lib/puma/jruby_restart.rb +2 -51
  70. data/lib/puma/json_serialization.rb +96 -0
  71. data/lib/puma/launcher/bundle_pruner.rb +102 -0
  72. data/lib/puma/launcher.rb +501 -0
  73. data/lib/puma/log_writer.rb +153 -0
  74. data/lib/puma/minissl/context_builder.rb +96 -0
  75. data/lib/puma/minissl.rb +355 -37
  76. data/lib/puma/null_io.rb +79 -12
  77. data/lib/puma/plugin/systemd.rb +90 -0
  78. data/lib/puma/plugin/tmp_restart.rb +36 -0
  79. data/lib/puma/plugin.rb +111 -0
  80. data/lib/puma/rack/builder.rb +297 -0
  81. data/lib/puma/rack/urlmap.rb +93 -0
  82. data/lib/puma/rack_default.rb +21 -4
  83. data/lib/puma/reactor.rb +102 -133
  84. data/lib/puma/response.rb +532 -0
  85. data/lib/puma/runner.rb +211 -0
  86. data/lib/puma/sd_notify.rb +146 -0
  87. data/lib/puma/server.rb +582 -445
  88. data/lib/puma/server_plugin_control.rb +32 -0
  89. data/lib/puma/single.rb +72 -0
  90. data/lib/puma/state_file.rb +69 -0
  91. data/lib/puma/thread_pool.rb +389 -57
  92. data/lib/puma/util.rb +125 -0
  93. data/lib/puma.rb +80 -6
  94. data/lib/rack/handler/puma.rb +125 -47
  95. data/tools/Dockerfile +26 -0
  96. data/tools/trickletest.rb +44 -0
  97. metadata +88 -148
  98. data/COPYING +0 -55
  99. data/Gemfile +0 -10
  100. data/History.txt +0 -302
  101. data/Manifest.txt +0 -60
  102. data/Rakefile +0 -165
  103. data/TODO +0 -5
  104. data/docs/config.md +0 -0
  105. data/ext/puma_http11/ext_help.h +0 -15
  106. data/ext/puma_http11/io_buffer.c +0 -154
  107. data/lib/puma/accept_nonblock.rb +0 -23
  108. data/lib/puma/capistrano.rb +0 -34
  109. data/lib/puma/compat.rb +0 -11
  110. data/lib/puma/daemon_ext.rb +0 -20
  111. data/lib/puma/delegation.rb +0 -11
  112. data/lib/puma/java_io_buffer.rb +0 -45
  113. data/lib/puma/rack_patch.rb +0 -25
  114. data/puma.gemspec +0 -45
  115. data/test/test_app_status.rb +0 -88
  116. data/test/test_cli.rb +0 -171
  117. data/test/test_config.rb +0 -16
  118. data/test/test_http10.rb +0 -27
  119. data/test/test_http11.rb +0 -126
  120. data/test/test_integration.rb +0 -154
  121. data/test/test_iobuffer.rb +0 -38
  122. data/test/test_minissl.rb +0 -25
  123. data/test/test_null_io.rb +0 -31
  124. data/test/test_persistent.rb +0 -238
  125. data/test/test_puma_server.rb +0 -224
  126. data/test/test_rack_handler.rb +0 -10
  127. data/test/test_rack_server.rb +0 -141
  128. data/test/test_thread_pool.rb +0 -146
  129. data/test/test_unix_socket.rb +0 -39
  130. data/test/test_ws.rb +0 -89
  131. data/tools/jungle/init.d/README.md +0 -54
  132. data/tools/jungle/init.d/puma +0 -332
  133. data/tools/jungle/init.d/run-puma +0 -3
  134. data/tools/jungle/upstart/README.md +0 -61
  135. data/tools/jungle/upstart/puma-manager.conf +0 -31
  136. data/tools/jungle/upstart/puma.conf +0 -52
@@ -1,224 +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
-
129
- def test_respect_x_forwarded_proto
130
- @server.app = proc do |env|
131
- [200, {}, [env['SERVER_PORT']]]
132
- end
133
-
134
- @server.add_tcp_listener @host, @port
135
- @server.run
136
-
137
- req = Net::HTTP::Get.new("/")
138
- req['HOST'] = "example.com"
139
- req['X_FORWARDED_PROTO'] = "https"
140
-
141
- res = Net::HTTP.start @host, @port do |http|
142
- http.request(req)
143
- end
144
-
145
- assert_equal "443", res.body
146
- end
147
-
148
- def test_default_server_port
149
- @server.app = proc do |env|
150
- [200, {}, [env['SERVER_PORT']]]
151
- end
152
-
153
- @server.add_tcp_listener @host, @port
154
- @server.run
155
-
156
- req = Net::HTTP::Get.new("/")
157
- req['HOST'] = "example.com"
158
-
159
- res = Net::HTTP.start @host, @port do |http|
160
- http.request(req)
161
- end
162
-
163
- assert_equal "80", res.body
164
- end
165
-
166
- def test_HEAD_has_no_body
167
- @server.app = proc { |env| [200, {"Foo" => "Bar"}, ["hello"]] }
168
-
169
- @server.add_tcp_listener @host, @port
170
- @server.run
171
-
172
- sock = TCPSocket.new @host, @port
173
- sock << "HEAD / HTTP/1.0\r\n\r\n"
174
-
175
- data = sock.read
176
-
177
- assert_equal "HTTP/1.0 200 OK\r\nFoo: Bar\r\n\r\n", data
178
- end
179
-
180
- def test_GET_with_empty_body_has_sane_chunking
181
- @server.app = proc { |env| [200, {}, [""]] }
182
-
183
- @server.add_tcp_listener @host, @port
184
- @server.run
185
-
186
- sock = TCPSocket.new @host, @port
187
- sock << "HEAD / HTTP/1.0\r\n\r\n"
188
-
189
- data = sock.read
190
-
191
- assert_equal "HTTP/1.0 200 OK\r\n\r\n", data
192
- end
193
-
194
- def test_GET_with_no_body_has_sane_chunking
195
- @server.app = proc { |env| [200, {}, [""]] }
196
-
197
- @server.add_tcp_listener @host, @port
198
- @server.run
199
-
200
- sock = TCPSocket.new @host, @port
201
- sock << "HEAD / HTTP/1.0\r\n\r\n"
202
-
203
- data = sock.read
204
-
205
- assert_equal "HTTP/1.0 200 OK\r\n\r\n", data
206
- end
207
-
208
- def test_doesnt_print_backtrace_in_production
209
- @events = Puma::Events.strings
210
- @server = Puma::Server.new @app, @events
211
-
212
- @server.app = proc { |e| raise "don't leak me bro" }
213
- @server.leak_stack_on_error = false
214
- @server.add_tcp_listener @host, @port
215
- @server.run
216
-
217
- sock = TCPSocket.new @host, @port
218
- sock << "GET / HTTP/1.0\r\n\r\n"
219
-
220
- data = sock.read
221
-
222
- assert_not_match(/don't leak me bro/, data)
223
- end
224
- end
@@ -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
@@ -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
@@ -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
@@ -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
data/test/test_ws.rb DELETED
@@ -1,89 +0,0 @@
1
- # Copyright (c) 2011 Evan Phoenix
2
- # Copyright (c) 2005 Zed A. Shaw
3
-
4
- require 'test/testhelp'
5
-
6
- include Puma
7
-
8
- class TestHandler
9
- attr_reader :ran_test
10
-
11
- def call(env)
12
- @ran_test = true
13
-
14
- [200, {"Content-Type" => "text/plain"}, ["hello!"]]
15
- end
16
- end
17
-
18
- class WebServerTest < Test::Unit::TestCase
19
-
20
- def setup
21
- @valid_request = "GET / HTTP/1.1\r\nHost: www.zedshaw.com\r\nContent-Type: text/plain\r\n\r\n"
22
-
23
- @tester = TestHandler.new
24
-
25
- @server = Server.new @tester, Events.strings
26
- @server.add_tcp_listener "127.0.0.1", 9998
27
-
28
- @server.run
29
- end
30
-
31
- def teardown
32
- @server.stop(true)
33
- end
34
-
35
- def test_simple_server
36
- hit(['http://127.0.0.1:9998/test'])
37
- assert @tester.ran_test, "Handler didn't really run"
38
- end
39
-
40
-
41
- def do_test(string, chunk, close_after=nil, shutdown_delay=0)
42
- # Do not use instance variables here, because it needs to be thread safe
43
- socket = TCPSocket.new("127.0.0.1", 9998);
44
- request = StringIO.new(string)
45
- chunks_out = 0
46
-
47
- while data = request.read(chunk)
48
- chunks_out += socket.write(data)
49
- socket.flush
50
- sleep 0.2
51
- if close_after and chunks_out > close_after
52
- socket.close
53
- sleep 1
54
- end
55
- end
56
- sleep(shutdown_delay)
57
- socket.write(" ") # Some platforms only raise the exception on attempted write
58
- socket.flush
59
- end
60
-
61
- def test_trickle_attack
62
- do_test(@valid_request, 3)
63
- end
64
-
65
- def test_close_client
66
- assert_raises IOError do
67
- do_test(@valid_request, 10, 20)
68
- end
69
- end
70
-
71
- def test_bad_client
72
- do_test("GET /test HTTP/BAD", 3)
73
- end
74
-
75
- def test_header_is_too_long
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)
79
- end
80
- end
81
-
82
- def test_file_streamed_request
83
- body = "a" * (Puma::Const::MAX_BODY * 2)
84
- long = "GET /test HTTP/1.1\r\nContent-length: #{body.length}\r\n\r\n" + body
85
- do_test(long, (Puma::Const::CHUNK_SIZE * 2) - 400)
86
- end
87
-
88
- end
89
-
@@ -1,54 +0,0 @@
1
- # Puma daemon service
2
-
3
- Init script to manage multiple Puma servers on the same box using start-stop-daemon.
4
-
5
- ## Installation
6
-
7
- # Copy the init script to services directory
8
- sudo cp puma /etc/init.d
9
- sudo chmod +x /etc/init.d/puma
10
-
11
- # Make it start at boot time.
12
- sudo update-rc.d -f puma defaults
13
-
14
- # Copy the Puma runner to an accessible location
15
- sudo cp run-puma /usr/local/bin
16
- sudo chmod +x /usr/local/bin/run-puma
17
-
18
- # Create an empty configuration file
19
- sudo touch /etc/puma.conf
20
-
21
- ## Managing the jungle
22
-
23
- Puma apps are held in /etc/puma.conf by default. It's mainly a CSV file and every line represents one app. Here's the syntax:
24
-
25
- app-path,user,config-file-path,log-file-path
26
-
27
- You can add an instance by editing the file or running the following command:
28
-
29
- sudo /etc/init.d/puma add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log
30
-
31
- The config and log paths are optional parameters and default to:
32
-
33
- * config: /path/to/app/*config/puma.rb*
34
- * log: /path/to/app/*config/puma.log*
35
-
36
- To remove an app, simply delete the line from the config file or run:
37
-
38
- sudo /etc/init.d/puma remove /path/to/app
39
-
40
- The command will make sure the Puma instance stops before removing it from the jungle.
41
-
42
- ## Assumptions
43
-
44
- * The script expects a temporary folder named /path/to/app/*tmp/puma* to exist. Create it if it's not there by default.
45
- The pid and state files should live there and must be called: *tmp/puma/pid* and *tmp/puma/state*.
46
- You can change those if you want but you'll have to adapt the script for it to work.
47
-
48
- * Here's what a minimal app's config file should have:
49
-
50
- ```
51
- pidfile "/path/to/app/tmp/puma/pid"
52
- state_path "/path/to/app/tmp/puma/state"
53
- activate_control_app
54
- ```