diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb index 32e04b4896..116179d21f 100644 --- a/ext/openssl/lib/openssl/buffering.rb +++ b/ext/openssl/lib/openssl/buffering.rb @@ -99,8 +99,27 @@ module OpenSSL::Buffering end end + if "".respond_to?(:unpack1) + def unpack_byte(str) + str.unpack1("C") + end + else + def unpack_byte(str) + str.unpack("C").first + end + end + public + # call-seq: + # ssl.getbyte => 81 + # + # Get the next 8bit byte from `ssl`. Returns `nil` on EOF + def getbyte + byte = read(1) + byte && unpack_byte(byte) + end + ## # Reads _size_ bytes from the stream. If _buf_ is provided it must # reference a string which will receive the data. diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb index f24aabe748..3dda754870 100644 --- a/test/openssl/test_ssl.rb +++ b/test/openssl/test_ssl.rb @@ -185,6 +185,19 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase } end + def test_getbyte + start_server { |port| + server_connect(port) { |ssl| + str = +("x" * 100 + "\n") + ssl.syswrite(str) + newstr = str.bytesize.times.map { |i| + ssl.getbyte + }.pack("C*") + assert_equal(str, newstr) + } + } + end + def test_sync_close start_server do |port| begin diff --git a/test/openssl/ut_eof.rb b/test/openssl/ut_eof.rb index cf1f2d423e..7b18f43a79 100644 --- a/test/openssl/ut_eof.rb +++ b/test/openssl/ut_eof.rb @@ -4,6 +4,10 @@ require 'test/unit' if defined?(OpenSSL) module OpenSSL::TestEOF + def test_getbyte_eof + open_file("") {|f| assert_nil f.getbyte } + end + def test_eof_0 open_file("") {|f| assert_equal("", f.read(0))