class Patron::Response

Represents the response from the HTTP server.

Attributes

body[R]

@return [String, nil] the response body as a String encoded as ‘Encoding::BINARY` or

or `nil` if the response was written directly to a file
charset[R]

@return [String] the recognized name of the charset for the response. The name is not checked

to be a valid charset name, just stored. To check the charset for validity, use #body_decodable?
headers[R]

@return [Hash] the response headers. If there were multiple headers received for the same value

(like "Cookie"), the header values will be within an Array under the key for the header, in order.
redirect_count[R]

@return [Integer] how many redirects were followed when fulfilling this request

status[R]

@return [Integer] the HTTP status code of the final response after all the redirects

status_line[R]

@return [String] the complete status line (code and message)

url[R]

@return [String] the original URL used to perform the request (contains the final URL after redirects)

Public Class Methods

new(url, status, redirect_count, raw_header_data, body, default_charset = nil) click to toggle source
# File lib/patron/response.rb, line 37
def initialize(url, status, redirect_count, raw_header_data, body, default_charset = nil)
  @url            = url.force_encoding(Encoding::ASCII) # the URL is always an ASCII subset, _always_.
  @status         = status
  @redirect_count = redirect_count
  @body           = body.force_encoding(Encoding::BINARY) if body

  header_data = decode_header_data(raw_header_data)
  parse_headers(header_data)
  @charset = charset_from_content_type
end

Public Instance Methods

body_decodable?() click to toggle source

Tells whether the response body can be decoded losslessly into the curren internal encoding

@return [Boolean] true if the body is decodable, false if otherwise

# File lib/patron/response.rb, line 65
def body_decodable?
  return true if @body.nil?
  return true if decoded_body
rescue HeaderCharsetInvalid, NonRepresentableBody
  false
end
decoded_body() click to toggle source

Returns the response body converted into the Ruby process internal encoding (the one set as ‘Encoding.default_internal`). As the response gets returned, the response body is not assumed to be in any encoding whatsoever - it will be explicitly set to `Encoding::BINARY` (as if you were reading a file in binary mode).

When you call ‘decoded_body`, the method will look at the `Content-Type` response header, and check if that header specified a charset. If it did, the method will then check whether the specified charset is valid (whether it is possible to find a matching `Encoding` class in the VM). Once that succeeds, the method will check whether the response body is in the encoding that the server said it is.

This might not be the case - you can, for instance, easily serve an HTML document with a UTF-8 header (with the header being configured somewhere on the webserver level) and then have the actual HTML document override it with a ‘meta` element or `charset` containing an overriding charset. However, parsing the response body is outside of scope for Patron, so if this situation happens (the server sets a charset in the header but this header does not match what the server actually sends in the body) you will get an exception stating this is a problem.

The next step is actually converting the body to the internal Ruby encoding. That stage may raise an exception as well, if you are using an internal encoding which can’t represent the response body faithfully. For example, if you run Ruby with a CJK internal encoding, and the response you are trying to decode uses Greek characters and is UTF-8, you are going to get an exception since it is impossible to coerce those characters to your internal encoding.

@raise {Patron::HeaderCharsetInvalid} when the server supplied a wrong or incorrect charset, {Patron::NonRepresentableBody}

when unable to decode the body into the current process encoding.

@return [String, nil]

# File lib/patron/response.rb, line 95
def decoded_body
  return unless @body
  @decoded_body ||= decode_body(true)
end
error?() click to toggle source

Tells whether the HTTP response code is larger than 399

@return [Boolean]

# File lib/patron/response.rb, line 58
def error?
  status >= 400
end
inspect() click to toggle source

Overridden so that the output is shorter and there is no response body printed

# File lib/patron/response.rb, line 32
def inspect
  # Avoid spamming the console with the header and body data
  "#<Patron::Response @status_line='#{@status_line}'>"
end
inspectable_body() click to toggle source

Works the same as ‘decoded_body`, with one substantial difference: characters which can’t be represented in your process’ default encoding are going to be replaced with question marks. This can be used for raising errors when you receive responses which indicate errors on the server you are calling. For example, if you expect a binary download, and the server sends you an error message and you don’t really want to bother figuring out the encoding it has - but you need to append this response to an error log or similar.

@see Patron::Response#decoded_body @return [String, nil]

# File lib/patron/response.rb, line 108
def inspectable_body
  return unless @body
  @inspectable_body ||= decode_body(false)
end
ok?() click to toggle source

Tells whether the HTTP response code is less than 400

@return [Boolean]

# File lib/patron/response.rb, line 51
def ok?
  !error?
end

Private Instance Methods

parse_headers(header_data_for_multiple_responses) click to toggle source

Called by the C code to parse and set the headers

# File lib/patron/response.rb, line 116
def parse_headers(header_data_for_multiple_responses)
  @headers = {}

  responses = Patron::HeaderParser.parse(header_data_for_multiple_responses)
  last_response = responses[-1] # Only use the last response (for proxies and redirects)

  @status_line = last_response.status_line
  last_response.headers.each do |line|
    hdr, val = line.split(":", 2)

    val.strip! unless val.nil?

    if @headers.key?(hdr)
      @headers[hdr] = [@headers[hdr]] unless @headers[hdr].kind_of? Array
      @headers[hdr] << val
    else
      @headers[hdr] = val
    end
  end
end