Class: HTTP::Connection

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Internals
Defined in:
lib/http/connection.rb,
lib/http/connection/internals.rb

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

Instance Method Summary collapse

Constructor Details

#initialize(req, options) ⇒ Connection

Initialize a new connection to an HTTP server

Examples:

Connection.new(req, options)

Parameters:

Raises:



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/http/connection.rb', line 52

def initialize(req, options)
  init_state(options)
  connect_socket(req, options)
rescue IO::TimeoutError => e
  close
  raise ConnectTimeoutError, e.message, 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

Examples:

connection.pending_response = response

Parameters:



93
94
95
# File 'lib/http/connection.rb', line 93

def pending_response=(value)
  @pending_response = value
end

#proxy_response_headersHTTP::Headers? (readonly)

Returned after HTTP CONNECT (via proxy)

Examples:

connection.proxy_response_headers

Returns:



40
41
42
# File 'lib/http/connection.rb', line 40

def proxy_response_headers
  @proxy_response_headers
end

Instance Method Details

#closevoid

This method returns an undefined value.

Close the connection

Examples:

connection.close


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

#expired?Boolean

Whether our connection has expired

Examples:

connection.expired?

Returns:

  • (Boolean)


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

Examples:

connection.failed_proxy_connect?

Returns:

  • (Boolean)

    whenever proxy connect failed



81
82
83
# File 'lib/http/connection.rb', line 81

def failed_proxy_connect?
  @failed_proxy_connect
end

#finish_responsevoid

This method returns an undefined value.

Callback for when we’ve reached the end of a response

Examples:

connection.finish_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

Examples:

connection.finished_request?

Returns:

  • (Boolean)


198
199
200
# File 'lib/http/connection.rb', line 198

def finished_request?
  !@pending_request && !@pending_response
end

#keep_alive?Boolean

Whether we’re keeping the conn alive

Examples:

connection.keep_alive?

Returns:

  • (Boolean)


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

Examples:

connection.read_headers!

Raises:



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

#readpartial(size = BUFFER_SIZE, outbuf = nil) ⇒ String

Read a chunk of the body

Examples:

connection.readpartial

Parameters:

  • size (Integer) (defaults to: BUFFER_SIZE)

    maximum bytes to read

  • outbuf (String, nil) (defaults to: nil)

    buffer to fill with data

Returns:

  • (String)

    data chunk

Raises:

  • (EOFError)

    when no more data left



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

#send_request(req) ⇒ nil

Send a request to the server

Examples:

connection.send_request(req)

Parameters:

  • req (Request)

    Request to send to the server

Returns:

  • (nil)


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