summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-03-31 20:33:55 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-03-31 20:33:55 +0000
commit280f7322151655b23c11a673b1adaab8796a358f (patch)
tree9b031057a7b6475862930da04022f527a8092c6c
parent8dd2435877fae9b13b107cb306c0f4d723451f20 (diff)
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
-rw-r--r--ChangeLog6
-rw-r--r--ext/openssl/ossl_ssl.c3
-rw-r--r--test/openssl/test_pair.rb29
3 files changed, 37 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 0fca5a1013..2ab4c9086a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* thread.c (update_coverage): Do not track coverage in loaded files
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 0e01d7c0b1..5fcd2145c3 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -145,7 +145,8 @@ static VALUE
ossl_sslctx_s_alloc(VALUE klass)
{
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;
#ifdef SSL_MODE_RELEASE_BUFFERS
diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
index 06ed3836ca..06c34442b7 100644
--- a/test/openssl/test_pair.rb
+++ b/test/openssl/test_pair.rb
@@ -280,6 +280,35 @@ module OpenSSL::TestPairM
}
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
host = "127.0.0.1"
serv = TCPServer.new(host, 0)