wendell-puma 2.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +55 -0
  3. data/DEPLOYMENT.md +92 -0
  4. data/Gemfile +17 -0
  5. data/History.txt +588 -0
  6. data/LICENSE +26 -0
  7. data/Manifest.txt +68 -0
  8. data/README.md +251 -0
  9. data/Rakefile +158 -0
  10. data/bin/puma +10 -0
  11. data/bin/puma-wild +31 -0
  12. data/bin/pumactl +12 -0
  13. data/docs/config.md +0 -0
  14. data/docs/nginx.md +80 -0
  15. data/docs/signals.md +43 -0
  16. data/ext/puma_http11/PumaHttp11Service.java +17 -0
  17. data/ext/puma_http11/ext_help.h +15 -0
  18. data/ext/puma_http11/extconf.rb +9 -0
  19. data/ext/puma_http11/http11_parser.c +1225 -0
  20. data/ext/puma_http11/http11_parser.h +64 -0
  21. data/ext/puma_http11/http11_parser.java.rl +161 -0
  22. data/ext/puma_http11/http11_parser.rl +146 -0
  23. data/ext/puma_http11/http11_parser_common.rl +54 -0
  24. data/ext/puma_http11/io_buffer.c +155 -0
  25. data/ext/puma_http11/mini_ssl.c +198 -0
  26. data/ext/puma_http11/org/jruby/puma/Http11.java +225 -0
  27. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +488 -0
  28. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +391 -0
  29. data/ext/puma_http11/puma_http11.c +491 -0
  30. data/lib/puma.rb +14 -0
  31. data/lib/puma/accept_nonblock.rb +23 -0
  32. data/lib/puma/app/status.rb +59 -0
  33. data/lib/puma/binder.rb +298 -0
  34. data/lib/puma/capistrano.rb +86 -0
  35. data/lib/puma/cli.rb +606 -0
  36. data/lib/puma/client.rb +289 -0
  37. data/lib/puma/cluster.rb +404 -0
  38. data/lib/puma/compat.rb +18 -0
  39. data/lib/puma/configuration.rb +377 -0
  40. data/lib/puma/const.rb +165 -0
  41. data/lib/puma/control_cli.rb +251 -0
  42. data/lib/puma/daemon_ext.rb +25 -0
  43. data/lib/puma/delegation.rb +11 -0
  44. data/lib/puma/detect.rb +4 -0
  45. data/lib/puma/events.rb +130 -0
  46. data/lib/puma/io_buffer.rb +7 -0
  47. data/lib/puma/java_io_buffer.rb +45 -0
  48. data/lib/puma/jruby_restart.rb +83 -0
  49. data/lib/puma/minissl.rb +187 -0
  50. data/lib/puma/null_io.rb +34 -0
  51. data/lib/puma/rack_default.rb +7 -0
  52. data/lib/puma/rack_patch.rb +45 -0
  53. data/lib/puma/reactor.rb +183 -0
  54. data/lib/puma/runner.rb +146 -0
  55. data/lib/puma/server.rb +801 -0
  56. data/lib/puma/single.rb +102 -0
  57. data/lib/puma/tcp_logger.rb +32 -0
  58. data/lib/puma/thread_pool.rb +185 -0
  59. data/lib/puma/util.rb +9 -0
  60. data/lib/rack/handler/puma.rb +66 -0
  61. data/test/test_app_status.rb +92 -0
  62. data/test/test_cli.rb +173 -0
  63. data/test/test_config.rb +26 -0
  64. data/test/test_http10.rb +27 -0
  65. data/test/test_http11.rb +144 -0
  66. data/test/test_integration.rb +165 -0
  67. data/test/test_iobuffer.rb +38 -0
  68. data/test/test_minissl.rb +29 -0
  69. data/test/test_null_io.rb +31 -0
  70. data/test/test_persistent.rb +238 -0
  71. data/test/test_puma_server.rb +288 -0
  72. data/test/test_puma_server_ssl.rb +137 -0
  73. data/test/test_rack_handler.rb +10 -0
  74. data/test/test_rack_server.rb +141 -0
  75. data/test/test_tcp_rack.rb +42 -0
  76. data/test/test_thread_pool.rb +156 -0
  77. data/test/test_unix_socket.rb +39 -0
  78. data/test/test_ws.rb +89 -0
  79. data/tools/jungle/README.md +9 -0
  80. data/tools/jungle/init.d/README.md +54 -0
  81. data/tools/jungle/init.d/puma +332 -0
  82. data/tools/jungle/init.d/run-puma +3 -0
  83. data/tools/jungle/upstart/README.md +61 -0
  84. data/tools/jungle/upstart/puma-manager.conf +31 -0
  85. data/tools/jungle/upstart/puma.conf +63 -0
  86. data/tools/trickletest.rb +45 -0
  87. data/wendell-puma.gemspec +55 -0
  88. metadata +225 -0
