class Net::HTTPResponse - Documentation for Ruby 3.3

# class Net::HTTPResponse

This class is the base class for Net::HTTP response classes.

## About the Examples¶ ↑

Examples here assume that `net/http` has been required (which also requires `uri`):

    require 'net/http'

Many code examples here use these example websites:

- jsonplaceholder.typicode.com.

- example.com.

Some examples also assume these variables:

    uri = URI('https://jsonplaceholder.typicode.com/')
    uri.freeze # Examples may not modify.
    hostname = uri.hostname # => "jsonplaceholder.typicode.com"
    path = uri.path         # => "/"
    port = uri.port         # => 443

So that example requests may be written as:

    Net::HTTP.get(uri)
    Net::HTTP.get(hostname, '/index.html')
    Net::HTTP.start(hostname) do |http|
      http.get('/todos/1')
      http.get('/todos/2')
    end

An example that needs a modified `URI` first duplicates `uri`, then modifies the duplicate:

    _uri = uri.dup
    _uri.path = '/todos/1'

## Returned Responses¶ ↑

Method `Net::HTTP.get_response` returns an instance of one of the subclasses of Net::HTTPResponse:

    Net::HTTP.get_response(uri)
    # => #<Net::HTTPOK 200 OK readbody=true>
    Net::HTTP.get_response(hostname, '/nosuch')
    # => #<Net::HTTPNotFound 404 Not Found readbody=true>

As does method `Net::HTTP#request`:

    req = Net::HTTP::Get.new(uri)
    Net::HTTP.start(hostname) do |http|
      http.request(req)
    end # => #<Net::HTTPOK 200 OK readbody=true>

Class Net::HTTPResponse includes module `Net::HTTPHeader`, which provides access to response header values via (among others):

- Hash-like method `[]`.

- Specific reader methods, such as `content_type`.

Examples:

    res = Net::HTTP.get_response(uri) # => #<Net::HTTPOK 200 OK readbody=true>
    res['Content-Type']               # => "text/html; charset=UTF-8"
    res.content_type                  # => "text/html"

## Response Subclasses¶ ↑

Class Net::HTTPResponse has a subclass for each HTTP status code. You can look up the response class for a given code:

    Net::HTTPResponse::CODE_TO_OBJ['200'] # => Net::HTTPOK
    Net::HTTPResponse::CODE_TO_OBJ['400'] # => Net::HTTPBadRequest
    Net::HTTPResponse::CODE_TO_OBJ['404'] # => Net::HTTPNotFound

And you can retrieve the status code for a response object:

    Net::HTTP.get_response(uri).code                 # => "200"
    Net::HTTP.get_response(hostname, '/nosuch').code # => "404"

The response subclasses (indentation shows class hierarchy):

- `Net::HTTPUnknownResponse` (for unhandled HTTP extensions).

- `Net::HTTPInformation`:

  - `Net::HTTPContinue` (100)

  - `Net::HTTPSwitchProtocol` (101)

  - `Net::HTTPProcessing` (102)

  - `Net::HTTPEarlyHints` (103)

- `Net::HTTPSuccess`:

  - `Net::HTTPOK` (200)

  - `Net::HTTPCreated` (201)

  - `Net::HTTPAccepted` (202)

  - `Net::HTTPNonAuthoritativeInformation` (203)

  - `Net::HTTPNoContent` (204)

  - `Net::HTTPResetContent` (205)

  - `Net::HTTPPartialContent` (206)

  - `Net::HTTPMultiStatus` (207)

  - `Net::HTTPAlreadyReported` (208)

  - `Net::HTTPIMUsed` (226)

- `Net::HTTPRedirection`:

  - `Net::HTTPMultipleChoices` (300)

  - `Net::HTTPMovedPermanently` (301)

  - `Net::HTTPFound` (302)

  - `Net::HTTPSeeOther` (303)

  - `Net::HTTPNotModified` (304)

  - `Net::HTTPUseProxy` (305)

  - `Net::HTTPTemporaryRedirect` (307)

  - `Net::HTTPPermanentRedirect` (308)

