Class: Async::IO::SSLSocket

Inherits:
Generic
  • Object
show all
Includes:
Peer
Defined in:
lib/async/io/ssl_socket.rb

Overview

Asynchronous TCP socket wrapper.

Constant Summary

Constants inherited from Generic

Generic::WRAPPERS

Instance Attribute Summary

Attributes inherited from Generic

#timeout

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Peer

#connected?, #eof, #eof?, #protocol, #sync, #sync=, #type

Methods inherited from Generic

#<<, #connected?, #dup, #nonblock, #nonblock=, #nonblock?, #read, #sysread, #syswrite, #wait, wrap, wrap_blocking_method, wraps, #write

Constructor Details

#initialize(socket, context) ⇒ SSLSocket

Returns a new instance of SSLSocket.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/async/io/ssl_socket.rb', line 66

def initialize(socket, context)
	if socket.is_a?(self.class.wrapped_klass)
		super
	else
		io = self.class.wrapped_klass.new(socket.to_io, context)
		
		# We detach the socket from the reactor, otherwise it's possible to add the file descriptor to the selector twice, which is bad.
		socket.reactor = nil
		
		# This ensures that when the internal IO is closed, it also closes the internal socket:
		io.sync_close = true
		
		# Copy the timeout:
		@timeout = socket.timeout
		
		super(io, socket.reactor)
	end
end

Class Method Details

.connect(socket, context, hostname = nil, &block) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/async/io/ssl_socket.rb', line 38

def self.connect(socket, context, hostname = nil, &block)
	client = self.new(socket, context)
	
	# Used for SNI:
	if hostname
		client.hostname = hostname
	end
	
	begin
		client.connect
	rescue
		# If the connection fails (e.g. certificates are invalid), the caller never sees the socket, so we close it and raise the exception up the chain.
		client.close
		
		raise
	end
	
	return client unless block_given?
	
	begin
		yield client
	ensure
		client.close
	end
end

Instance Method Details

#acceptObject

Invokes ‘accept_nonblock` on the underlying io. If the operation would block, the current task is paused until the operation can succeed, at which point it’s resumed and the operation is completed.



35
# File 'lib/async/io/ssl_socket.rb', line 35

wrap_blocking_method :accept, :accept_nonblock

#close_readObject



97
98
99
# File 'lib/async/io/ssl_socket.rb', line 97

def close_read
	self.shutdown(Socket::SHUT_RD)
end

#close_writeObject



93
94
95
# File 'lib/async/io/ssl_socket.rb', line 93

def close_write
	self.shutdown(Socket::SHUT_WR)
end

#connectObject

Invokes ‘connect_nonblock` on the underlying io. If the operation would block, the current task is paused until the operation can succeed, at which point it’s resumed and the operation is completed.



36
# File 'lib/async/io/ssl_socket.rb', line 36

wrap_blocking_method :connect, :connect_nonblock

#local_addressObject



85
86
87
# File 'lib/async/io/ssl_socket.rb', line 85

def local_address
	@io.to_io.local_address
end

#remote_addressObject



89
90
91
# File 'lib/async/io/ssl_socket.rb', line 89

def remote_address
	@io.to_io.remote_address
end

#shutdown(how) ⇒ Object



101
102
103
104
# File 'lib/async/io/ssl_socket.rb', line 101

def shutdown(how)
	@io.flush
	@io.to_io.shutdown(how)
end