123456789_123456789_123456789_123456789_123456789_

Class: Net::HTTPResponse

Relationships & Source Files
Namespace Children
Classes:
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, HTTPHeader
Inherits: Object
Defined in: lib/net/http/response.rb,
lib/net/http/responses.rb

Overview

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:

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 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 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 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 {Net::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):

  • HTTPUnknownResponse (for unhandled HTTP extensions).

  • HTTPInformation:

    • Net::HTTPContinue (100)

    • Net::HTTPSwitchProtocol (101)

    • Net::HTTPProcessing (102)

    • Net::HTTPEarlyHints (103)

  • 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)

  • 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)

  • 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)

  • 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 HTTPBadResponse exception which is raised when there is a protocol error.

Constant Summary

HTTPHeader - Included

MAX_FIELD_LENGTH, MAX_KEY_LENGTH

Class Attribute Summary

Class Method Summary

Instance Attribute Summary

  • #body (also: #entity) rw

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

  • #body=(value) rw

    Sets the body of the response to the given value.

  • #body_encoding rw

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

  • #body_encoding=(value) rw

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

  • #code readonly

    The HTTP result code string.

  • #decode_content rw

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

  • #http_version readonly

    The HTTP version supported by the server.

  • #ignore_eof rw

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

  • #message (also: #msg) readonly

    The HTTP result message sent by the server.

  • #uri rw

    The URI used to fetch this response.

  • #entity readonly Internal use only

    Alias for #body.

  • #msg readonly Internal use only

    Alias for #message.

  • #uri=(uri) rw Internal use only

HTTPHeader - Included

#chunked?

Returns true if field 'Transfer-Encoding' exists and has value 'chunked', false otherwise; see Transfer-Encoding response header:

#connection_close?

Returns whether the HTTP session is to be closed.

#connection_keep_alive?

Returns whether the HTTP session is to be kept alive.

#content_length

Returns the value of field 'Content-Length' as an integer, or nil if there is no such field; see Content-Length request header:

#content_length=

Sets the value of field 'Content-Length' to the given numeric; see Content-Length response header:

Instance Method Summary

HTTPHeader - Included

#[]

Returns the string field value for the case-insensitive field key, or nil if there is no such key; see Fields:

#[]=

Sets the value for the case-insensitive key to val, overwriting the previous value if the field exists; see Fields:

#add_field

Adds value val to the value array for field key if the field exists; creates the field with the given key and val if it does not exist.

#basic_auth

Sets header 'Authorization' using the given account and password strings:

#canonical_each
#content_range

Returns a Range object representing the value of field 'Content-Range', or nil if no such field exists; see Content-Range response header:

#content_type

Returns the media type from the value of field 'Content-Type', or nil if no such field exists; see Content-Type response header:

#content_type=
#delete

Removes the header for the given case-insensitive key (see Fields); returns the deleted value, or nil if no such field exists:

#each
#each_capitalized

Like #each_header, but the keys are returned in capitalized form.

#each_capitalized_name

Calls the block with each capitalized field name:

#each_header

Calls the block with each key/value pair:

#each_key
#each_name

Calls the block with each field key:

#each_value

Calls the block with each string field value:

#fetch

With a block, returns the string value for key if it exists; otherwise returns the value of the block; ignores the default_val; see Fields:

#form_data=
#get_fields

Returns the array field value for the given key, or nil if there is no such field; see Fields:

#key?

Returns true if the field for the case-insensitive key exists, false otherwise:

#main_type

Returns the leading (‘type’) part of the media type from the value of field 'Content-Type', or nil if no such field exists; see Content-Type response header:

#proxy_basic_auth

Sets header 'Proxy-Authorization' using the given account and password strings:

#range

Returns an array of Range objects that represent the value of field 'Range', or nil if there is no such field; see Range request header:

#range=
#range_length

Returns the integer representing length of the value of field 'Content-Range', or nil if no such field exists; see Content-Range response header:

#set_content_type

Sets the value of field 'Content-Type'; returns the new value; see Content-Type request header:

#set_form