- `Net::HTTPClientError`:

  - `Net::HTTPBadRequest` (400)

  - `Net::HTTPUnauthorized` (401)

  - `Net::HTTPPaymentRequired` (402)

  - `Net::HTTPForbidden` (403)

  - `Net::HTTPNotFound` (404)

  - `Net::HTTPMethodNotAllowed` (405)

  - `Net::HTTPNotAcceptable` (406)

  - `Net::HTTPProxyAuthenticationRequired` (407)

  - `Net::HTTPRequestTimeOut` (408)

  - `Net::HTTPConflict` (409)

  - `Net::HTTPGone` (410)

  - `Net::HTTPLengthRequired` (411)

  - `Net::HTTPPreconditionFailed` (412)

  - `Net::HTTPRequestEntityTooLarge` (413)

  - `Net::HTTPRequestURITooLong` (414)

  - `Net::HTTPUnsupportedMediaType` (415)

  - `Net::HTTPRequestedRangeNotSatisfiable` (416)

  - `Net::HTTPExpectationFailed` (417)

  - `Net::HTTPMisdirectedRequest` (421)

  - `Net::HTTPUnprocessableEntity` (422)

  - `Net::HTTPLocked` (423)

  - `Net::HTTPFailedDependency` (424)

  - `Net::HTTPUpgradeRequired` (426)

  - `Net::HTTPPreconditionRequired` (428)

  - `Net::HTTPTooManyRequests` (429)

  - `Net::HTTPRequestHeaderFieldsTooLarge` (431)

  - `Net::HTTPUnavailableForLegalReasons` (451)

- `Net::HTTPServerError`:

  - `Net::HTTPInternalServerError` (500)

  - `Net::HTTPNotImplemented` (501)

  - `Net::HTTPBadGateway` (502)

  - `Net::HTTPServiceUnavailable` (503)

  - `Net::HTTPGatewayTimeOut` (504)

  - `Net::HTTPVersionNotSupported` (505)

  - `Net::HTTPVariantAlsoNegotiates` (506)

  - `Net::HTTPInsufficientStorage` (507)

  - `Net::HTTPLoopDetected` (508)

  - `Net::HTTPNotExtended` (510)

  - `Net::HTTPNetworkAuthenticationRequired` (511)

There is also the Net::HTTPBadResponse exception which is raised when there is a protocol error.

### Constants

CODE_CLASS_TO_OBJ
CODE_TO_OBJ

### Attributes

body_encoding[R]

Returns the value set by `body_encoding`=, or `false` if none; see `body_encoding=`.

code[R]

The HTTP result code string. For example, ‘302’. You can also determine the response type by examining which response subclass the response object is an instance of.

decode_content[RW]

`Set` to true automatically when the request did not contain an Accept-Encoding header from the user.

http_version[R]

The HTTP version supported by the server.

ignore_eof[RW]

Whether to ignore EOF when reading bodies with a specified Content-Length header.

message[R]

The HTTP result message sent by the server. For example, ‘Not Found’.

msg[R]

The HTTP result message sent by the server. For example, ‘Not Found’.

uri[R]

The `URI` used to fetch this response. The response `URI` is only available if a `URI` was used to create the request.

### Public Class Methods

body_permitted?() click to toggle source

true if the response has a body.

    # File lib/net/http/response.rb, line 138
    def body_permitted?
      self::HAS_BODY
    end

### Private Class Methods

each_response_header(sock) { |key, value| ... } click to toggle source

    # File lib/net/http/response.rb, line 170
    def each_response_header(sock)
      key = value = nil
      while true
        line = sock.readuntil("\n", true).sub(/\s+\z/, '')
        break if line.empty?
        if line[0] == ?\s or line[0] == ?\t and value
          value << ' ' unless value.empty?
          value << line.strip
        else
          yield key, value if key
          key, value = line.strip.split(/\s*:\s*/, 2)
          raise Net::HTTPBadResponse, 'wrong header line format' if value.nil?
        end
      end
      yield key, value if key
    end

