From cb4d7b1a7f5dd5749bbfb750957ca458bab3eab8 Mon Sep 17 00:00:00 2001 From: akr Date: Wed, 31 Dec 2008 04:52:18 +0000 Subject: [PATCH] * ext/openssl/lib/openssl/buffering.rb (Buffering#read_nonblock): implemented. * ext/openssl/ossl_ssl.c (rb_sys_fail_path): removed. (fcntl.h): don't include. (ossl_ssl_read_internal): defined. (ossl_ssl_read): use ossl_ssl_read_internal. (ossl_ssl_read_nonblock): use ossl_ssl_read_internal. (Init_ossl_ssl): define sysread_nonblock, instead of read_nonblock. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21207 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 +++ ext/openssl/lib/openssl/buffering.rb | 21 +++++ ext/openssl/ossl_ssl.c | 136 ++++++++++----------------- 3 files changed, 81 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index 410ac58359..6e23fc1e67 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Wed Dec 31 13:49:06 2008 Tanaka Akira + + * ext/openssl/lib/openssl/buffering.rb (Buffering#read_nonblock): + implemented. + + * ext/openssl/ossl_ssl.c (rb_sys_fail_path): removed. + (fcntl.h): don't include. + (ossl_ssl_read_internal): defined. + (ossl_ssl_read): use ossl_ssl_read_internal. + (ossl_ssl_read_nonblock): use ossl_ssl_read_internal. + (Init_ossl_ssl): define sysread_nonblock, instead of read_nonblock. + Wed Dec 31 00:27:54 2008 Yukihiro Matsumoto * object.c (rb_to_float): prohibit conversion from nil to float. diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb index 5dabcd5135..095ab248ce 100644 --- a/ext/openssl/lib/openssl/buffering.rb +++ b/ext/openssl/lib/openssl/buffering.rb @@ -99,6 +99,27 @@ module Buffering ret end + def read_nonblock(maxlen, buf=nil) + if maxlen == 0 + if buf + buf.clear + return buf + else + return "" + end + end + if @rbuffer.empty? + return sysread_nonblock(maxlen, buf) + end + ret = consume_rbuff(maxlen) + if buf + buf.replace(ret) + ret = buf + end + raise EOFError if ret.empty? + ret + end + def gets(eol=$/, limit=nil) idx = @rbuffer.index(eol) until @eof diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index c4959dd6e7..310e0c5783 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -12,14 +12,6 @@ */ #include "ossl.h" -#define rb_sys_fail_path(path) rb_sys_fail(NIL_P(path) ? 0 : RSTRING_PTR(path)) - -#if defined(HAVE_FCNTL_H) || defined(_WIN32) -#include -#elif defined(HAVE_SYS_FCNTL_H) -#include -#endif - #if defined(HAVE_UNISTD_H) # include /* for read(), and write() */ #endif @@ -999,82 +991,8 @@ ossl_ssl_accept(VALUE self) return ossl_start_ssl(self, SSL_accept, "SSL_accept"); } -/* - * call-seq: - * ssl.sysread(length) => string - * ssl.sysread(length, buffer) => buffer - * - * === Parameters - * * +length+ is a positive integer. - * * +buffer+ is a string used to store the result. - */ static VALUE -ossl_ssl_read(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); - if (ssl) { - if(SSL_pending(ssl) <= 0) - rb_thread_wait_fd(FPTR_TO_FD(fptr)); - 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_io_wait_readable(FPTR_TO_FD(fptr)); - 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("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) +ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) { SSL *ssl; int ilen, nread = 0; @@ -1093,20 +1011,29 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self) Data_Get_Struct(self, SSL, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); - rb_io_set_nonblock(fptr); if (ssl) { + if(!nonblock && SSL_pending(ssl) <= 0) + rb_thread_wait_fd(FPTR_TO_FD(fptr)); for (;;){ nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str)); - switch(SSL_get_error(ssl, nread)){ + 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: + if (nonblock) { + errno = EWOULDBLOCK; + rb_sys_fail(0); + } rb_io_wait_writable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_WANT_READ: - rb_sys_fail_path(fptr->pathv); + if (nonblock) { + errno = EWOULDBLOCK; + rb_sys_fail(0); + } + rb_io_wait_readable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_SYSCALL: if(ERR_peek_error() == 0 && nread == 0) rb_eof_error(); @@ -1117,8 +1044,9 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self) } } else { + ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); rb_warning("SSL session is not started yet."); - return rb_funcall(ossl_ssl_get_io(self), rb_intern("sysread"), 2, len, str); + return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str); } end: @@ -1128,6 +1056,38 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self) return str; } + +/* + * call-seq: + * ssl.sysread(length) => string + * ssl.sysread(length, buffer) => buffer + * + * === Parameters + * * +length+ is a positive integer. + * * +buffer+ is a string used to store the result. + */ +static VALUE +ossl_ssl_read(int argc, VALUE *argv, VALUE self) +{ + return ossl_ssl_read_internal(argc, argv, self, 0); +} + +/* + * call-seq: + * ssl.sysread_nonblock(length) => string + * ssl.sysread_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) +{ + return ossl_ssl_read_internal(argc, argv, self, 1); +} + + /* * call-seq: * ssl.syswrite(string) => integer @@ -1490,9 +1450,9 @@ Init_ossl_ssl() rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0); rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0); rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1); + rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1); rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1); 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, "peer_cert", ossl_ssl_get_peer_cert, 0); rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);