diff options
author | gotoyuzo <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-08-22 07:28:45 +0000 |
---|---|---|
committer | gotoyuzo <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-08-22 07:28:45 +0000 |
commit | 7b505316a49875bd3ae5ee15a91a392cf55565e9 (patch) | |
tree | 2ab6f5177e0b0ce985f1aa522cbc1e1d95132319 /ext/openssl | |
parent | b21ef0f47abd3b1d89f9d313cdd347a87a9138f8 (diff) | |
download | ruby-7b505316a49875bd3ae5ee15a91a392cf55565e9.tar.gz |
* ext/openssl/ossl_ssl.c (ossl_ssl_read):
- should return an empty string if specified length to read is 0.
- should check for pending data and wait for fd before reading.
- call underlying IO's sysread if SSL session is not started.
[ruby-dev:24072], [ruby-dev:24075]
* ext/openssl/ossl_ssl.c (ossl_ssl_write):
- call underlying IO's syswrite if SSL session is not started.
* ext/openssl/ossl_ssl.c (ossl_ssl_pending): new method
OpenSSL::SSL#pending.
* ext/openssl/lib/openssl/buffering.rb: should not use select.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6806 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl')
-rw-r--r-- | ext/openssl/lib/openssl/buffering.rb | 3 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.c | 47 |
2 files changed, 27 insertions, 23 deletions
diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb index 6fcb143fc8..31dcdf1f9a 100644 --- a/ext/openssl/lib/openssl/buffering.rb +++ b/ext/openssl/lib/openssl/buffering.rb @@ -31,9 +31,6 @@ module Buffering def fill_rbuff @rbuffer = "" unless defined? @rbuffer begin - if self.respond_to?(:to_io) - IO.select([self.to_io], nil, nil) - end @rbuffer << self.sysread(BLOCK_SIZE) rescue EOFError @eof = true diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 031f2334f7..4d8a64fc11 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -492,6 +492,7 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self) OpenFile *fptr; Data_Get_Struct(self, SSL, ssl); + GetOpenFile(ossl_ssl_get_io(self), fptr); rb_scan_args(argc, argv, "11", &len, &str); ilen = NUM2INT(len); if(NIL_P(str)) str = rb_str_new(0, ilen); @@ -500,37 +501,34 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self) rb_str_modify(str); rb_str_resize(str, ilen); } + if(ilen == 0) return str; if (ssl) { + if(SSL_pending(ssl) <= 0) + rb_thread_wait_fd(fileno(fptr->f)); for (;;){ nread = SSL_read(ssl, RSTRING(str)->ptr, RSTRING(str)->len); switch(SSL_get_error(ssl, nread)){ case SSL_ERROR_NONE: goto end; case SSL_ERROR_ZERO_RETURN: - ossl_raise(rb_eEOFError, "End of file reached"); + rb_eof_error(); case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: rb_thread_schedule(); continue; + case SSL_ERROR_SYSCALL: + if(ERR_peek_error() == 0 && nread == 0) rb_eof_error(); + ossl_raise(eSSLError, "SSL_read: %s", strerror(errno)); default: ossl_raise(eSSLError, "SSL_read:"); } } } else { + ID id_sysread = rb_intern("sysread"); rb_warning("SSL session is not started yet."); - GetOpenFile(ossl_ssl_get_io(self), fptr); - rb_io_check_readable(fptr); - TRAP_BEG; - nread = read(fileno(fptr->f), RSTRING(str)->ptr, RSTRING(str)->len); - TRAP_END; - if (nread == 0) { - ossl_raise(rb_eEOFError, "End of file reached"); - } - if(nread < 0) { - ossl_raise(eSSLError, "read:%s", strerror(errno)); - } + return rb_funcall(ossl_ssl_get_io(self), id_sysread, 2, len, str); } end: @@ -546,7 +544,6 @@ ossl_ssl_write(VALUE self, VALUE str) { SSL *ssl; int nwrite = 0; - OpenFile *fptr; FILE *fp; Data_Get_Struct(self, SSL, ssl); @@ -568,14 +565,9 @@ ossl_ssl_write(VALUE self, VALUE str) } } else { + ID id_syswrite = rb_intern("syswrite"); rb_warning("SSL session is not started yet."); - GetOpenFile(ossl_ssl_get_io(self), fptr); - rb_io_check_writable(fptr); - fp = GetWriteFile(fptr); - nwrite = write(fileno(fp), RSTRING(str)->ptr, RSTRING(str)->len); - if (nwrite < 0) { - ossl_raise(eSSLError, "write:%s", strerror(errno)); - } + return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str); } end: @@ -705,6 +697,20 @@ ossl_ssl_get_state(VALUE self) return ret; } +static VALUE +ossl_ssl_pending(VALUE self) +{ + SSL *ssl; + + Data_Get_Struct(self, SSL, ssl); + if (!ssl) { + rb_warning("SSL session is not started yet."); + return Qnil; + } + + return INT2NUM(SSL_pending(ssl)); +} + void Init_ossl_ssl() { @@ -744,6 +750,7 @@ Init_ossl_ssl() rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0); rb_define_method(cSSLSocket, "cipher", ossl_ssl_get_cipher, 0); rb_define_method(cSSLSocket, "state", ossl_ssl_get_state, 0); + rb_define_method(cSSLSocket, "pending", ossl_ssl_pending, 0); #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2FIX(SSL_##x)) |