read_status_line(sock) click to toggle source

    # File lib/net/http/response.rb, line 157
    def read_status_line(sock)
      str = sock.readline
      m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)(?:\s+(.*))?\z/in.match(str) or
        raise Net::HTTPBadResponse, "wrong status line: #{str.dump}"
      m.captures
    end

response_class(code) click to toggle source

    # File lib/net/http/response.rb, line 164
    def response_class(code)
      CODE_TO_OBJ[code] or
      CODE_CLASS_TO_OBJ[code[0,1]] or
      Net::HTTPUnknownResponse
    end

### Public Instance Methods

body() click to toggle source

Returns the string response body; note that repeated calls for the unmodified body return a cached string:

    path = '/todos/1'
    Net::HTTP.start(hostname) do |http|
      res = http.get(path)
      p res.body
      p http.head(path).body # No body.
    end

Output:

    "{\n  \"userId\": 1,\n  \"id\": 1,\n  \"title\": \"delectus aut autem\",\n  \"completed\": false\n}"
    nil

    # File lib/net/http/response.rb, line 400
    def body
      read_body()
    end

Also aliased as: entity
body=(value) click to toggle source

Sets the body of the response to the given value.

    # File lib/net/http/response.rb, line 405
    def body=(value)
      @body = value
    end

body_encoding=(value) click to toggle source

Sets the encoding that should be used when reading the body:

- If the given value is an `Encoding` object, that encoding will be used.

- Otherwise if the value is a string, the value of Encoding#find(value) will be used.

- Otherwise an encoding will be deduced from the body itself.

Examples:

    http = Net::HTTP.new(hostname)
    req = Net::HTTP::Get.new('/')

    http.request(req) do |res|
      p res.body.encoding # => #<Encoding:ASCII-8BIT>
    end

    http.request(req) do |res|
      res.body_encoding = "UTF-8"
      p res.body.encoding # => #<Encoding:UTF-8>
    end

    # File lib/net/http/response.rb, line 253
    def body_encoding=(value)
      value = Encoding.find(value) if value.is_a?(String)
      @body_encoding = value
    end

entity()
Alias for: body
inspect() click to toggle source

    # File lib/net/http/response.rb, line 262
    def inspect
      "#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
    end

read_body(dest = nil, &block) click to toggle source

Gets the entity body returned by the remote HTTP server.

If a block is given, the body is passed to the block, and the body is provided in fragments, as it is read in from the socket.

If `dest` argument is given, response is read into that variable, with `dest#<<` method (it could be `String` or `IO`, or any other object responding to `<<`).

Calling this method a second or subsequent time for the same `HTTPResponse` object will return the value already read.

    http.request_get('/index.html') {|res|
      puts res.read_body
    }

    http.request_get('/index.html') {|res|
      p res.read_body.object_id   # 538149362
      p res.read_body.object_id   # 538149362
    }

    # using iterator
    http.request_get('/index.html') {|res|
      res.read_body do |segment|
        print segment
      end
    }

    # File lib/net/http/response.rb, line 355
    def read_body(dest = nil, &block)
      if @read
        raise IOError, "#{self.class}\#read_body called twice" if dest or block
        return @body
      end
      to = procdest(dest, block)
      stream_check
      if @body_exist
        read_body_0 to
        @body = to
      else
        @body = nil
      end
      @read = true
      return if @body.nil?

      case enc = @body_encoding
      when Encoding, false, nil
        # Encoding: force given encoding
        # false/nil: do not force encoding
      else
        # other value: detect encoding from body
        enc = detect_encoding(@body)
      end

      @body.force_encoding(enc) if enc

      @body
    end

value() click to toggle source

Raises an HTTP error if the response is not 2xx (success).

    # File lib/net/http/response.rb, line 285
    def value
      error! unless self.kind_of?(Net::HTTPSuccess)
    end