@@ -0,0 +1,137 @@
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 TestPumaServerSSL < 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
+ @ctx = Puma::MiniSSL::Context.new
20
+
21
+ if defined?(JRUBY_VERSION)
22
+ @ctx.keystore = File.expand_path "../../examples/puma/keystore.jks", __FILE__
23
+ @ctx.keystore_pass = 'blahblah'
24
+ else
25
+ @ctx.key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
26
+ @ctx.cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__
27
+ end
28
+
29
+ @ctx.verify_mode = Puma::MiniSSL::VERIFY_NONE
30
+
31
+ @events = Puma::Events.new STDOUT, STDERR
32
+ @server = Puma::Server.new @app, @events
33
+ @server.add_ssl_listener @host, @port, @ctx
34
+ @server.run
35
+
36
+ @http = Net::HTTP.new @host, @port
37
+ @http.use_ssl = true
38
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
39
+ end
40
+
41
+ def teardown
42
+ @server.stop(true)
43
+ end
44
+
45
+ def test_url_scheme_for_https
46
+ body = nil
47
+ @http.start do
48
+ req = Net::HTTP::Get.new "/", {}
49
+
50
+ @http.request(req) do |rep|
51
+ body = rep.body
52
+ end
53
+ end
54
+
55
+ assert_equal "https", body
56
+ end
57
+
58
+ def test_very_large_return
59
+ giant = "x" * 2056610
60
+
61
+ @server.app = proc do
62
+ [200, {}, [giant]]
63
+ end
64
+
65
+ body = nil
66
+ @http.start do
67
+ req = Net::HTTP::Get.new "/"
68
+ @http.request(req) do |rep|
69
+ body = rep.body
70
+ end
71
+ end
72
+
73
+ assert_equal giant.bytesize, body.bytesize
74
+ end
75
+
76
+ def test_form_submit
77
+ body = nil
78
+ @http.start do
79
+ req = Net::HTTP::Post.new '/'
80
+ req.set_form_data('a' => '1', 'b' => '2')
81
+
82
+ @http.request(req) do |rep|
83
+ body = rep.body
84
+ end
85
+
86
+ end
87
+
88
+ assert_equal "https", body
89
+ end
90
+
91
+ if defined?(JRUBY_VERSION)
92
+ def test_ssl_v3_support_disabled_by_default
93
+ @http.ssl_version='SSLv3'
94
+ assert_raises(OpenSSL::SSL::SSLError) do
95
+ @http.start do
96
+ Net::HTTP::Get.new '/'
97
+ end
98
+ end
99
+ end
100
+
101
+ def test_enabling_ssl_v3_support
102
+ @server.stop(true)
103
+ @ctx.enable_SSLv3 = true
104
+ @server = Puma::Server.new @app, @events
105
+ @server.add_ssl_listener @host, @port, @ctx
106
+ @server.run
107
+ @http.ssl_version='SSLv3'
108
+
109
+ body = nil
110
+ @http.start do
111
+ req = Net::HTTP::Get.new "/", {}
112
+
113
+ @http.request(req) do |rep|
114
+ body = rep.body
115
+ end
116
+ end
117
+
118
+ assert_equal "https", body
119
+ end
120
+
121
+ def test_enabling_ssl_v3_support_requires_true
122
+ @server.stop(true)
123
+ @ctx.enable_SSLv3 = "truthy but not true"
124
+ @server = Puma::Server.new @app, @events
125
+ @server.add_ssl_listener @host, @port, @ctx
126
+ @server.run
127
+ @http.ssl_version='SSLv3'
128
+
129
+ assert_raises(OpenSSL::SSL::SSLError) do
130
+ @http.start do
131
+ Net::HTTP::Get.new '/'
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ end
@@ -0,0 +1,10 @@
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
@@ -0,0 +1,141 @@
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
@@ -0,0 +1,42 @@
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 TestTCPRack < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @port = 3212
15
+ @host = "127.0.0.1"
16
+
17
+ @events = Puma::Events.new STDOUT, STDERR
18
+ @server = Puma::Server.new nil, @events
19
+ end
20
+
21
+ def teardown
22
+ @server.stop(true)
23
+ end
24
+
25
+ def test_passes_the_socket
26
+ @server.tcp_mode!
27
+
28
+ body = "We sell hats for a discount!\n"
29
+
30
+ @server.app = proc do |env, socket|
31
+ socket << body
32
+ socket.close
33
+ end
34
+
35
+ @server.add_tcp_listener @host, @port
36
+ @server.run
37
+
38
+ sock = TCPSocket.new @host, @port
39
+
40
+ assert_equal body, sock.read
41
+ end
42
+ end
@@ -0,0 +1,156 @@
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, &block)
12
+ block = proc { } unless block
13
+ @pool = Puma::ThreadPool.new(min, max, &block)
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_converts_pool_sizes
36
+ pool = new_pool('0', '1')
37
+
38
+ assert_equal 0, pool.spawned
39
+
40
+ pool << 1
41
+
42
+ assert_equal 1, pool.spawned
43
+ end
44
+
45
+ def test_append_queues_on_max
46
+ finish = false
47
+ pool = new_pool(0, 1) { Thread.pass until finish }
48
+
49
+ pool << 1
50
+ pool << 2
51
+ pool << 3
52
+
53
+ pause
54
+
55
+ assert_equal 2, pool.backlog
56
+
57
+ finish = true
58
+ end
59
+
60
+ def test_trim
61
+ pool = new_pool(0, 1)
62
+
63
+ pool << 1
64
+
65
+ pause
66
+
67
+ assert_equal 1, pool.spawned
68
+ pool.trim
69
+
70
+ pause
71
+ assert_equal 0, pool.spawned
72
+ end
73
+
74
+ def test_trim_leaves_min
75
+ finish = false
76
+ pool = new_pool(1, 2) { Thread.pass until finish }
77
+
78
+ pool << 1
79
+ pool << 2
80
+
81
+ finish = true
82
+
83
+ pause
84
+
85
+ assert_equal 2, pool.spawned
86
+ pool.trim
87
+ pause
88
+
89
+ assert_equal 1, pool.spawned
90
+ pool.trim
91
+ pause
92
+
93
+ assert_equal 1, pool.spawned
94
+
95
+ end
96
+
97
+ def test_force_trim_doesnt_overtrim
98
+ finish = false
99
+ pool = new_pool(1, 2) { Thread.pass until finish }
100
+
101
+ pool << 1
102
+ pool << 2
103
+
104
+ assert_equal 2, pool.spawned
105
+ pool.trim true
106
+ pool.trim true
107
+
108
+ finish = true
109
+
110
+ pause
111
+
112
+ assert_equal 1, pool.spawned
113
+ end
114
+
115
+ def test_trim_is_ignored_if_no_waiting_threads
116
+ finish = false
117
+ pool = new_pool(1, 2) { Thread.pass until finish }
118
+
119
+ pool << 1
120
+ pool << 2
121
+
122
+ assert_equal 2, pool.spawned
123
+ pool.trim
124
+ pool.trim
125
+
126
+ assert_equal 0, pool.trim_requested
127
+
128
+ finish = true
129
+
130
+ pause
131
+ end
132
+
133
+ def test_autotrim
134
+ finish = false
135
+ pool = new_pool(1, 2) { Thread.pass until finish }
136
+
137
+ pool << 1
138
+ pool << 2
139
+
140
+ assert_equal 2, pool.spawned
141
+
142
+ finish = true
143
+
144
+ pause
145
+
146
+ assert_equal 2, pool.spawned
147
+
148
+ pool.auto_trim! 1
149
+
150
+ sleep 1
151
+
152
+ pause
153
+
154
+ assert_equal 1, pool.spawned
155
+ end
156
+ end