mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/openssl/ossl_ssl.c (ossl_start_ssl, ossl_ssl_read,
ossl_ssl_write):
- need to set errno on Win32 platform.
- should call rb_sys_fail instead of rasing SSLError if
SSL_ERROR_SYSCALL occured.
- should wait for that the underlying IO become readable or
writable if the error was SSL_ERROR_WANT_READ or
SSL_ERROR_WANT_WRITE. [ruby-dev:25795]
* ext/openssl/lib/openssl/buffering.rb
(Buffering#initialize): should set @eof and @rbuffer.
(Buffering#fill_rbuff): should rescue Errno::EAGAIN.
(Buffering#consume_rbuf): pointless eof flag resetting is deleted.
(Buffering#read): should return an empty string if the specified
size is zero.
(Buffering#readpartial): new method.
(Buffering#readline): fix typo.
(Buffering#getc): return the first character of string correctly.
(Buffering#each): fix typo. suggested by Brian Ollenberger.
(Buffering#readchar): fix typo.
(Buffering#eof?): should read again it the input buffer is empty.
(Buffering#do_write): should rescue Errno::EAGAIN.
(Buffering#puts): use "\n" as the output field separator.
* ext/openssl/lib/openssl/ssl.rb: set non-blocking flag to the
underlying IO.
* ext/openssl/extconf.rb: get rid of GNUmakefile generation.
* text/openssl/test_pair.rb: test for IO like methods.
* test/ruby/ut_eof.rb: test about empty file.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@8104 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
64eaecb8a8
commit
24cb3707eb
6 changed files with 158 additions and 77 deletions
41
ChangeLog
41
ChangeLog
|
|
@ -1,3 +1,38 @@
|
|||
Wed Feb 16 02:55:21 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||
|
||||
* ext/openssl/ossl_ssl.c (ossl_start_ssl, ossl_ssl_read,
|
||||
ossl_ssl_write):
|
||||
- need to set errno on Win32 platform.
|
||||
- should call rb_sys_fail instead of rasing SSLError if
|
||||
SSL_ERROR_SYSCALL occured.
|
||||
- should wait for that the underlying IO become readable or
|
||||
writable if the error was SSL_ERROR_WANT_READ or
|
||||
SSL_ERROR_WANT_WRITE. [ruby-dev:25795]
|
||||
|
||||
* ext/openssl/lib/openssl/buffering.rb
|
||||
(Buffering#initialize): should set @eof and @rbuffer.
|
||||
(Buffering#fill_rbuff): should rescue Errno::EAGAIN.
|
||||
(Buffering#consume_rbuf): pointless eof flag resetting is deleted.
|
||||
(Buffering#read): should return an empty string if the specified
|
||||
size is zero.
|
||||
(Buffering#readpartial): new method.
|
||||
(Buffering#readline): fix typo.
|
||||
(Buffering#getc): return the first character of string correctly.
|
||||
(Buffering#each): fix typo. suggested by Brian Ollenberger.
|
||||
(Buffering#readchar): fix typo.
|
||||
(Buffering#eof?): should read again it the input buffer is empty.
|
||||
(Buffering#do_write): should rescue Errno::EAGAIN.
|
||||
(Buffering#puts): use "\n" as the output field separator.
|
||||
|
||||
* ext/openssl/lib/openssl/ssl.rb: set non-blocking flag to the
|
||||
underlying IO.
|
||||
|
||||
* ext/openssl/extconf.rb: get rid of GNUmakefile generation.
|
||||
|
||||
* text/openssl/test_pair.rb: test for IO like methods.
|
||||
|
||||
* test/ruby/ut_eof.rb: test about empty file.
|
||||
|
||||
Mon Mar 7 10:22:06 2005 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||
|
||||
* lib/un.rb: should use OptionParser. (backported form HEAD)
|
||||
|
|
@ -361,9 +396,9 @@ Fri Feb 11 17:40:42 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
|||
|
||||
Fri Feb 11 11:33:53 2005 Tanaka Akira <akr@m17n.org>
|
||||
|
||||
* lib/open-uri.rb (URI::HTTP#proxy_open): new option supported:
|
||||
:http_basic_authentication.
|
||||
suggested by Kent Sibilev. [ruby-core:4392]
|
||||
* lib/open-uri.rb (URI::HTTP#proxy_open): new option supported:
|
||||
:http_basic_authentication.
|
||||
suggested by Kent Sibilev. [ruby-core:4392]
|
||||
|
||||
Fri Feb 11 06:30:07 2005 George Ogata <g_ogata@optushome.com.au>
|
||||
|
||||
|
|
|
|||
|
|
@ -113,33 +113,5 @@ have_struct_member("EVP_CIPHER_CTX", "engine", "openssl/evp.h")
|
|||
have_struct_member("X509_ATTRIBUTE", "single", "openssl/x509.h")
|
||||
|
||||
message "=== Checking done. ===\n"
|
||||
$distcleanfiles << "GNUmakefile" << "dep"
|
||||
create_makefile("openssl")
|
||||
if /gcc/ =~ CONFIG["CC"]
|
||||
File.open("GNUmakefile", "w") {|f|
|
||||
f.print <<EOD
|
||||
include Makefile
|
||||
|
||||
SRCS = $(OBJS:.o=.c)
|
||||
|
||||
test-link: $(OBJS)
|
||||
$(CC) $(DLDFLAGS) #{OUTFLAG}.testlink $(OBJS) $(LIBPATH) $(LIBS) $(LOCAL_LIBS)
|
||||
@$(RM) .testlink
|
||||
@echo "Done."
|
||||
|
||||
dep:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(SRCS) -MM | \\
|
||||
$(RUBY) -p -e 'BEGIN{S = []' \\
|
||||
-e 'while !ARGV.empty? and /^(\\w+)=(.*)/ =~ ARGV[0]' \\
|
||||
-e 'S << [/\#{Regexp.quote($$2)}\\//, "$$(\#{$$1})/"]' \\
|
||||
-e 'ARGV.shift' \\
|
||||
-e 'end' \\
|
||||
-e '}' -e 'S.each(&method(:gsub!))' -- \\
|
||||
'topdir=$(topdir)' 'srcdir=$(srcdir)' 'hdrdir=$(hdrdir)' \\
|
||||
> dep
|
||||
|
||||
include dep
|
||||
EOD
|
||||
}
|
||||
end
|
||||
message "Done.\n"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ module Buffering
|
|||
BLOCK_SIZE = 1024*16
|
||||
|
||||
def initialize(*args)
|
||||
@eof = false
|
||||
@rbuffer = ""
|
||||
@sync = @io.sync
|
||||
end
|
||||
|
||||
|
|
@ -29,17 +31,17 @@ module Buffering
|
|||
private
|
||||
|
||||
def fill_rbuff
|
||||
@rbuffer = "" unless defined? @rbuffer
|
||||
begin
|
||||
@rbuffer << self.sysread(BLOCK_SIZE)
|
||||
rescue Errno::EAGAIN
|
||||
retry
|
||||
rescue EOFError
|
||||
@eof = true
|
||||
end
|
||||
end
|
||||
|
||||
def consume_rbuff(size=nil)
|
||||
if @rbuffer.size == 0
|
||||
@eof = nil
|
||||
if @rbuffer.empty?
|
||||
nil
|
||||
else
|
||||
size = @rbuffer.size unless size
|
||||
|
|
@ -52,8 +54,14 @@ module Buffering
|
|||
public
|
||||
|
||||
def read(size=nil, buf=nil)
|
||||
fill_rbuff unless defined? @rbuffer
|
||||
@eof ||= nil
|
||||
if size == 0
|
||||
if buf
|
||||
buf.clear
|
||||
else
|
||||
buf = ""
|
||||
end
|
||||
return @eof ? nil : buf
|
||||
end
|
||||
until @eof
|
||||
break if size && size <= @rbuffer.size
|
||||
fill_rbuff
|
||||
|
|
@ -66,10 +74,33 @@ module Buffering
|
|||
(size && ret.empty?) ? nil : ret
|
||||
end
|
||||
|
||||
def readpartial(maxlen, buf=nil)
|
||||
if maxlen == 0
|
||||
if buf
|
||||
buf.clear
|
||||
else
|
||||
buf = ""
|
||||
end
|
||||
return @eof ? nil : buf
|
||||
end
|
||||
if @rbuffer.empty?
|
||||
begin
|
||||
return sysread(maxlen, buf)
|
||||
rescue Errno::EAGAIN
|
||||
retry
|
||||
end
|
||||
end
|
||||
ret = consume_rbuff(maxlen)
|
||||
if buf
|
||||
buf.replace(ret)
|
||||
ret = buf
|
||||
end
|
||||
raise EOFError if ret.empty?
|
||||
ret
|
||||
end
|
||||
|
||||
def gets(eol=$/)
|
||||
fill_rbuff unless defined? @rbuffer
|
||||
idx = @rbuffer.index(eol)
|
||||
@eof ||= nil
|
||||
until @eof
|
||||
break if idx
|
||||
fill_rbuff
|
||||
|
|
@ -84,7 +115,7 @@ module Buffering
|
|||
end
|
||||
|
||||
def each(eol=$/)
|
||||
while line = self.gets(eol?)
|
||||
while line = self.gets(eol)
|
||||
yield line
|
||||
end
|
||||
end
|
||||
|
|
@ -99,13 +130,13 @@ module Buffering
|
|||
end
|
||||
|
||||
def readline(eol=$/)
|
||||
raise EOFErorr if eof?
|
||||
raise EOFError if eof?
|
||||
gets(eol)
|
||||
end
|
||||
|
||||
def getc
|
||||
c = read(1)
|
||||
c ? c.to_i : nil
|
||||
c ? c[0] : nil
|
||||
end
|
||||
|
||||
def each_byte
|
||||
|
|
@ -115,7 +146,7 @@ module Buffering
|
|||
end
|
||||
|
||||
def readchar
|
||||
raise EOFErorr if eof?
|
||||
raise EOFError if eof?
|
||||
getc
|
||||
end
|
||||
|
||||
|
|
@ -124,8 +155,8 @@ module Buffering
|
|||
end
|
||||
|
||||
def eof?
|
||||
@eof ||= nil
|
||||
@eof && @rbuffer.size == 0
|
||||
fill_rbuff if !@eof && @rbuffer.empty?
|
||||
@eof && @rbuffer.empty?
|
||||
end
|
||||
alias eof eof?
|
||||
|
||||
|
|
@ -142,7 +173,12 @@ module Buffering
|
|||
remain = idx ? idx + $/.size : @wbuffer.length
|
||||
nwritten = 0
|
||||
while remain > 0
|
||||
nwrote = syswrite(@wbuffer[nwritten,remain])
|
||||
str = @wbuffer[nwritten,remain]
|
||||
begin
|
||||
nwrote = syswrite(str)
|
||||
rescue Errno::EAGAIN
|
||||
retry
|
||||
end
|
||||
remain -= nwrote
|
||||
nwritten += nwrote
|
||||
end
|
||||
|
|
@ -164,10 +200,13 @@ module Buffering
|
|||
|
||||
def puts(*args)
|
||||
s = ""
|
||||
if args.empty?
|
||||
s << "\n"
|
||||
end
|
||||
args.each{|arg|
|
||||
s << arg.to_s
|
||||
unless /#{$/}\z/o =~ s
|
||||
s << $/
|
||||
if $/ && /\n\z/ !~ s
|
||||
s << "\n"
|
||||
end
|
||||
}
|
||||
do_write(s)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
require "openssl"
|
||||
require "openssl/buffering"
|
||||
require "fcntl"
|
||||
|
||||
module OpenSSL
|
||||
module SSL
|
||||
|
|
@ -49,9 +50,19 @@ module OpenSSL
|
|||
end
|
||||
end
|
||||
|
||||
module Nonblock
|
||||
def initialize(*args)
|
||||
flag = File::NONBLOCK
|
||||
flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
|
||||
@io.fcntl(Fcntl::F_SETFL, flag)
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
class SSLSocket
|
||||
include Buffering
|
||||
include SocketForwarder
|
||||
include Nonblock
|
||||
|
||||
def post_connection_check(hostname)
|
||||
check_common_name = true
|
||||
|
|
|
|||
|
|
@ -433,52 +433,56 @@ ossl_ssl_setup(VALUE self)
|
|||
return Qtrue;
|
||||
}
|
||||
|
||||
static void
|
||||
ossl_start_ssl(SSL *ssl, int (*func)())
|
||||
#ifdef _WIN32
|
||||
#define ssl_get_error(ssl, ret) \
|
||||
(errno = WSAGetLastError(), SSL_get_error(ssl, ret))
|
||||
#else
|
||||
#define ssl_get_error(ssl, ret) SSL_get_error(ssl, ret)
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
ossl_start_ssl(VALUE self, int (*func)())
|
||||
{
|
||||
SSL *ssl;
|
||||
OpenFile *fptr;
|
||||
VALUE cb;
|
||||
int ret;
|
||||
|
||||
Data_Get_Struct(self, SSL, ssl);
|
||||
GetOpenFile(ossl_ssl_get_io(self), fptr);
|
||||
cb = ossl_sslctx_get_verify_cb(ossl_ssl_get_ctx(self));
|
||||
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)cb);
|
||||
for(;;){
|
||||
if((ret = func(ssl)) > 0) break;
|
||||
switch(SSL_get_error(ssl, ret)){
|
||||
switch(ssl_get_error(ssl, ret)){
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
rb_io_wait_writable(fileno(fptr->f));
|
||||
continue;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
rb_thread_schedule();
|
||||
continue;
|
||||
rb_io_wait_readable(fileno(fptr->f));
|
||||
continue;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
rb_sys_fail(0);
|
||||
default:
|
||||
ossl_raise(eSSLError, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ossl_ssl_connect(VALUE self)
|
||||
{
|
||||
SSL *ssl;
|
||||
VALUE cb;
|
||||
|
||||
ossl_ssl_setup(self);
|
||||
Data_Get_Struct(self, SSL, ssl);
|
||||
cb = ossl_sslctx_get_verify_cb(ossl_ssl_get_ctx(self));
|
||||
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)cb);
|
||||
ossl_start_ssl(ssl, SSL_connect);
|
||||
|
||||
return self;
|
||||
return ossl_start_ssl(self, SSL_connect);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ossl_ssl_accept(VALUE self)
|
||||
{
|
||||
SSL *ssl;
|
||||
VALUE cb;
|
||||
|
||||
ossl_ssl_setup(self);
|
||||
Data_Get_Struct(self, SSL, ssl);
|
||||
cb = ossl_sslctx_get_verify_cb(ossl_ssl_get_ctx(self));
|
||||
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)cb);
|
||||
ossl_start_ssl(ssl, SSL_accept);
|
||||
|
||||
return self;
|
||||
return ossl_start_ssl(self, SSL_accept);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
@ -506,18 +510,20 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
|
|||
rb_thread_wait_fd(fileno(fptr->f));
|
||||
for (;;){
|
||||
nread = SSL_read(ssl, RSTRING(str)->ptr, RSTRING(str)->len);
|
||||
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:
|
||||
rb_io_wait_writable(fileno(fptr->f));
|
||||
continue;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
rb_thread_schedule();
|
||||
rb_io_wait_readable(fileno(fptr->f));
|
||||
continue;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
|
||||
ossl_raise(eSSLError, "SSL_read: %s", strerror(errno));
|
||||
rb_sys_fail(0);
|
||||
default:
|
||||
ossl_raise(eSSLError, "SSL_read:");
|
||||
}
|
||||
|
|
@ -542,21 +548,26 @@ ossl_ssl_write(VALUE self, VALUE str)
|
|||
{
|
||||
SSL *ssl;
|
||||
int nwrite = 0;
|
||||
FILE *fp;
|
||||
OpenFile *fptr;
|
||||
|
||||
StringValue(str);
|
||||
Data_Get_Struct(self, SSL, ssl);
|
||||
GetOpenFile(ossl_ssl_get_io(self), fptr);
|
||||
|
||||
if (ssl) {
|
||||
for (;;){
|
||||
nwrite = SSL_write(ssl, RSTRING(str)->ptr, RSTRING(str)->len);
|
||||
switch(SSL_get_error(ssl, nwrite)){
|
||||
switch(ssl_get_error(ssl, nwrite)){
|
||||
case SSL_ERROR_NONE:
|
||||
goto end;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
rb_io_wait_writable(fileno(fptr->f));
|
||||
continue;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
rb_thread_schedule();
|
||||
continue;
|
||||
rb_io_wait_readable(fileno(fptr->f));
|
||||
continue;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
rb_sys_fail(0);
|
||||
default:
|
||||
ossl_raise(eSSLError, "SSL_write:");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,19 @@ module TestEOF
|
|||
}
|
||||
end
|
||||
|
||||
def test_eof_2
|
||||
open_file("") {|f|
|
||||
assert_equal("", f.read)
|
||||
assert(f.eof?)
|
||||
}
|
||||
end
|
||||
|
||||
def test_eof_3
|
||||
open_file("") {|f|
|
||||
assert(f.eof?)
|
||||
}
|
||||
end
|
||||
|
||||
module Seek
|
||||
def open_file_seek(content, pos)
|
||||
open_file(content) do |f|
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue