puma 2.0.0.b3 → 2.0.0.b4
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.
- data/History.txt +8 -0
- data/Rakefile +5 -1
- data/ext/puma_http11/io_buffer.c +2 -0
- data/ext/puma_http11/mini_ssl.c +11 -6
- data/lib/puma/cli.rb +2 -0
- data/lib/puma/compat.rb +4 -0
- data/lib/puma/const.rb +1 -1
- data/lib/puma/minissl.rb +14 -1
- data/lib/puma/server.rb +22 -4
- data/puma.gemspec +4 -4
- data/test/test_integration.rb +3 -1
- data/test/test_minissl.rb +22 -0
- data/test/test_puma_server.rb +24 -1
- metadata +4 -2
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 2.0.0.b4 / 2012-12-12
|
2
|
+
|
3
|
+
* 4 bug fixes:
|
4
|
+
* Properly check #syswrite's value for variable sized buffers. Fixes #170
|
5
|
+
* Shutdown status server properly
|
6
|
+
* Handle char vs byte and mixing syswrite with write properly
|
7
|
+
* made MiniSSL validate key/cert file existence
|
8
|
+
|
1
9
|
=== 2.0.0.b3 / 2012-11-22
|
2
10
|
|
3
11
|
* 1 bug fix:
|
data/Rakefile
CHANGED
data/ext/puma_http11/io_buffer.c
CHANGED
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -37,19 +37,22 @@ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
|
|
37
37
|
|
38
38
|
VALUE engine_init_server(VALUE self, VALUE key, VALUE cert) {
|
39
39
|
VALUE obj;
|
40
|
+
SSL_CTX* ctx;
|
41
|
+
SSL* ssl;
|
42
|
+
|
40
43
|
ms_conn* conn = engine_alloc(self, &obj);
|
41
44
|
|
42
45
|
StringValue(key);
|
43
46
|
StringValue(cert);
|
44
47
|
|
45
|
-
|
48
|
+
ctx = SSL_CTX_new(SSLv23_server_method());
|
46
49
|
conn->ctx = ctx;
|
47
50
|
|
48
51
|
SSL_CTX_use_certificate_file(ctx, RSTRING_PTR(cert), SSL_FILETYPE_PEM);
|
49
52
|
SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
|
50
53
|
/* SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); */
|
51
54
|
|
52
|
-
|
55
|
+
ssl = SSL_new(ctx);
|
53
56
|
conn->ssl = ssl;
|
54
57
|
|
55
58
|
/* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
|
@@ -82,7 +85,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
82
85
|
|
83
86
|
StringValue(str);
|
84
87
|
|
85
|
-
used = BIO_write(conn->read, RSTRING_PTR(str), RSTRING_LEN(str));
|
88
|
+
used = BIO_write(conn->read, RSTRING_PTR(str), (int)RSTRING_LEN(str));
|
86
89
|
|
87
90
|
if(used == 0 || used == -1) {
|
88
91
|
return Qfalse;
|
@@ -134,7 +137,7 @@ VALUE engine_write(VALUE self, VALUE str) {
|
|
134
137
|
|
135
138
|
StringValue(str);
|
136
139
|
|
137
|
-
bytes = SSL_write(conn->ssl, (void*)RSTRING_PTR(str), RSTRING_LEN(str));
|
140
|
+
bytes = SSL_write(conn->ssl, (void*)RSTRING_PTR(str), (int)RSTRING_LEN(str));
|
138
141
|
if(bytes > 0) {
|
139
142
|
return INT2FIX(bytes);
|
140
143
|
}
|
@@ -168,13 +171,15 @@ VALUE engine_extract(VALUE self) {
|
|
168
171
|
}
|
169
172
|
|
170
173
|
void Init_mini_ssl(VALUE puma) {
|
174
|
+
VALUE mod, eng;
|
175
|
+
|
171
176
|
SSL_library_init();
|
172
177
|
OpenSSL_add_ssl_algorithms();
|
173
178
|
SSL_load_error_strings();
|
174
179
|
ERR_load_crypto_strings();
|
175
180
|
|
176
|
-
|
177
|
-
|
181
|
+
mod = rb_define_module_under(puma, "MiniSSL");
|
182
|
+
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
178
183
|
|
179
184
|
eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
|
180
185
|
|
data/lib/puma/cli.rb
CHANGED
@@ -321,6 +321,7 @@ module Puma
|
|
321
321
|
|
322
322
|
def graceful_stop(server)
|
323
323
|
log " - Gracefully stopping, waiting for requests to finish"
|
324
|
+
@status.stop(true) if @status
|
324
325
|
server.stop(true)
|
325
326
|
delete_pidfile
|
326
327
|
log " - Goodbye!"
|
@@ -623,6 +624,7 @@ module Puma
|
|
623
624
|
end
|
624
625
|
|
625
626
|
def stop
|
627
|
+
@status.stop(true) if @status
|
626
628
|
@server.stop(true) if @server
|
627
629
|
delete_pidfile
|
628
630
|
end
|
data/lib/puma/compat.rb
CHANGED
data/lib/puma/const.rb
CHANGED
data/lib/puma/minissl.rb
CHANGED
@@ -79,7 +79,20 @@ module Puma::MiniSSL
|
|
79
79
|
end
|
80
80
|
|
81
81
|
class Context
|
82
|
-
attr_accessor :
|
82
|
+
attr_accessor :verify_mode
|
83
|
+
|
84
|
+
attr_reader :key
|
85
|
+
attr_reader :cert
|
86
|
+
|
87
|
+
def key=(key)
|
88
|
+
raise ArgumentError, "No such key file '#{key}'" unless File.exist? key
|
89
|
+
@key = key
|
90
|
+
end
|
91
|
+
|
92
|
+
def cert=(cert)
|
93
|
+
raise ArgumentError, "No such cert file '#{cert}'" unless File.exist? cert
|
94
|
+
@cert = cert
|
95
|
+
end
|
83
96
|
end
|
84
97
|
|
85
98
|
VERIFY_NONE = 0
|
data/lib/puma/server.rb
CHANGED
@@ -423,7 +423,7 @@ module Puma
|
|
423
423
|
|
424
424
|
if no_body
|
425
425
|
lines << line_ending
|
426
|
-
client
|
426
|
+
fast_write client, lines.to_s
|
427
427
|
return keep_alive
|
428
428
|
end
|
429
429
|
|
@@ -443,16 +443,16 @@ module Puma
|
|
443
443
|
|
444
444
|
lines << line_ending
|
445
445
|
|
446
|
-
client
|
446
|
+
fast_write client, lines.to_s
|
447
447
|
|
448
448
|
res_body.each do |part|
|
449
449
|
if chunked
|
450
450
|
client.syswrite part.bytesize.to_s(16)
|
451
451
|
client.syswrite line_ending
|
452
|
-
client
|
452
|
+
fast_write client, part
|
453
453
|
client.syswrite line_ending
|
454
454
|
else
|
455
|
-
client
|
455
|
+
fast_write client, part
|
456
456
|
end
|
457
457
|
|
458
458
|
client.flush
|
@@ -562,5 +562,23 @@ module Puma
|
|
562
562
|
@persistent_wakeup.close
|
563
563
|
@notify << RESTART_COMMAND
|
564
564
|
end
|
565
|
+
|
566
|
+
def fast_write(io, str)
|
567
|
+
n = io.syswrite str
|
568
|
+
|
569
|
+
# Fast path.
|
570
|
+
return if n == str.bytesize
|
571
|
+
|
572
|
+
pos = n
|
573
|
+
left = str.bytesize - n
|
574
|
+
|
575
|
+
until left == 0
|
576
|
+
n = io.syswrite str.byteslice(pos..-1)
|
577
|
+
|
578
|
+
pos += n
|
579
|
+
left -= n
|
580
|
+
end
|
581
|
+
end
|
582
|
+
private :fast_write
|
565
583
|
end
|
566
584
|
end
|
data/puma.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "puma"
|
5
|
-
s.version = "2.0.0.
|
5
|
+
s.version = "2.0.0.b4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Evan Phoenix"]
|
9
|
-
s.date = "2012-
|
9
|
+
s.date = "2012-12-13"
|
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"]
|
13
13
|
s.extensions = ["ext/puma_http11/extconf.rb"]
|
14
14
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
|
15
|
-
s.files = ["COPYING", "Gemfile", "History.txt", "LICENSE", "Manifest.txt", "README.md", "Rakefile", "TODO", "bin/puma", "bin/pumactl", "docs/config.md", "docs/nginx.md", "ext/puma_http11/PumaHttp11Service.java", "ext/puma_http11/ext_help.h", "ext/puma_http11/extconf.rb", "ext/puma_http11/http11_parser.c", "ext/puma_http11/http11_parser.h", "ext/puma_http11/http11_parser.java.rl", "ext/puma_http11/http11_parser.rl", "ext/puma_http11/http11_parser_common.rl", "ext/puma_http11/io_buffer.c", "ext/puma_http11/mini_ssl.c", "ext/puma_http11/org/jruby/puma/Http11.java", "ext/puma_http11/org/jruby/puma/Http11Parser.java", "ext/puma_http11/org/jruby/puma/MiniSSL.java", "ext/puma_http11/puma_http11.c", "lib/puma.rb", "lib/puma/accept_nonblock.rb", "lib/puma/app/status.rb", "lib/puma/binder.rb", "lib/puma/capistrano.rb", "lib/puma/cli.rb", "lib/puma/client.rb", "lib/puma/compat.rb", "lib/puma/configuration.rb", "lib/puma/const.rb", "lib/puma/control_cli.rb", "lib/puma/daemon_ext.rb", "lib/puma/delegation.rb", "lib/puma/detect.rb", "lib/puma/events.rb", "lib/puma/io_buffer.rb", "lib/puma/java_io_buffer.rb", "lib/puma/jruby_restart.rb", "lib/puma/minissl.rb", "lib/puma/null_io.rb", "lib/puma/rack_patch.rb", "lib/puma/reactor.rb", "lib/puma/server.rb", "lib/puma/thread_pool.rb", "lib/rack/handler/puma.rb", "puma.gemspec", "tools/jungle/README.md", "tools/jungle/puma", "tools/jungle/run-puma", "test/test_app_status.rb", "test/test_cli.rb", "test/test_config.rb", "test/test_http10.rb", "test/test_http11.rb", "test/test_integration.rb", "test/test_iobuffer.rb", "test/test_null_io.rb", "test/test_persistent.rb", "test/test_puma_server.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb"]
|
15
|
+
s.files = ["COPYING", "Gemfile", "History.txt", "LICENSE", "Manifest.txt", "README.md", "Rakefile", "TODO", "bin/puma", "bin/pumactl", "docs/config.md", "docs/nginx.md", "ext/puma_http11/PumaHttp11Service.java", "ext/puma_http11/ext_help.h", "ext/puma_http11/extconf.rb", "ext/puma_http11/http11_parser.c", "ext/puma_http11/http11_parser.h", "ext/puma_http11/http11_parser.java.rl", "ext/puma_http11/http11_parser.rl", "ext/puma_http11/http11_parser_common.rl", "ext/puma_http11/io_buffer.c", "ext/puma_http11/mini_ssl.c", "ext/puma_http11/org/jruby/puma/Http11.java", "ext/puma_http11/org/jruby/puma/Http11Parser.java", "ext/puma_http11/org/jruby/puma/MiniSSL.java", "ext/puma_http11/puma_http11.c", "lib/puma.rb", "lib/puma/accept_nonblock.rb", "lib/puma/app/status.rb", "lib/puma/binder.rb", "lib/puma/capistrano.rb", "lib/puma/cli.rb", "lib/puma/client.rb", "lib/puma/compat.rb", "lib/puma/configuration.rb", "lib/puma/const.rb", "lib/puma/control_cli.rb", "lib/puma/daemon_ext.rb", "lib/puma/delegation.rb", "lib/puma/detect.rb", "lib/puma/events.rb", "lib/puma/io_buffer.rb", "lib/puma/java_io_buffer.rb", "lib/puma/jruby_restart.rb", "lib/puma/minissl.rb", "lib/puma/null_io.rb", "lib/puma/rack_patch.rb", "lib/puma/reactor.rb", "lib/puma/server.rb", "lib/puma/thread_pool.rb", "lib/rack/handler/puma.rb", "puma.gemspec", "tools/jungle/README.md", "tools/jungle/puma", "tools/jungle/run-puma", "test/test_app_status.rb", "test/test_cli.rb", "test/test_config.rb", "test/test_http10.rb", "test/test_http11.rb", "test/test_integration.rb", "test/test_iobuffer.rb", "test/test_minissl.rb", "test/test_null_io.rb", "test/test_persistent.rb", "test/test_puma_server.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb"]
|
16
16
|
s.homepage = "http://puma.io"
|
17
17
|
s.rdoc_options = ["--main", "README.md"]
|
18
18
|
s.require_paths = ["lib"]
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.rubyforge_project = "puma"
|
21
21
|
s.rubygems_version = "1.8.24"
|
22
22
|
s.summary = "Puma is a simple, fast, and highly concurrent HTTP 1.1 server for Ruby web applications"
|
23
|
-
s.test_files = ["test/test_app_status.rb", "test/test_cli.rb", "test/test_config.rb", "test/test_http10.rb", "test/test_http11.rb", "test/test_integration.rb", "test/test_iobuffer.rb", "test/test_null_io.rb", "test/test_persistent.rb", "test/test_puma_server.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb"]
|
23
|
+
s.test_files = ["test/test_app_status.rb", "test/test_cli.rb", "test/test_config.rb", "test/test_http10.rb", "test/test_http11.rb", "test/test_integration.rb", "test/test_iobuffer.rb", "test/test_minissl.rb", "test/test_null_io.rb", "test/test_persistent.rb", "test/test_puma_server.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb"]
|
24
24
|
|
25
25
|
if s.respond_to? :specification_version then
|
26
26
|
s.specification_version = 3
|
data/test/test_integration.rb
CHANGED
@@ -8,6 +8,8 @@ require 'tempfile'
|
|
8
8
|
require 'puma/cli'
|
9
9
|
require 'puma/control_cli'
|
10
10
|
|
11
|
+
# These don't run on travis because they're too fragile
|
12
|
+
|
11
13
|
class TestIntegration < Test::Unit::TestCase
|
12
14
|
def setup
|
13
15
|
@state_path = "test/test_puma.state"
|
@@ -145,4 +147,4 @@ class TestIntegration < Test::Unit::TestCase
|
|
145
147
|
data = s.read
|
146
148
|
assert_equal "HTTP/1.1 400 Bad Request\r\n\r\n", data
|
147
149
|
end
|
148
|
-
end
|
150
|
+
end unless ENV['TRAVIS']
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'puma'
|
4
|
+
require 'puma/minissl'
|
5
|
+
|
6
|
+
class TestMiniSSL < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_raises_with_invalid_key_file
|
9
|
+
ctx = Puma::MiniSSL::Context.new
|
10
|
+
|
11
|
+
exception = assert_raise(ArgumentError) { ctx.key = "/no/such/key" }
|
12
|
+
assert_equal("No such key file '/no/such/key'", exception.message)
|
13
|
+
end unless defined? JRUBY_VERSION
|
14
|
+
|
15
|
+
def test_raises_with_invalid_cert_file
|
16
|
+
ctx = Puma::MiniSSL::Context.new
|
17
|
+
|
18
|
+
exception = assert_raise(ArgumentError) { ctx.cert = "/no/such/cert" }
|
19
|
+
assert_equal("No such cert file '/no/such/cert'", exception.message)
|
20
|
+
end unless defined? JRUBY_VERSION
|
21
|
+
|
22
|
+
end
|
data/test/test_puma_server.rb
CHANGED
@@ -57,7 +57,7 @@ class TestPumaServer < Test::Unit::TestCase
|
|
57
57
|
end
|
58
58
|
|
59
59
|
assert_equal "https", body
|
60
|
-
end
|
60
|
+
end unless defined? JRUBY_VERSION
|
61
61
|
|
62
62
|
def test_proper_stringio_body
|
63
63
|
data = nil
|
@@ -102,4 +102,27 @@ class TestPumaServer < Test::Unit::TestCase
|
|
102
102
|
|
103
103
|
assert_equal body, sock.read
|
104
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
|
105
128
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.b4
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -173,6 +173,7 @@ files:
|
|
173
173
|
- test/test_http11.rb
|
174
174
|
- test/test_integration.rb
|
175
175
|
- test/test_iobuffer.rb
|
176
|
+
- test/test_minissl.rb
|
176
177
|
- test/test_null_io.rb
|
177
178
|
- test/test_persistent.rb
|
178
179
|
- test/test_puma_server.rb
|
@@ -216,6 +217,7 @@ test_files:
|
|
216
217
|
- test/test_http11.rb
|
217
218
|
- test/test_integration.rb
|
218
219
|
- test/test_iobuffer.rb
|
220
|
+
- test/test_minissl.rb
|
219
221
|
- test/test_null_io.rb
|
220
222
|
- test/test_persistent.rb
|
221
223
|
- test/test_puma_server.rb
|