class Async::IO::SSLSocket

Asynchronous TCP socket wrapper.

def self.connect(socket, context, hostname = nil, &block)

def self.connect(socket, context, hostname = nil, &block)
	client = self.wrap(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

def self.wrap(socket, context)

def self.wrap(socket, context)
	io = @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
	
	return self.new(io, socket.reactor)
end

def local_address

def local_address
	@io.to_io.local_address
end

def remote_address

def remote_address
	@io.to_io.remote_address
end