class RaptorIO::Socket::TCP
TCP
client socket
Constants
Attributes
@!attribute socket
The underlying IO for this socket. Usually this is the `socket` passed to {#initialize} @return [IO]
Public Class Methods
@param (see Socket#initialize)
RaptorIO::Socket::new
# File lib/raptor-io/socket/tcp.rb, line 25 def initialize(socket, options = {}) options = DEFAULT_OPTIONS.merge(options) super @plaintext_socket = @socket = socket end
Public Instance Methods
Ruby ‘Socket#gets` accepts:
-
‘gets( sep = $/ )`
-
‘gets( limit = nil )`
-
‘gets( sep = $/, limit = nil )`
‘OpenSSL::SSL::SSLSocket#gets` however only supports `gets(sep=$/, limit=nil)`. This hack allows SSLSocket to behave the same as Ruby Socket.
@note May block
# File lib/raptor-io/socket/tcp.rb, line 126 def gets(*args) translate_errors do if args.size == 1 arg = args.first if arg.is_a?(Numeric) @socket.gets($/, arg) else @socket.gets(arg) end else @socket.gets(*args) end end end
Read exactly ‘maxlen` bytes from the {#socket}. If fewer than `maxlen` bytes are available for reading, wait until enough data is sent.
@note May block
@param (see read_nonblock
) @return (see read_nonblock
)
# File lib/raptor-io/socket/tcp.rb, line 81 def read(maxlen) buf = "" until 0 == maxlen prev_length = buf.length buf << readpartial(maxlen) maxlen -= buf.length - prev_length end buf end
Read at most ‘maxlen` bytes from the {#socket}.
@param maxlen [Fixnum] @return [String]
# File lib/raptor-io/socket/tcp.rb, line 110 def read_nonblock(maxlen = nil) translate_errors do @socket.read_nonblock(maxlen) end end
Read at most ‘maxlen` bytes from the {#socket}.
@note May block
@param (see read_nonblock
) @return (see read_nonblock
)
# File lib/raptor-io/socket/tcp.rb, line 97 def readpartial(maxlen = nil) begin read_nonblock(maxlen) rescue IO::WaitReadable IO.select([@socket]) retry end end
# File lib/raptor-io/socket/tcp.rb, line 46 def remote_address ::Addrinfo.new([ "AF_INET", options[:peer_port], options[:peer_host], options[:peer_host] ]) end
Whether this socket is encrypted with SSL
# File lib/raptor-io/socket/tcp.rb, line 163 def ssl? !!(@socket.respond_to?(:context) && @socket.context) end
@return [OpenSSL::SSL::SSLContext] @return [nil] If this socket is not SSL
(see {#ssl?})
# File lib/raptor-io/socket/tcp.rb, line 179 def ssl_context return nil unless ssl? @socket.context end
The version of SSL/TLS that was negotiated with the server.
@return [String] See OpenSSL::SSL::SSLSocket#ssl_version for
possible values
@return [nil] If this socket is not SSL
# File lib/raptor-io/socket/tcp.rb, line 172 def ssl_version return nil unless ssl? @socket.ssl_version end
Attempt to turn this into something usable by ‘IO.select`.
@return [IO]
# File lib/raptor-io/socket/tcp.rb, line 158 def to_io IO.try_convert(@socket) || @socket end
@note The original socket is replaced by the newly connected
{TCP::SSL} socket
Starts an SSL/TLS stream over this connection.
Using this as opposed to directly instantiating {TCP::SSL} allows you to start a TLS connection after data has already been exchanged to enable things like ‘STARTTLS`.
@note May block
@param ssl_options [Hash] Options @option ssl_options :ssl_version [Symbol] (:TLSv1) @option ssl_options :ssl_verify_mode [Constant] (OpenSSL::SSL::VERIFY_PEER)
Peer verification mode.
@option ssl_config :ssl_context [OpenSSL::SSL::SSLContext] (nil)
SSL context to use.
@return [RaptorIO::Socket::TCP::SSL] A new Socket with an established
SSL connection
# File lib/raptor-io/socket/tcp.rb, line 204 def to_ssl(ssl_options = {}) if ssl_options[:ssl_context] options[:ssl_context] = ssl_options[:ssl_context] else ssl_options = DEFAULT_SSL_OPTIONS.merge(ssl_options) options[:ssl_context] = OpenSSL::SSL::SSLContext.new.tap do |ctx| ctx.ssl_version = ssl_options[:ssl_version] ctx.verify_mode = ssl_options[:ssl_verify_mode] end end s = RaptorIO::Socket::TCP::SSL.new(@plaintext_socket, options) @socket = s s end
Write ‘data` to the {#socket}.
@param data [String,#to_s] @return [Fixnum]
# File lib/raptor-io/socket/tcp.rb, line 54 def write(data) begin write_nonblock(data) rescue IO::WaitWritable IO.select(nil, [@socket]) retry end end
Try to write ‘data` to the {#socket}.
@param maxlen [Fixnum] @return [String]
# File lib/raptor-io/socket/tcp.rb, line 67 def write_nonblock(data) translate_errors do @socket.write_nonblock(data) end end
Private Instance Methods
# File lib/raptor-io/socket/tcp.rb, line 223 def translate_errors(&block) yield rescue Errno::ECONNRESET, Errno::EPIPE raise RaptorIO::Socket::Error::BrokenPipe rescue Errno::ECONNREFUSED raise RaptorIO::Socket::Error::ConnectionRefused end