1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

openssl: accept moving write buffer for write_nonblock

By setting the SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER flag.
This flag was introduced at the same time as
SSL_MODE_ENABLE_PARTIAL_WRITE in OpenSSL 0.9.4 and makes usage
with non-blocking sockets much easier.

Before this, a Rubyist would need to remember the exact object
which failed to write and reuse it later when the socket became
writable again.  This causes problems when the buffer is given
by another layer of the application (e.g. a buffer is given
by a Rack middleware or application to a Rack web server).

* ext/openssl/ossl_ssl.c (ossl_sslctx_s_alloc):
  enable SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER by default
  [Bug #12126]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
normal 2016-03-31 20:33:55 +00:00
parent 8dd2435877
commit 280f732215
3 changed files with 37 additions and 1 deletions

View file

@ -1,3 +1,9 @@
Fri Apr 1 04:50:44 2016 Eric Wong <e@80x24.org>
* ext/openssl/ossl_ssl.c (ossl_sslctx_s_alloc):
enable SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER by default
[Bug #12126]
Fri Apr 1 01:13:55 2016 Benoit Daloze <eregontp@gmail.com> Fri Apr 1 01:13:55 2016 Benoit Daloze <eregontp@gmail.com>
* thread.c (update_coverage): Do not track coverage in loaded files * thread.c (update_coverage): Do not track coverage in loaded files

View file

@ -145,7 +145,8 @@ static VALUE
ossl_sslctx_s_alloc(VALUE klass) ossl_sslctx_s_alloc(VALUE klass)
{ {
SSL_CTX *ctx; SSL_CTX *ctx;
long mode = SSL_MODE_ENABLE_PARTIAL_WRITE; long mode = SSL_MODE_ENABLE_PARTIAL_WRITE |
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
VALUE obj; VALUE obj;
#ifdef SSL_MODE_RELEASE_BUFFERS #ifdef SSL_MODE_RELEASE_BUFFERS

View file

@ -280,6 +280,35 @@ module OpenSSL::TestPairM
} }
end end
def test_write_nonblock_retry
ssl_pair {|s1, s2|
# fill up a socket so we hit EAGAIN
written = String.new
n = 0
buf = 'a' * 11
case ret = s1.write_nonblock(buf, exception: false)
when :wait_readable then break
when :wait_writable then break
when Integer
written << buf
n += ret
exp = buf.bytesize
if ret != exp
buf = buf.byteslice(ret, exp - ret)
end
end while true
assert_kind_of Symbol, ret
# make more space for subsequent write:
readed = s2.read(n)
assert_equal written, readed
# this fails if SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is missing:
buf2 = Marshal.load(Marshal.dump(buf))
assert_kind_of Integer, s1.write_nonblock(buf2, exception: false)
}
end
def tcp_pair def tcp_pair
host = "127.0.0.1" host = "127.0.0.1"
serv = TCPServer.new(host, 0) serv = TCPServer.new(host, 0)