Stores form data to be used in a POST or PUT request.

#set_form_data

Sets the request body to a URL-encoded string derived from argument params, and sets request header field 'Content-Type' to 'application/x-www-form-urlencoded'.

#set_range

Sets the value for field 'Range'; see Range request header:

#sub_type

Returns the trailing (‘subtype’) part of the media type from the value of field 'Content-Type', or nil if no such field exists; see Content-Type response header:

#to_hash

Returns a hash of the key/value pairs:

#type_params

Returns the trailing (‘parameters’) part of the value of field 'Content-Type', or nil if no such field exists; see Content-Type response header:

#append_field_value, #basic_encode, #capitalize, #set_field, #initialize_http_header,
#length

Alias for HTTPHeader#size.

#size

obsolete.

Constructor Details

.new(httpv, code, msg) ⇒ HTTPResponse

This method is for internal use only.

internal use only

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 194

def initialize(httpv, code, msg)   #:nodoc: internal use only
  @http_version = httpv
  @code         = code
  @message      = msg
  initialize_http_header nil
  @body = nil
  @read = false
  @uri  = nil
  @decode_content = false
  @body_encoding = false
  @ignore_eof = true
end

Class Attribute Details

.body_permitted?Boolean (readonly)

true if the response has a body.

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 138

def body_permitted?
  self::HAS_BODY
end

Class Method Details

.each_response_header(sock) {|key, value| ... } (private)

Yields:

[ GitHub ]

  
# 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

.exception_type

This method is for internal use only.

internal use only

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 142

def exception_type   # :nodoc: internal use only
  self::EXCEPTION_TYPE
end

.read_new(sock)

This method is for internal use only.

internal use only

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 146

def read_new(sock)   #:nodoc: internal use only
  httpv, code, msg = read_status_line(sock)
  res = response_class(code).new(httpv, code, msg)
  each_response_header(sock) do |k,v|
    res.add_field k, v
  end
  res
end

.read_status_line(sock) (private)

[ GitHub ]

  
# 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) (private)

[ GitHub ]

  
# 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

Instance Attribute Details

#body (rw) Also known as: #entity

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
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 400

def body
  read_body()
end

#body=(value) (rw)

Sets the body of the response to the given value.

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 405

def body=(value)
  @body = value
end

#body_encoding (rw)

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

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 229

attr_reader :body_encoding

#body_encoding=(value) (rw)

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 = 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
[ GitHub ]

  
# 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

#code (readonly)

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.

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 213

attr_reader :code

#decode_content (rw)

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

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 225

attr_accessor :decode_content

#entity (readonly)

This method is for internal use only.

Alias for #body.

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 409

alias entity body   #:nodoc: obsolete

#http_version (readonly)

The HTTP version supported by the server.

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 208

attr_reader :http_version

#ignore_eof (rw)

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

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 260

attr_accessor :ignore_eof

#message (readonly) Also known as: #msg

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

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 216

attr_reader :message

#msg (readonly)

This method is for internal use only.

Alias for #message.

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 217

alias msg message   # :nodoc: obsolete

#uri (rw)

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

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 221

attr_reader :uri

#uri=(uri) (rw)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 289

def uri= uri # :nodoc:
  @uri = uri.dup if uri
end

Instance Method Details

#check_bom(str) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 450

def check_bom(str)
  case str.byteslice(0, 2)
  when "\xFE\xFF"
    return Encoding::UTF_16BE
  when "\xFF\xFE"
    return Encoding::UTF_16LE
  end
  if "\xEF\xBB\xBF" == str.byteslice(0, 3)
    return Encoding::UTF_8
  end
  nil
end

#code_type

This method is for internal use only.

response <-> exception relationship

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 270

def code_type   #:nodoc:
  self.class
end

#detect_encoding(str, encoding = nil) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 414

