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

HTTP response class.

This class wraps together the response header and the response body (the entity requested).

It mixes in the HTTPHeader module, which provides access to response header values both via hash-like methods and via individual readers.

Note that each possible HTTP response code defines its own HTTPResponse subclass. All classes are defined under the ::Net module. Indentation indicates inheritance. For a list of the classes see HTTP.

Correspondence HTTP code => class is stored in CODE_TO_OBJ constant:

Net::HTTPResponse::CODE_TO_OBJ['404'] #=> Net::HTTPNotFound

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 full entity body.

  • #body=(value) rw

    Because it may be necessary to modify the body, Eg, decompression this method facilitates that.

  • #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.

  • #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 the “transfer-encoding” header is present and set to “chunked”.

#connection_close?, #connection_keep_alive?,
#content_length

Returns an Integer object which represents the HTTP Content-Length: header field, or nil if that field was not provided.

#content_length=

Instance Method Summary

HTTPHeader - Included

#[]

Returns the header field corresponding to the case-insensitive key.

#[]=

Sets the header field corresponding to the case-insensitive key.

#add_field
Ruby 1.8.3

Adds a value to a named header field, instead of replacing its value.

#basic_auth

Set the Authorization: header for “Basic” authorization.

#canonical_each
#content_range

Returns a Range object which represents the value of the Content-Range: header field.

#content_type

Returns a content type string such as “text/html”.

#content_type=
#delete

Removes a header field, specified by case-insensitive key.

#each
#each_capitalized

As for #each_header, except the keys are provided in capitalized form.

#each_capitalized_name

Iterates through the header names in the header, passing capitalized header names to the code block.

#each_header

Iterates through the header names and values, passing in the name and value to the code block supplied.

#each_key
#each_name

Iterates through the header names in the header, passing each header name to the code block.

#each_value

Iterates through header values, passing each value to the code block.

#fetch

Returns the header field corresponding to the case-insensitive key.

#form_data=
#get_fields
Ruby 1.8.3

Returns an array of header field strings corresponding to the case-insensitive key.

#initialize_http_header,
#key?

true if key header exists.

#main_type

Returns a content type string such as “text”.

#proxy_basic_auth

Set Proxy-Authorization: header for “Basic” authorization.

#range

Returns an Array of Range objects which represent the Range: HTTP header field, or nil if there is no such header.

#range=
#range_length

The length of the range represented in Content-Range: header.

#set_content_type

Sets the content type in an HTTP header.

#set_form

Set an HTML form data set.

#set_form_data

Set header fields and a body from HTML form data.

#set_range

Sets the HTTP Range: header.

#sub_type

Returns a content type string such as “html”.

#to_hash

Returns a Hash consisting of header names and array of values.

#type_params

Any parameters specified for the content type, returned as a Hash.

#append_field_value, #basic_encode, #capitalize, #set_field,
#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 78

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
end

Class Attribute Details

.body_permitted?Boolean (readonly)

true if the response has a body.

[ GitHub ]

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

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 54

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 26

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 30

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 41

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 48

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 full entity body.

Calling this method a second or subsequent time will return the string already read.

http.request_get(‘/index.html’) {|res|

  puts res.body
}

http.request_get(‘/index.html’) {|res|

  p res.body.object_id   # 538149362
  p res.body.object_id   # 538149362
}
[ GitHub ]

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

def body
  read_body()
end

#body=(value) (rw)

Because it may be necessary to modify the body, Eg, decompression this method facilitates that.

[ GitHub ]

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

def body=(value)
  @body = 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 95

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 107

attr_accessor :decode_content

#entity (readonly)

This method is for internal use only.

Alias for #body.

[ GitHub ]

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

alias entity body   #:nodoc: obsolete

#http_version (readonly)

The HTTP version supported by the server.

[ GitHub ]

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

attr_reader :http_version

#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 98

attr_reader :message

#msg (readonly)

This method is for internal use only.

Alias for #message.

[ GitHub ]

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

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 103

attr_reader :uri

#uri=(uri) (rw)

This method is for internal use only.
[ GitHub ]

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

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

Instance Method Details

#code_type

This method is for internal use only.

response <-> exception relationship

[ GitHub ]

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

def code_type   #:nodoc:
  self.class
end

#error!

This method is for internal use only.

Raises:

[ GitHub ]

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

def error!   #:nodoc:
  message = @code
  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 127

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

#header

This method is for internal use only.
[ GitHub ]

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

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 257

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
      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 109

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

#procdest(dest, block) (private)

Raises:

  • (ArgumentError)
[ GitHub ]

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

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 202

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

  @body
end

#read_body_0(dest) (private)

[ GitHub ]

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

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, true   # 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 319

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 154

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 163

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 144

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

#stream_check (private)

Raises:

  • (IOError)
[ GitHub ]

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

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

#value

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

[ GitHub ]

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

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