Class: HTTP::Timeout::Null

Inherits:
Object
  • Object
show all
Defined in:
lib/http/timeout/null.rb,
sig/http.rbs

Overview

Base timeout handler with no timeout enforcement

Direct Known Subclasses

Global, PerOperation

Constant Summary collapse

NATIVE_CONNECT_TIMEOUT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Whether TCPSocket natively supports connect_timeout and Happy Eyeballs (RFC 8305). Available in Ruby 3.4+.

RUBY_VERSION >= "3.4"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(read_timeout: nil, write_timeout: nil, connect_timeout: nil, global_timeout: nil) ⇒ HTTP::Timeout::Null

Initializes the null timeout handler

Examples:

HTTP::Timeout::Null.new(read_timeout: 5)


46
47
48
49
# File 'lib/http/timeout/null.rb', line 46

def initialize(read_timeout: nil, write_timeout: nil, connect_timeout: nil, global_timeout: nil)
  @options = { read_timeout: read_timeout, write_timeout: write_timeout,
               connect_timeout: connect_timeout, global_timeout: global_timeout }.compact
end

Instance Attribute Details

#optionsHash (readonly)

Timeout configuration options

Examples:

timeout.options # => {read_timeout: 5}


24
25
26
# File 'lib/http/timeout/null.rb', line 24

def options
  @options
end

#socketObject (readonly)

The underlying socket

Examples:

timeout.socket


33
34
35
# File 'lib/http/timeout/null.rb', line 33

def socket
  @socket
end

Instance Method Details

#closevoid

This method returns an undefined value.

Closes the underlying socket

Examples:

timeout.close


85
86
87
# File 'lib/http/timeout/null.rb', line 85

def close
  @socket&.close
end

#closed?Boolean

Checks whether the socket is closed

Examples:

timeout.closed?


96
97
98
# File 'lib/http/timeout/null.rb', line 96

def closed?
  @socket&.closed?
end

#connect(socket_class, host, port, nodelay: false) ⇒ void

This method returns an undefined value.

Connects to a socket

Examples:

timeout.connect(TCPSocket, "example.com", 80)


62
63
64
65
# File 'lib/http/timeout/null.rb', line 62

def connect(socket_class, host, port, nodelay: false)
  @socket = open_socket(socket_class, host, port)
  @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) if nodelay
end

#connect_sslvoid

This method returns an undefined value.

Starts a SSL connection on a socket

Examples:

timeout.connect_ssl


74
75
76
# File 'lib/http/timeout/null.rb', line 74

def connect_ssl
  @socket.connect
end

#native_timeout?(socket_class) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Whether the socket class supports native connect_timeout



222
223
224
# File 'lib/http/timeout/null.rb', line 222

def native_timeout?(socket_class)
  NATIVE_CONNECT_TIMEOUT && socket_class.is_a?(Class) && socket_class <= TCPSocket
end

#open_socket(socket_class, host, port, connect_timeout: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Opens a TCP socket, using native connect_timeout when available

On Ruby 3.4+ with TCPSocket, passes connect_timeout natively to enable proper Happy Eyeballs (RFC 8305) support. Falls back to Timeout.timeout on older Rubies or with custom socket classes.



187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/http/timeout/null.rb', line 187

def open_socket(socket_class, host, port, connect_timeout: nil)
  return socket_class.open(host, port) unless connect_timeout

  if native_timeout?(socket_class)
    open_with_timeout(socket_class, host, port, connect_timeout)
  else
    ::Timeout.timeout(connect_timeout, ConnectTimeoutError) do
      open_with_timeout(socket_class, host, port, connect_timeout)
    end
  end
rescue IO::TimeoutError
  raise ConnectTimeoutError, "Connect timed out after #{connect_timeout} seconds"
end

#open_with_timeout(socket_class, host, port, connect_timeout) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Opens a socket, passing connect_timeout natively when supported



209
210
211
212
213
214
215
# File 'lib/http/timeout/null.rb', line 209

def open_with_timeout(socket_class, host, port, connect_timeout)
  if native_timeout?(socket_class)
    socket_class.open(host, port, connect_timeout: connect_timeout)
  else
    socket_class.open(host, port)
  end
end

#read_timeoutNumeric?



1511
# File 'sig/http.rbs', line 1511

def read_timeout: () -> Numeric?

#readpartial(size, buffer = nil) ⇒ String, :eof

Read from the socket

Examples:

timeout.readpartial(1024)


132
133
134
135
136
# File 'lib/http/timeout/null.rb', line 132

def readpartial(size, buffer = nil)
  @socket.readpartial(size, buffer)
rescue EOFError
  :eof
end

#rescue_readable(timeout = read_timeout) { ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retries reading on wait readable

Yields:

Yield Returns:

  • (Object)


157
158
159
160
161
162
# File 'lib/http/timeout/null.rb', line 157

def rescue_readable(timeout = read_timeout)
  yield
rescue IO::WaitReadable
  retry if @socket.to_io.wait_readable(timeout)
  raise TimeoutError, "Read timed out after #{timeout} seconds"
end

#rescue_writable(timeout = write_timeout) { ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retries writing on wait writable

Yields:

Yield Returns:

  • (Object)


168
169
170
171
172
173
# File 'lib/http/timeout/null.rb', line 168

def rescue_writable(timeout = write_timeout)
  yield
rescue IO::WaitWritable
  retry if @socket.to_io.wait_writable(timeout)
  raise TimeoutError, "Write timed out after #{timeout} seconds"
end

#start_tls(host, ssl_socket_class, ssl_context) ⇒ void

This method returns an undefined value.

Configures the SSL connection and starts it

Examples:

timeout.start_tls("example.com", ssl_class, ssl_ctx)


110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/http/timeout/null.rb', line 110

def start_tls(host, ssl_socket_class, ssl_context)
  @socket = ssl_socket_class.new(socket, ssl_context)
  @socket.hostname = host if @socket.respond_to? :hostname=
  @socket.sync_close = true if @socket.respond_to? :sync_close=

  connect_ssl

  return unless ssl_context.verify_mode == OpenSSL::SSL::VERIFY_PEER
  return if ssl_context.respond_to?(:verify_hostname) && !ssl_context.verify_hostname

  @socket.post_connection_check(host)
end

#write(data) ⇒ Integer Also known as: <<

Write to the socket

Examples:

timeout.write("GET / HTTP/1.1")


146
147
148
# File 'lib/http/timeout/null.rb', line 146

def write(data)
  @socket.write(data)
end

#write_timeoutNumeric?



1512
# File 'sig/http.rbs', line 1512

def write_timeout: () -> Numeric?