def detect_encoding(str, encoding=nil)
  if encoding
  elsif encoding = type_params['charset']
  elsif encoding = check_bom(str)
  else
    encoding = case content_type&.downcase
    when %r{text/x(?:ht)?ml|application/(?:[^]\+)?xml}
      /\A<xml[ \t\r\n]+
        version[ \t\r\n]*=[ \t\r\n]*(?:"[0-9.]+"|'[0-9.]*')[ \t\r\n]+
        encoding[ \t\r\n]*=[ \t\r\n]*
        (?:"([A-Za-z][\-A-Za-z0-9._]*)"|'([A-Za-z][\-A-Za-z0-9._]*)')/x =~ str
      encoding = $1 || $2 || Encoding::UTF_8
    when %r{text/html.*}
      sniff_encoding(str)
    end
  end
  return encoding
end

#error!

This method is for internal use only.

Raises:

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 274

def error!   #:nodoc:
  message = @code
  message = "#{message} #{@message.dump}" if @message
  raise error_type().new(message, self)
end

#error_type

This method is for internal use only.
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 280

def error_type   #:nodoc:
  self.class::EXCEPTION_TYPE
end

#extracting_encodings_from_meta_elements(value) (private)

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 540

def extracting_encodings_from_meta_elements(value)
  # http://dev.w3.org/html5/spec/fetching-resources.html#algorithm-for-extracting-an-encoding-from-a-meta-element
  if /charset[\t\n\f\r ]*=(?:"([^"]*)"|'([^']*)'|["']|\z|([^\t\n\f\r ;]+))/i =~ value
    return $1 || $2 || $3
  end
  return nil
end

#get_attribute(ss) (private)

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 505

