Skip to content

Commit 2ef7b9c

Browse files
committed
handle read_nonblock EOF as nil when exception: false (Ruby 2.3 compatibility)
1 parent 9dce852 commit 2ef7b9c

File tree

2 files changed

+78
-11
lines changed

2 files changed

+78
-11
lines changed

src/main/java/org/jruby/ext/openssl/SSLSocket.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -733,19 +733,22 @@ private IRubyObject sysreadImpl(final ThreadContext context,
733733
if ( ex instanceof IRubyObject ) return (IRubyObject) ex; // :wait_readable
734734
}
735735

736-
ByteBuffer dst = ByteBuffer.allocate(length);
737-
int rr = -1;
736+
final ByteBuffer dst = ByteBuffer.allocate(length);
737+
int read = -1;
738738
// ensure >0 bytes read; sysread is blocking read.
739-
while ( rr <= 0 ) {
739+
while ( read <= 0 ) {
740740
if ( engine == null ) {
741-
rr = socketChannelImpl().read(dst);
741+
read = socketChannelImpl().read(dst);
742742
} else {
743-
rr = read(dst, blocking);
743+
read = read(dst, blocking);
744744
}
745745

746-
if ( rr == -1 ) throw runtime.newEOFError();
746+
if ( read == -1 ) {
747+
if ( exception ) throw runtime.newEOFError();
748+
return runtime.getNil();
749+
}
747750

748-
if ( rr == 0 && status == SSLEngineResult.Status.BUFFER_UNDERFLOW ) {
751+
if ( read == 0 && status == SSLEngineResult.Status.BUFFER_UNDERFLOW ) {
749752
// If we didn't get any data back because we only read in a partial TLS record,
750753
// instead of spinning until the rest comes in, call waitSelect to either block
751754
// until the rest is available, or throw a "read would block" error if we are in
@@ -754,10 +757,10 @@ private IRubyObject sysreadImpl(final ThreadContext context,
754757
if ( ex instanceof IRubyObject ) return (IRubyObject) ex; // :wait_readable
755758
}
756759
}
757-
byte[] bss = new byte[rr];
758-
dst.position(dst.position() - rr);
759-
dst.get(bss);
760-
buffStr.setValue(new ByteList(bss, false));
760+
byte[] bytesRead = new byte[read];
761+
dst.position(dst.position() - read);
762+
dst.get(bytesRead);
763+
buffStr.setValue(new ByteList(bytesRead, false));
761764
return buffStr;
762765
}
763766
catch (IOException ioe) {

src/test/ruby/ssl/test_socket.rb

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,68 @@ def test_ssl_sysread_blocking_error
8585
end
8686
end if RUBY_VERSION > '2.2'
8787

88+
def test_read_nonblock_no_exception
89+
ssl_pair do |s1, s2|
90+
assert_equal :wait_readable, eval('s2.read_nonblock 10, exception: false')
91+
s1.write "abc\ndef\n"
92+
IO.select [ s2 ]
93+
ret = eval('s2.read_nonblock 2, exception: false')
94+
assert_equal "ab", ret
95+
assert_equal "c\n", s2.gets
96+
ret = eval('s2.read_nonblock 10, exception: false')
97+
assert_equal("def\n", ret)
98+
s1.close
99+
sleep 0.1
100+
opts = { :exception => false }
101+
assert_equal nil, s2.read_nonblock(10, opts)
102+
end
103+
end if RUBY_VERSION > '2.2'
104+
105+
private
106+
107+
def server
108+
require 'socket'
109+
host = "127.0.0.1"; port = 0
110+
ctx = OpenSSL::SSL::SSLContext.new()
111+
ctx.ciphers = "ADH"
112+
server = TCPServer.new(host, port)
113+
OpenSSL::SSL::SSLServer.new(server, ctx)
114+
end
115+
116+
def client(port)
117+
require 'socket'
118+
host = "127.0.0.1"
119+
ctx = OpenSSL::SSL::SSLContext.new()
120+
ctx.ciphers = "ADH"
121+
client = TCPSocket.new(host, port)
122+
ssl = OpenSSL::SSL::SSLSocket.new(client, ctx)
123+
ssl.connect
124+
ssl.sync_close = true
125+
ssl
126+
end
127+
128+
def ssl_pair
129+
ssl_server = server
130+
thread = Thread.new do
131+
ssl_server.accept.tap { ssl_server.close }
132+
end
133+
port = ssl_server.to_io.local_address.ip_port
134+
ssl_client = client(port)
135+
ssl_socket = thread.value
136+
if block_given?
137+
begin
138+
yield ssl_client, ssl_socket
139+
ensure
140+
ssl_client.close unless ssl_client.closed?
141+
ssl_socket.close unless ssl_socket.closed?
142+
end
143+
else
144+
return ssl_client, ssl_socket
145+
end
146+
ensure
147+
if thread && thread.alive?
148+
thread.kill; thread.join
149+
end
150+
end
151+
88152
end

0 commit comments

Comments
 (0)