Class: HTTP::Response

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/http/response.rb,
lib/http/response/body.rb,
lib/http/response/parser.rb,
lib/http/response/status.rb,
lib/http/response/inflater.rb,
lib/http/response/status/reasons.rb

Overview

Represents an HTTP response with status, headers, and body

Defined Under Namespace

Classes: Body, Inflater, Parser, Status

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(status:, version:, headers: {}, proxy_headers: {}, connection: nil, encoding: nil, body: nil, request: nil, uri: nil) ⇒ Response

Create a new Response instance

Examples:

Response.new(status: 200, version: "1.1", request: req)

Parameters:

  • status (Integer)

    Status code

  • version (String)

    HTTP version

  • headers (Hash) (defaults to: {})
  • proxy_headers (Hash) (defaults to: {})
  • connection (HTTP::Connection, nil) (defaults to: nil)
  • encoding (String, nil) (defaults to: nil)

    Encoding to use when reading body

  • body (String, nil) (defaults to: nil)
  • request (HTTP::Request, nil) (defaults to: nil)

    The request this is in response to

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

    (DEPRECATED) used to populate a missing request



89
90
91
92
93
94
95
96
97
# File 'lib/http/response.rb', line 89

def initialize(status:, version:, headers: {}, proxy_headers: {}, connection: nil,
               encoding: nil, body: nil, request: nil, uri: nil)
  @version       = version
  @request       = init_request(request, uri)
  @status        = HTTP::Response::Status.new(status)
  @headers       = HTTP::Headers.coerce(headers)
  @proxy_headers = HTTP::Headers.coerce(proxy_headers)
  @body          = init_body(body, connection, encoding)
end

Instance Attribute Details

#bodyBody (readonly)

The response body

Examples:

response.body

Returns:

  • (Body)

    the response body



44
45
46
# File 'lib/http/response.rb', line 44

def body
  @body
end

#headersHTTP::Headers (readonly)

The HTTP headers collection

Examples:

response.headers

Returns:



62
63
64
# File 'lib/http/response.rb', line 62

def headers
  @headers
end

#proxy_headersHash (readonly)

The proxy headers

Examples:

response.proxy_headers

Returns:

  • (Hash)

    the proxy headers



71
72
73
# File 'lib/http/response.rb', line 71

def proxy_headers
  @proxy_headers
end

#requestRequest (readonly)

The original request

Examples:

response.request

Returns:

  • (Request)

    the original request



53
54
55
# File 'lib/http/response.rb', line 53

def request
  @request
end

#statusStatus (readonly)

The response status

Examples:

response.status # => #<HTTP::Response::Status 200>

Returns:

  • (Status)

    the response status



26
27
28
# File 'lib/http/response.rb', line 26

def status
  @status
end

#versionString (readonly)

The HTTP version

Examples:

response.version # => "1.1"

Returns:

  • (String)

    the HTTP version



35
36
37
# File 'lib/http/response.rb', line 35

def version
  @version
end

Instance Method Details

#charsetString?

Charset of response (if any)

Examples:

response.charset # => "utf-8"

Returns:

  • (String, nil)


256
# File 'lib/http/response.rb', line 256

def_delegator :content_type, :charset

#chunked?Boolean

Check if the response uses chunked transfer encoding

Examples:

response.chunked? # => true

Returns:

  • (Boolean)


276
277
278
279
280
281
282
# File 'lib/http/response.rb', line 276

def chunked?
  return false unless @headers.include?(Headers::TRANSFER_ENCODING)

  encoding = @headers.get(Headers::TRANSFER_ENCODING)

  encoding.last == Headers::CHUNKED
end

#codeInteger

Return the numeric status code

Examples:

response.code # => 200

Returns:

  • (Integer)


113
# File 'lib/http/response.rb', line 113

def_delegator :@status, :code

#connectionHTTP::Connection

Return the underlying connection object

Examples:

response.connection

Returns:



139
# File 'lib/http/response.rb', line 139

def_delegator :@body, :connection

#content_lengthnil, Integer

Value of the Content-Length header

Examples:

response.content_length # => 438

Returns:

  • (nil)

    if Content-Length was not given, or it’s value was invalid (not an integer, e.g. empty string or string with non-digits).

  • (Integer)

    otherwise



217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/http/response.rb', line 217