def get_attribute(ss)
  ss.scan(/[\t\n\f\r \/]*/)
  if ss.peek(1) == '>'
    ss.getch
    return nil
  end
  name = ss.scan(/[^=\t\n\f\r \/>]*/)
  name.downcase!
  raise if name.empty?
  ss.skip(/[\t\n\f\r ]*/)
  if ss.getch != '='
    value = ''
    return [name, value]
  end
  ss.skip(/[\t\n\f\r ]*/)
  case ss.peek(1)
  when '"'
    ss.getch
    value = ss.scan(/[^"]+/)
    value.downcase!
    ss.getch
  when "'"
    ss.getch
    value = ss.scan(/[^']+/)
    value.downcase!
    ss.getch
  when '>'
    value = ''
  else
    value = ss.scan(/[^\t\n\f\r >]+/)
    value.downcase!
  end
  [name, value]
end

#header

This method is for internal use only.
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 302

def header   #:nodoc:
  warn "Net::HTTPResponse#header is obsolete", uplevel: 1 if $VERBOSE
  self
end

#inflater (private)

This method is for internal use only.

Checks for a supported Content-Encoding header and yields an Inflate wrapper for this response’s socket when zlib is present. If the Content-Encoding is not supported or zlib is missing, the plain socket is yielded.

If a Content-Range header is present, a plain socket is yielded as the bytes in the range may not be a complete deflate block.

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 557

def inflater # :nodoc:
  return yield @socket unless Net::HTTP::HAVE_ZLIB
  return yield @socket unless @decode_content
  return yield @socket if self['content-range']

  v = self['content-encoding']
  case v&.downcase
  when 'deflate', 'gzip', 'x-gzip' then
    self.delete 'content-encoding'

    inflate_body_io = Inflater.new(@socket)

    begin
      yield inflate_body_io
      success = true
    ensure
      begin
        inflate_body_io.finish
        if self['content-length']
          self['content-length'] = inflate_body_io.bytes_inflated.to_s
        end
      rescue => err
        # Ignore #finish's error if there is an exception from yield
        raise err if success
      end
    end
  when 'none', 'identity' then
    self.delete 'content-encoding'

    yield @socket
  else
    yield @socket
  end
end

#inspect

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 262

def inspect
  "#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
end

#procdest(dest, block) (private)

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 646

def procdest(dest, block)
  raise ArgumentError, 'both arg and block given for HTTP method' if
    dest and block
  if block
    Net::ReadAdapter.new(block)
  else
    dest || +''
  end
end

#read_body(dest = nil, &block)

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
}
[ GitHub ]

  
# 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

#read_body_0(dest) (private)

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 592

def read_body_0(dest)
  inflater do |inflate_body_io|
    if chunked?
      read_chunked dest, inflate_body_io
      return
    end

    @socket = inflate_body_io

    clen = content_length()
    if clen
      @socket.read clen, dest, @ignore_eof
      return
    end
    clen = range_length()
    if clen
      @socket.read clen, dest
      return
    end
    @socket.read_all dest
  end
end

#read_chunked(dest, chunk_data_io) (private)

This method is for internal use only.

read_chunked reads from @socket for chunk-size, chunk-extension, CRLF, etc. and chunk_data_io for chunk-data which may be deflate or gzip encoded.

See RFC 2616 section 3.6.1 for definitions

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 622

def read_chunked(dest, chunk_data_io) # :nodoc:
  total = 0
  while true
    line = @socket.readline
    hexlen = line.slice(/[0-9a-fA-F]+/) or
        raise Net::HTTPBadResponse, "wrong chunk size line: #{line}"
    len = hexlen.hex
    break if len == 0
    begin
      chunk_data_io.read len, dest
    ensure
      total += len
      @socket.read 2   # \r\n
    end
  end
  until @socket.readline.empty?
    # none
  end
end

#read_header

This method is for internal use only.
[ GitHub ]

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

def read_header   #:nodoc:
  warn "Net::HTTPResponse#read_header is obsolete", uplevel: 1 if $VERBOSE
  self
end

#reading_body(sock, reqmethodallowbody)

This method is for internal use only.

body

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 316

def reading_body(sock, reqmethodallowbody)  #:nodoc: internal use only
  @socket = sock
  @body_exist = reqmethodallowbody && self.class.body_permitted?
  begin
    yield
    self.body   # ensure to read body
  ensure
    @socket = nil
  end
end

#response

This method is for internal use only.

header (for backward compatibility only; DO NOT USE)

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 297

def response   #:nodoc:
  warn "Net::HTTPResponse#response is obsolete", uplevel: 1 if $VERBOSE
  self
end

#scanning_meta(str) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 464

def scanning_meta(str)
  require 'strscan'
  ss = StringScanner.new(str)
  if ss.scan_until(/<meta[\t\n\f\r ]*/)
    attrs = {} # attribute_list
    got_pragma = false
    need_pragma = nil
    charset = nil

    # step: Attributes
    while attr = get_attribute(ss)
      name, value = *attr
      next if attrs[name]
      attrs[name] = true
      case name
      when 'http-equiv'
        got_pragma = true if value == 'content-type'
      when 'content'
        encoding = extracting_encodings_from_meta_elements(value)
        unless charset
          charset = encoding
        end
        need_pragma = true
      when 'charset'
        need_pragma = false
        charset = value
      end
    end

    # step: Processing
    return if need_pragma.nil?
    return if need_pragma && !got_pragma

    charset = Encoding.find(charset) rescue nil
    return unless charset
    charset = Encoding::UTF_8 if charset == Encoding::UTF_16
    return charset # tentative
  end
  nil
end

#sniff_encoding(str, encoding = nil) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 434

def sniff_encoding(str, encoding=nil)
  # the encoding sniffing algorithm
  # http://www.w3.org/TR/html5/parsing.html#determining-the-character-encoding
  if enc = scanning_meta(str)
    enc
  # 6. last visited page or something
  # 7. frequency
  elsif str.ascii_only?
    Encoding::US_ASCII
  elsif str.dup.force_encoding(Encoding::UTF_8).valid_encoding?
    Encoding::UTF_8
  end
  # 8. implementation-defined or user-specified
end

#stream_check (private)

Raises:

  • (IOError)
[ GitHub ]

  
# File 'lib/net/http/response.rb', line 642

def stream_check
  raise IOError, 'attempt to read body out of block' if @socket.nil? || @socket.closed?
end

#value

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

[ GitHub ]

  
# File 'lib/net/http/response.rb', line 285

def value
  error! unless self.kind_of?(Net::HTTPSuccess)
end