Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby-openssl
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f15abeb59a5d
Choose a base ref
...
head repository: jruby/jruby-openssl
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2ef7b9c09717
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Dec 21, 2015

  1. Copy the full SHA
    9dce852 View commit details
  2. Copy the full SHA
    2ef7b9c View commit details
Showing with 81 additions and 17 deletions.
  1. +3 −6 lib/jopenssl23/openssl.rb
  2. +14 −11 src/main/java/org/jruby/ext/openssl/SSLSocket.java
  3. +64 −0 src/test/ruby/ssl/test_socket.rb
9 changes: 3 additions & 6 deletions lib/jopenssl23/openssl.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
# frozen_string_literal: false
=begin
= $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions
= Info
'OpenSSL for Ruby 2' project
Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
All rights reserved.
= Licence
This program is licenced under the same licence as Ruby.
This program is licensed under the same licence as Ruby.
(See the file 'LICENCE'.)
= Version
$Id$
=end

require 'openssl/bn'
require 'openssl/pkey'
require 'openssl/cipher'
require 'openssl/config'
require 'openssl/digest'
25 changes: 14 additions & 11 deletions src/main/java/org/jruby/ext/openssl/SSLSocket.java
Original file line number Diff line number Diff line change
@@ -733,19 +733,22 @@ private IRubyObject sysreadImpl(final ThreadContext context,
if ( ex instanceof IRubyObject ) return (IRubyObject) ex; // :wait_readable
}

ByteBuffer dst = ByteBuffer.allocate(length);
int rr = -1;
final ByteBuffer dst = ByteBuffer.allocate(length);
int read = -1;
// ensure >0 bytes read; sysread is blocking read.
while ( rr <= 0 ) {
while ( read <= 0 ) {
if ( engine == null ) {
rr = socketChannelImpl().read(dst);
read = socketChannelImpl().read(dst);
} else {
rr = read(dst, blocking);
read = read(dst, blocking);
}

if ( rr == -1 ) throw runtime.newEOFError();
if ( read == -1 ) {
if ( exception ) throw runtime.newEOFError();
return runtime.getNil();
}

if ( rr == 0 && status == SSLEngineResult.Status.BUFFER_UNDERFLOW ) {
if ( read == 0 && status == SSLEngineResult.Status.BUFFER_UNDERFLOW ) {
// If we didn't get any data back because we only read in a partial TLS record,
// instead of spinning until the rest comes in, call waitSelect to either block
// 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,
if ( ex instanceof IRubyObject ) return (IRubyObject) ex; // :wait_readable
}
}
byte[] bss = new byte[rr];
dst.position(dst.position() - rr);
dst.get(bss);
buffStr.setValue(new ByteList(bss, false));
byte[] bytesRead = new byte[read];
dst.position(dst.position() - read);
dst.get(bytesRead);
buffStr.setValue(new ByteList(bytesRead, false));
return buffStr;
}
catch (IOException ioe) {
64 changes: 64 additions & 0 deletions src/test/ruby/ssl/test_socket.rb
Original file line number Diff line number Diff line change
@@ -85,4 +85,68 @@ def test_ssl_sysread_blocking_error
end
end if RUBY_VERSION > '2.2'

def test_read_nonblock_no_exception
ssl_pair do |s1, s2|
assert_equal :wait_readable, eval('s2.read_nonblock 10, exception: false')
s1.write "abc\ndef\n"
IO.select [ s2 ]
ret = eval('s2.read_nonblock 2, exception: false')
assert_equal "ab", ret
assert_equal "c\n", s2.gets
ret = eval('s2.read_nonblock 10, exception: false')
assert_equal("def\n", ret)
s1.close
sleep 0.1
opts = { :exception => false }
assert_equal nil, s2.read_nonblock(10, opts)
end
end if RUBY_VERSION > '2.2'

private

def server
require 'socket'
host = "127.0.0.1"; port = 0
ctx = OpenSSL::SSL::SSLContext.new()
ctx.ciphers = "ADH"
server = TCPServer.new(host, port)
OpenSSL::SSL::SSLServer.new(server, ctx)
end

def client(port)
require 'socket'
host = "127.0.0.1"
ctx = OpenSSL::SSL::SSLContext.new()
ctx.ciphers = "ADH"
client = TCPSocket.new(host, port)
ssl = OpenSSL::SSL::SSLSocket.new(client, ctx)
ssl.connect
ssl.sync_close = true
ssl
end

def ssl_pair
ssl_server = server
thread = Thread.new do
ssl_server.accept.tap { ssl_server.close }
end
port = ssl_server.to_io.local_address.ip_port
ssl_client = client(port)
ssl_socket = thread.value
if block_given?
begin
yield ssl_client, ssl_socket
ensure
ssl_client.close unless ssl_client.closed?
ssl_socket.close unless ssl_socket.closed?
end
else
return ssl_client, ssl_socket
end
ensure
if thread && thread.alive?
thread.kill; thread.join
end
end

end