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.

@@ -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
@@ -112,6 +112,10 @@ namespace :test do
112
112
  end
113
113
 
114
114
  desc "Run all tests"
115
- task :all => [:test, "test:integration"]
115
+ if defined?(JRUBY_VERSION) and ENV['TRAVIS']
116
+ task :all => :test
117
+ else
118
+ task :all => [:test, "test:integration"]
119
+ end
116
120
  end
117
121
 
@@ -107,6 +107,8 @@ static VALUE buf_append2(int argc, VALUE* argv, VALUE self) {
107
107
  memcpy(b->cur, RSTRING_PTR(str), str_len);
108
108
  b->cur += str_len;
109
109
  }
110
+
111
+ return self;
110
112
  }
111
113
 
112
114
  static VALUE buf_to_str(VALUE self) {
@@ -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
- SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
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
- SSL* ssl = SSL_new(ctx);
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
- VALUE mod = rb_define_module_under(puma, "MiniSSL");
177
- VALUE eng = rb_define_class_under(mod, "Engine", rb_cObject);
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
 
@@ -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
@@ -4,4 +4,8 @@ class String
4
4
  unless method_defined? :bytesize
5
5
  alias_method :bytesize, :size
6
6
  end
7
+
8
+ unless method_defined? :byteslice
9
+ alias_method :byteslice, :[]
10
+ end
7
11
  end
@@ -28,7 +28,7 @@ module Puma
28
28
  # too taxing on performance.
29
29
  module Const
30
30
 
31
- PUMA_VERSION = VERSION = "2.0.0.b3".freeze
31
+ PUMA_VERSION = VERSION = "2.0.0.b4".freeze
32
32
 
33
33
  FAST_TRACK_KA_TIMEOUT = 0.2
34
34
 
@@ -79,7 +79,20 @@ module Puma::MiniSSL
79
79
  end
80
80
 
81
81
  class Context
82
- attr_accessor :key, :cert, :verify_mode
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
@@ -423,7 +423,7 @@ module Puma
423
423
 
424
424
  if no_body
425
425
  lines << line_ending
426
- client.syswrite lines.to_s
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.syswrite lines.to_s
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.syswrite part
452
+ fast_write client, part
453
453
  client.syswrite line_ending
454
454
  else
455
- client.syswrite part
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
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "puma"
5
- s.version = "2.0.0.b3"
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-11-22"
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
@@ -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
@@ -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.b3
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-11-22 00:00:00.000000000 Z
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