mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/openssl/ossl_ssl.c (ossl_ssl_read_nonblock):
OpenSSL::SSL::SSLSocket should implement read_nonblock. a patch from Aaron Patterson in [ruby-core:20277]. fix: #814 [ruby-core:20241] * ext/tk/lib/tk/menu.rb: TkOptionMenubutton.new fails to treat git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@20494 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
01d4a7ad91
commit
ffe57003cc
3 changed files with 98 additions and 7 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Thu Dec 4 16:19:18 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/openssl/ossl_ssl.c (ossl_ssl_read_nonblock):
|
||||||
|
OpenSSL::SSL::SSLSocket should implement read_nonblock. a patch
|
||||||
|
from Aaron Patterson in [ruby-core:20277]. fix: #814 [ruby-core:20241]
|
||||||
|
|
||||||
Thu Dec 4 06:04:16 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
Thu Dec 4 06:04:16 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
* ext/tk/lib/tk/menu.rb: TkOptionMenubutton.new fails to treat
|
* ext/tk/lib/tk/menu.rb: TkOptionMenubutton.new fails to treat
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
#include <rubysig.h>
|
#include <rubysig.h>
|
||||||
#include <rubyio.h>
|
#include <rubyio.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_FCNTL_H) || defined(_WIN32)
|
||||||
|
#include <fcntl.h>
|
||||||
|
#elif defined(HAVE_SYS_FCNTL_H)
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_UNISTD_H)
|
#if defined(HAVE_UNISTD_H)
|
||||||
# include <unistd.h> /* for read(), and write() */
|
# include <unistd.h> /* for read(), and write() */
|
||||||
#endif
|
#endif
|
||||||
|
@ -1047,9 +1053,72 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ID id_sysread = rb_intern("sysread");
|
|
||||||
rb_warning("SSL session is not started yet.");
|
rb_warning("SSL session is not started yet.");
|
||||||
return rb_funcall(ossl_ssl_get_io(self), id_sysread, 2, len, str);
|
return rb_funcall(ossl_ssl_get_io(self), rb_intern("read_nonblock"), 2, len, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
rb_str_set_len(str, nread);
|
||||||
|
OBJ_TAINT(str);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* ssl.read_nonblock(length) => string
|
||||||
|
* ssl.read_nonblock(length, buffer) => buffer
|
||||||
|
*
|
||||||
|
* === Parameters
|
||||||
|
* * +length+ is a positive integer.
|
||||||
|
* * +buffer+ is a string used to store the result.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
|
||||||
|
{
|
||||||
|
SSL *ssl;
|
||||||
|
int ilen, nread = 0;
|
||||||
|
VALUE len, str;
|
||||||
|
rb_io_t *fptr;
|
||||||
|
|
||||||
|
rb_scan_args(argc, argv, "11", &len, &str);
|
||||||
|
ilen = NUM2INT(len);
|
||||||
|
if(NIL_P(str)) str = rb_str_new(0, ilen);
|
||||||
|
else{
|
||||||
|
StringValue(str);
|
||||||
|
rb_str_modify(str);
|
||||||
|
rb_str_resize(str, ilen);
|
||||||
|
}
|
||||||
|
if(ilen == 0) return str;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, SSL, ssl);
|
||||||
|
GetOpenFile(ossl_ssl_get_io(self), fptr);
|
||||||
|
rb_io_set_nonblock(fptr);
|
||||||
|
if (ssl) {
|
||||||
|
for (;;){
|
||||||
|
nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str));
|
||||||
|
switch(SSL_get_error(ssl, nread)){
|
||||||
|
case SSL_ERROR_NONE:
|
||||||
|
goto end;
|
||||||
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
|
rb_eof_error();
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
rb_io_wait_writable(FPTR_TO_FD(fptr));
|
||||||
|
continue;
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
rb_sys_fail(fptr->path);
|
||||||
|
continue;
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
|
||||||
|
rb_sys_fail(0);
|
||||||
|
default:
|
||||||
|
ossl_raise(eSSLError, "SSL_read:");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_warning("SSL session is not started yet.");
|
||||||
|
return rb_funcall(ossl_ssl_get_io(self), rb_intern("sysread"), 2, len, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -1423,6 +1492,7 @@ Init_ossl_ssl()
|
||||||
rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1);
|
rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1);
|
||||||
rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1);
|
rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1);
|
||||||
rb_define_method(cSSLSocket, "sysclose", ossl_ssl_close, 0);
|
rb_define_method(cSSLSocket, "sysclose", ossl_ssl_close, 0);
|
||||||
|
rb_define_method(cSSLSocket, "read_nonblock", ossl_ssl_read_nonblock, -1);
|
||||||
rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0);
|
rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0);
|
||||||
rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0);
|
rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0);
|
||||||
rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
|
rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
|
||||||
|
|
|
@ -155,6 +155,21 @@ class OpenSSL::TestSSL < Test::Unit::TestCase
|
||||||
assert_equal(ctx.setup, nil)
|
assert_equal(ctx.setup, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_ssl_read_nonblock
|
||||||
|
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) { |server, port|
|
||||||
|
sock = TCPSocket.new("127.0.0.1", port)
|
||||||
|
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
||||||
|
ssl.sync_close = true
|
||||||
|
ssl.connect
|
||||||
|
assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { ssl.read_nonblock(100) }
|
||||||
|
ssl.write("abc\n")
|
||||||
|
IO.select [ssl]
|
||||||
|
assert_equal('a', ssl.read_nonblock(1))
|
||||||
|
assert_equal("bc\n", ssl.read_nonblock(100))
|
||||||
|
assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { ssl.read_nonblock(100) }
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def test_connect_and_close
|
def test_connect_and_close
|
||||||
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
|
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
|
||||||
sock = TCPSocket.new("127.0.0.1", port)
|
sock = TCPSocket.new("127.0.0.1", port)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue