Class: HTTP::Connection
- Inherits:
-
Object
- Object
- HTTP::Connection
- Extended by:
- Forwardable
- Includes:
- Internals
- Defined in:
- lib/http/connection.rb,
lib/http/connection/internals.rb,
sig/http.rbs
Overview
A connection to the HTTP server
Defined Under Namespace
Modules: Internals
Constant Summary collapse
- KEEP_ALIVE =
Allowed values for CONNECTION header
"Keep-Alive"- CLOSE =
Connection: close header value
"close"- BUFFER_SIZE =
Attempt to read this much data
16_384- MAX_FLUSH_SIZE =
Maximum response body size (in bytes) to auto-flush when reusing a connection. Bodies larger than this cause the connection to close instead, to avoid blocking on huge downloads.
1_048_576- HTTP_1_0 =
HTTP/1.0
"1.0"- HTTP_1_1 =
HTTP/1.1
"1.1"
Instance Attribute Summary collapse
-
#pending_response ⇒ void
writeonly
Set the pending response for auto-flushing before the next request.
-
#proxy_response_headers ⇒ HTTP::Headers?
readonly
Returned after HTTP CONNECT (via proxy).
Instance Method Summary collapse
-
#check_premature_eof(eof) ⇒ void
private
Check for premature end-of-file and raise if detected.
-
#close ⇒ void
Close the connection.
-
#connect_socket(req, options) ⇒ void
private
Connect socket and set up proxy/TLS.
-
#expired? ⇒ Boolean
Whether our connection has expired.
-
#failed_proxy_connect? ⇒ Boolean
Whether the proxy CONNECT request failed.
-
#finish_response ⇒ void
Callback for when we've reached the end of a response.
-
#finished_request? ⇒ Boolean
Whether there are no pending requests or responses.
- #handle_proxy_connect_response ⇒ void
- #headers ⇒ Headers
- #http_version ⇒ String?
-
#init_state(options) ⇒ void
private
Initialize connection state.
-
#initialize(req, options) ⇒ Connection
constructor
Initialize a new connection to an HTTP server.
-
#keep_alive? ⇒ Boolean
Whether we're keeping the conn alive.
-
#read_headers! ⇒ void
Reads data from socket up until headers are loaded.
- #read_more ⇒ Object
-
#readpartial(size = BUFFER_SIZE, outbuf = nil) ⇒ String
Read a chunk of the body.
- #reset_timer ⇒ void
- #send_proxy_connect_request ⇒ void
-
#send_request(req) ⇒ nil
Send a request to the server.
- #set_keep_alive ⇒ void
- #start_tls ⇒ void
- #status_code ⇒ Integer?
Methods included from Internals
#body_framed?, #flush_or_close_response, #flush_pending_response
Constructor Details
#initialize(req, options) ⇒ Connection
Initialize a new connection to an HTTP server
52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/http/connection.rb', line 52 def initialize(req, ) init_state() connect_socket(req, ) rescue IO::TimeoutError => e close raise ConnectTimeoutError, e., e.backtrace rescue IOError, SocketError, SystemCallError => e raise ConnectionError, "failed to connect: #{e}", e.backtrace rescue TimeoutError close raise end |
Instance Attribute Details
#pending_response=(value) ⇒ void (writeonly)
This method returns an undefined value.
Set the pending response for auto-flushing before the next request
93 94 95 |
# File 'lib/http/connection.rb', line 93 def pending_response=(value) @pending_response = value end |
#proxy_response_headers ⇒ HTTP::Headers? (readonly)
Returned after HTTP CONNECT (via proxy)
40 41 42 |
# File 'lib/http/connection.rb', line 40 def proxy_response_headers @proxy_response_headers end |
Instance Method Details
#check_premature_eof(eof) ⇒ void
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.
This method returns an undefined value.
Check for premature end-of-file and raise if detected
246 247 248 249 250 251 |
# File 'lib/http/connection.rb', line 246 def check_premature_eof(eof) return unless eof && !@parser.finished? && body_framed? close raise ConnectionError, "response body ended prematurely" end |
#close ⇒ void
This method returns an undefined value.
Close the connection
184 185 186 187 188 189 |
# File 'lib/http/connection.rb', line 184 def close @socket.close unless @socket&.closed? @pending_response = false @pending_request = false end |
#connect_socket(req, options) ⇒ void
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.
This method returns an undefined value.
Connect socket and set up proxy/TLS
256 257 258 259 260 261 262 263 |
# File 'lib/http/connection.rb', line 256 def connect_socket(req, ) @socket = .timeout_class.new(**.) @socket.connect(.socket_class, req.socket_host, req.socket_port, nodelay: .nodelay) send_proxy_connect_request(req) start_tls(req, ) reset_timer end |
#expired? ⇒ Boolean
Whether our connection has expired
220 221 222 |
# File 'lib/http/connection.rb', line 220 def expired? !@conn_expires_at || @conn_expires_at < Time.now end |
#failed_proxy_connect? ⇒ Boolean
Whether the proxy CONNECT request failed
81 82 83 |
# File 'lib/http/connection.rb', line 81 def failed_proxy_connect? @failed_proxy_connect end |
#finish_response ⇒ void
This method returns an undefined value.
Callback for when we've reached the end of a response
167 168 169 170 171 172 173 174 175 |
# File 'lib/http/connection.rb', line 167 def finish_response close unless keep_alive? @parser.reset @socket.reset_counter if @socket.respond_to?(:reset_counter) reset_timer @pending_response = false end |
#finished_request? ⇒ Boolean
Whether there are no pending requests or responses
198 199 200 |
# File 'lib/http/connection.rb', line 198 def finished_request? !@pending_request && !@pending_response end |
#handle_proxy_connect_response ⇒ void
This method returns an undefined value.
1155 |
# File 'sig/http.rbs', line 1155
def handle_proxy_connect_response: () -> void
|
#http_version ⇒ String?
1145 |
# File 'sig/http.rbs', line 1145
def http_version: () -> String?
|
#init_state(options) ⇒ void
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.
This method returns an undefined value.
Initialize connection state
229 230 231 232 233 234 235 236 237 |
# File 'lib/http/connection.rb', line 229 def init_state() @persistent = .persistent? @keep_alive_timeout = .keep_alive_timeout.to_f @pending_request = false @pending_response = false @failed_proxy_connect = false @buffer = "".b @parser = Response::Parser.new end |
#keep_alive? ⇒ Boolean
Whether we're keeping the conn alive
209 210 211 |
# File 'lib/http/connection.rb', line 209 def keep_alive? @keep_alive && !@socket.closed? end |
#read_headers! ⇒ void
This method returns an undefined value.
Reads data from socket up until headers are loaded
151 152 153 154 155 156 157 158 |
# File 'lib/http/connection.rb', line 151 def read_headers! until @parser.headers? result = read_more(BUFFER_SIZE) raise ResponseHeaderError, "couldn't read response headers" if result == :eof end set_keep_alive end |
#read_more ⇒ Object
1158 |
# File 'sig/http.rbs', line 1158
def read_more: (Integer size) -> untyped
|
#readpartial(size = BUFFER_SIZE, outbuf = nil) ⇒ String
Read a chunk of the body
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/http/connection.rb', line 128 def readpartial(size = BUFFER_SIZE, outbuf = nil) raise EOFError unless @pending_response chunk = @parser.read(size) unless chunk eof = read_more(size) == :eof check_premature_eof(eof) finished = eof || @parser.finished? chunk = @parser.read(size) || "".b finish_response if finished end outbuf ? outbuf.replace(chunk) : chunk end |
#reset_timer ⇒ void
This method returns an undefined value.
1156 |
# File 'sig/http.rbs', line 1156
def reset_timer: () -> void
|
#send_proxy_connect_request ⇒ void
This method returns an undefined value.
1154 |
# File 'sig/http.rbs', line 1154
def send_proxy_connect_request: (Request req) -> void
|
#send_request(req) ⇒ nil
Send a request to the server
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/http/connection.rb', line 103 def send_request(req) flush_pending_response if @pending_response if @pending_request raise StateError, "Tried to send a request while a response is pending. Make sure you read off the body." end @pending_request = true req.stream @socket @pending_response = true @pending_request = false end |
#set_keep_alive ⇒ void
This method returns an undefined value.
1157 |
# File 'sig/http.rbs', line 1157
def set_keep_alive: () -> void
|
#start_tls ⇒ void
This method returns an undefined value.
1153 |
# File 'sig/http.rbs', line 1153
def start_tls: (Request req, Options options) -> void
|
#status_code ⇒ Integer?
1144 |
# File 'sig/http.rbs', line 1144
def status_code: () -> Integer?
|