Skip to content

Commit a7f2d22

Browse files
authored
Merge pull request #743 from ruby/close-read-write
Introduce basic support for `close_read` and `close_write`.
2 parents 362a69a + 0697f2f commit a7f2d22

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

lib/openssl/ssl.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,32 @@ def session
459459
nil
460460
end
461461

462+
# Close the stream for reading.
463+
# This method is ignored by OpenSSL as there is no reasonable way to
464+
# implement it, but exists for compatibility with IO.
465+
def close_read
466+
# Unsupported and ignored.
467+
# Just don't read any more.
468+
end
469+
470+
# Closes the stream for writing. The behavior of this method depends on
471+
# the version of OpenSSL and the TLS protocol in use.
472+
#
473+
# - Sends a 'close_notify' alert to the peer.
474+
# - Does not wait for the peer's 'close_notify' alert in response.
475+
#
476+
# In TLS 1.2 and earlier:
477+
# - On receipt of a 'close_notify' alert, responds with a 'close_notify'
478+
# alert of its own and close down the connection immediately,
479+
# discarding any pending writes.
480+
#
481+
# Therefore, on TLS 1.2, this method will cause the connection to be
482+
# completely shut down. On TLS 1.3, the connection will remain open for
483+
# reading only.
484+
def close_write
485+
stop
486+
end
487+
462488
private
463489

464490
def using_anon_cipher?

test/openssl/test_ssl.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,30 @@ def test_socket_open_with_local_address_port_context
117117
}
118118
end
119119

120+
def test_socket_close_write
121+
server_proc = proc do |ctx, ssl|
122+
message = ssl.read
123+
ssl.write(message)
124+
ssl.close_write
125+
ensure
126+
ssl.close
127+
end
128+
129+
start_server(server_proc: server_proc) do |port|
130+
ctx = OpenSSL::SSL::SSLContext.new
131+
ssl = OpenSSL::SSL::SSLSocket.open("127.0.0.1", port, context: ctx)
132+
ssl.sync_close = true
133+
ssl.connect
134+
135+
message = "abc"*1024
136+
ssl.write message
137+
ssl.close_write
138+
assert_equal message, ssl.read
139+
ensure
140+
ssl&.close
141+
end
142+
end
143+
120144
def test_add_certificate
121145
ctx_proc = -> ctx {
122146
# Unset values set by start_server

0 commit comments

Comments
 (0)