Skip to content

Loading…

Encode to binary before writing with OpenSSL::SSL::SSLSocket #189

Merged
merged 2 commits into from

2 participants

@eitoball

This PR should fix MacRuby/MacRuby#188. The problem is Net::IMAP sends the content length in bytes to imap server, but OpenSSL::SSL:SSLSocket#print computes the content length in characters. That is why the patch sends the length in characters in the issue works.

The same fix in OpenSSL::Buffering is in MRI 1.9.3 or above.

@Watson1978
MacRuby member

Maybe, we might need this changing too : ruby/ruby@65ca601#L1R337

@eitoball

Maybe, we might need this changing too : ruby/ruby@65ca601#L1R337

I added the changes in ruby/ruby@65ca601 as @Watson1978 suggested. Actually, to fix #188, only #do_write needs to be fixed because Net::IMAP seems to use only #print and #print relies on #do_write.

@Watson1978 Watson1978 merged commit 5c352cf into MacRuby:master
@Watson1978
MacRuby member

Thanks !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 21, 2013
  1. @eitoball
Commits on Feb 22, 2013
  1. @eitoball
This page is out of date. Refresh to see the latest.
View
7 ext/openssl/lib/openssl/buffering.rb
@@ -115,7 +115,7 @@ def readpartial(maxlen, buf=nil)
# underlying IO is writable.
#
# So OpenSSL::Buffering#read_nonblock needs two rescue clause as follows.
- #
+ #
# # emulates blocking read (readpartial).
# begin
# result = ssl.read_nonblock(maxlen)
@@ -225,6 +225,7 @@ def eof?
def do_write(s)
@wbuffer = "" unless defined? @wbuffer
@wbuffer << s
+ @wbuffer.force_encoding(Encoding::BINARY)
@sync ||= false
if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/)
remain = idx ? idx + $/.size : @wbuffer.length
@@ -247,7 +248,7 @@ def do_write(s)
def write(s)
do_write(s)
- s.length
+ s.bytesize
end
# Writes _str_ in the non-blocking manner.
@@ -270,7 +271,7 @@ def write(s)
# underlying IO is writable.
#
# So OpenSSL::Buffering#write_nonblock needs two rescue clause as follows.
- #
+ #
# # emulates blocking write.
# begin
# result = ssl.write_nonblock(str)
View
6 test-mri/test/openssl/test_buffering.rb
@@ -63,4 +63,10 @@ def @io.syswrite *a
refute @io.sync, 'sync must not change'
end
+ def test_print
+ str = "123\r\n".force_encoding(Encoding::UTF_8)
+ @io.print(str)
+ assert(Encoding::BINARY, @io.string.encoding)
+ end
+
end if defined?(OpenSSL)
View
30 test-mri/test/openssl/test_ssl.rb
@@ -685,6 +685,36 @@ def test_unset_OP_ALL
ssl.close
}
end
+
+ def test_multibyte_read_write
+ #German a umlaut
+ auml = [%w{ C3 A4 }.join('')].pack('H*')
+ auml.force_encoding(Encoding::UTF_8)
+
+ str = nil
+ num_written = nil
+
+ server_proc = Proc.new {|ctx, ssl|
+ cmp = ssl.read
+ raw_size = cmp.size
+ cmp.force_encoding(Encoding::UTF_8)
+ assert_equal(str, cmp)
+ assert_equal(num_written, raw_size)
+ ssl.close
+ }
+
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :server_proc => server_proc){|server, port|
+ [10, 1000, 100000].each {|i|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.sync_close = true
+ ssl.connect
+ str = auml * i
+ num_written = ssl.write(str)
+ ssl.close
+ }
+ }
+ end
end
end
Something went wrong with that request. Please try again.