def content_length
  # http://greenbytes.de/tech/webdav/rfc7230.html#rfc.section.3.3.3
  # Clause 3: "If a message is received with both a Transfer-Encoding
  # and a Content-Length header field, the Transfer-Encoding overrides the Content-Length.
  return nil if @headers.include?(Headers::TRANSFER_ENCODING)

  # RFC 7230 Section 3.3.2: If multiple Content-Length values are present,
  # they must all be identical; otherwise treat as invalid.
  values = @headers.get(Headers::CONTENT_LENGTH).uniq
  return nil unless values.one?

  Integer(values.first, exception: false)
end

#content_typeHTTP::ContentType

Parsed Content-Type header

Examples:

response.content_type # => #<HTTP::ContentType ...>

Returns:



238
239
240
# File 'lib/http/response.rb', line 238

def content_type
  @content_type ||= ContentType.parse headers[Headers::CONTENT_TYPE]
end

#cookiesArray<HTTP::Cookie>

Cookies from Set-Cookie headers

Examples:

response.cookies # => [#<HTTP::Cookie ...>, ...]

Returns:

  • (Array<HTTP::Cookie>)


265
266
267
# File 'lib/http/response.rb', line 265

def cookies
  @cookies ||= headers.get(Headers::SET_COOKIE).flat_map { |v| HTTP::Cookie.parse(v, uri) }
end

#deconstruct_keys(keys) ⇒ Hash{Symbol => Object}

Pattern matching interface for matching against response attributes

Examples:

case response
in { status: 200..299, body: /success/ }
  "ok"
in { status: 400.. }
  "error"
end

Parameters:

  • keys (Array<Symbol>, nil)

    keys to extract, or nil for all

Returns:

  • (Hash{Symbol => Object})


184
185
186
187
188
189
190
191
192
193
194
# File 'lib/http/response.rb', line 184

def deconstruct_keys(keys)
  hash = {
    status:        @status,
    version:       @version,
    headers:       @headers,
    body:          @body,
    request:       @request,
    proxy_headers: @proxy_headers
  }
  keys ? hash.slice(*keys) : hash
end

#flushResponse

Flushes body and returns self-reference

Examples:

response.flush # => #<HTTP::Response ...>

Returns:



203
204
205
206
# File 'lib/http/response.rb', line 203

def flush
  body.to_s
  self
end

#inspectString

Inspect a response

Examples:

response.inspect # => "#<HTTP::Response/1.1 200 OK text/html>"

Returns:

  • (String)


306
307
308
# File 'lib/http/response.rb', line 306

def inspect
  "#<#{self.class}/#{@version} #{code} #{reason} #{mime_type}>"
end

#mime_typeString?

MIME type of response (if any)

Examples:

response.mime_type # => "text/html"

Returns:

  • (String, nil)


248
# File 'lib/http/response.rb', line 248

def_delegator :content_type, :mime_type

#parse(type = nil) ⇒ Object

Parse response body with corresponding MIME type adapter

Examples:

response.parse("application/json") # => {"key" => "value"}

Parameters:

  • type (#to_s) (defaults to: nil)

    Parse as given MIME type.

Returns:

  • (Object)

Raises:

  • (Error)

    if no adapter found



293
294
295
296
297
# File 'lib/http/response.rb', line 293

def parse(type = nil)
  MimeType[type || mime_type].decode to_s
rescue => e
  raise ParseError, e.message
end

#readpartialString

Read a chunk of the response body

Examples:

response.readpartial # => "chunk"

Returns:

  • (String)

Raises:

  • (EOFError)

    when no more data left



131
# File 'lib/http/response.rb', line 131

def_delegator :@body, :readpartial

#reasonString?

Return the reason phrase for the response status

Examples:

response.reason # => "OK"

Returns:

  • (String, nil)


105
# File 'lib/http/response.rb', line 105

def_delegator :@status, :reason

#to_aArray(Fixnum, Hash, String) Also known as: deconstruct

Returns an Array ala Rack: ‘[status, headers, body]`

Examples:

response.to_a # => [200, {"Content-Type" => "text/html"}, "body"]

Returns:

  • (Array(Fixnum, Hash, String))


156
157
158
# File 'lib/http/response.rb', line 156

def to_a
  [status.to_i, headers.to_h, body.to_s]
end

#to_sString Also known as: to_str

Consume the response body as a string

Examples:

response.to_s # => "<html>...</html>"

Returns:

  • (String)


121
# File 'lib/http/response.rb', line 121

def_delegator :@body, :to_s

#uriHTTP::URI

Return the URI of the original request

Examples:

response.uri # => #<HTTP::URI ...>

Returns:



147
# File 'lib/http/response.rb', line 147

def_delegator :@request, :uri