mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
More gracefully deal with SSL sessions. Fixes #1002
The problem was a few points: * We were not clearing the reactor on a normal stop, which is what is used in a phased restart. * On close, SSL sockets were not sending the shutdown message. * SSL sockets that were completely uninitialized ended up sitting in reactor and could not actually be shutdown because there were not initialized.
This commit is contained in:
parent
2f7364f170
commit
46416cb49e
4 changed files with 66 additions and 2 deletions
|
@ -3,6 +3,8 @@ require 'mkmf'
|
|||
dir_config("puma_http11")
|
||||
|
||||
unless ENV["DISABLE_SSL"]
|
||||
dir_config("openssl")
|
||||
|
||||
if %w'crypto libeay32'.find {|crypto| have_library(crypto, 'BIO_read')} and
|
||||
%w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')}
|
||||
|
||||
|
|
|
@ -327,6 +327,33 @@ VALUE engine_extract(VALUE self) {
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE engine_shutdown(VALUE self) {
|
||||
ms_conn* conn;
|
||||
int ok, err;
|
||||
char buf[512];
|
||||
|
||||
Data_Get_Struct(self, ms_conn, conn);
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
ok = SSL_shutdown(conn->ssl);
|
||||
if (ok == 0) {
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
VALUE engine_init(VALUE self) {
|
||||
ms_conn* conn;
|
||||
int ok, err;
|
||||
char buf[512];
|
||||
|
||||
Data_Get_Struct(self, ms_conn, conn);
|
||||
|
||||
return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
VALUE engine_peercert(VALUE self) {
|
||||
ms_conn* conn;
|
||||
X509* cert;
|
||||
|
@ -394,6 +421,10 @@ void Init_mini_ssl(VALUE puma) {
|
|||
rb_define_method(eng, "write", engine_write, 1);
|
||||
rb_define_method(eng, "extract", engine_extract, 0);
|
||||
|
||||
rb_define_method(eng, "shutdown", engine_shutdown, 0);
|
||||
|
||||
rb_define_method(eng, "init?", engine_init, 0);
|
||||
|
||||
rb_define_method(eng, "peercert", engine_peercert, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,38 @@ module Puma
|
|||
end
|
||||
|
||||
def close
|
||||
@socket.close
|
||||
begin
|
||||
# Try to setup (so that we can then close them) any
|
||||
# partially initialized sockets.
|
||||
while @engine.init?
|
||||
# Don't let this socket hold this loop forever.
|
||||
# If it can't send more packets within 1s, then
|
||||
# give up.
|
||||
return unless IO.select([@socket], nil, nil, 1)
|
||||
begin
|
||||
read_nonblock(1024)
|
||||
rescue Errno::EAGAIN
|
||||
end
|
||||
end
|
||||
|
||||
done = @engine.shutdown
|
||||
|
||||
while true
|
||||
enc = @engine.extract
|
||||
@socket.write enc
|
||||
|
||||
notify = @socket.sysread(1024)
|
||||
|
||||
@engine.inject notify
|
||||
done = @engine.shutdown
|
||||
|
||||
break if done
|
||||
end
|
||||
rescue IOError, SystemCallError
|
||||
# nothing
|
||||
ensure
|
||||
@socket.close
|
||||
end
|
||||
end
|
||||
|
||||
def peeraddr
|
||||
|
|
|
@ -358,7 +358,7 @@ module Puma
|
|||
|
||||
graceful_shutdown if @status == :stop || @status == :restart
|
||||
if queue_requests
|
||||
@reactor.clear! if @status == :restart
|
||||
@reactor.clear!
|
||||
@reactor.shutdown
|
||||
end
|
||||
rescue Exception => e
|
||||
|
|
Loading…
Reference in a new issue