Class: Gem::Net::HTTPResponse
Overview
This class is the base class for Gem::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 ::Gem::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 Gem::Net::HTTPResponse:
Gem::Net::HTTP.get_response(uri)
# => #<Gem::Net::HTTPOK 200 OK readbody=true>
Gem::Net::HTTP.get_response(hostname, '/nosuch')
# => #<Gem::Net::HTTPNotFound 404 Not Found readbody=true>
As does method HTTP#request:
req = Gem::Net::HTTP::Get.new(uri)
Gem::Net::HTTP.start(hostname) do |http|
http.request(req)
end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
Class Gem::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 = Gem::Net::HTTP.get_response(uri) # => #<Gem::Net::HTTPOK 200 OK readbody=true>
res['Content-Type'] # => "text/html; charset=UTF-8"
res.content_type # => "text/html"
Response Subclasses
Class Gem::Net::HTTPResponse has a subclass for each {Gem::Net::HTTP status code}. You can look up the response class for a given code:
Gem::Net::HTTPResponse::CODE_TO_OBJ['200'] # => Gem::Net::HTTPOK
Gem::Net::HTTPResponse::CODE_TO_OBJ['400'] # => Gem::Net::HTTPBadRequest
Gem::Net::HTTPResponse::CODE_TO_OBJ['404'] # => Gem::Net::HTTPNotFound
And you can retrieve the status code for a response object:
Gem::Net::HTTP.get_response(uri).code # => "200"
Gem::Net::HTTP.get_response(hostname, '/nosuch').code # => "404"
The response subclasses (indentation shows class hierarchy):
-
HTTPUnknownResponse
(for unhandled HTTP extensions). -
-
Gem::Net::HTTPContinue (100)
-
Gem::Net::HTTPSwitchProtocol (101)
-
Gem::Net::HTTPProcessing (102)
-
Gem::Net::HTTPEarlyHints (103)
-
-
-
Gem::Net::HTTPOK (200)
-
Gem::Net::HTTPCreated (201)
-
Gem::Net::HTTPAccepted (202)
-
Gem::Net::HTTPNonAuthoritativeInformation (203)
-
Gem::Net::HTTPNoContent (204)
-
Gem::Net::HTTPResetContent (205)
-
Gem::Net::HTTPPartialContent (206)
-
Gem::Net::HTTPMultiStatus (207)
-
Gem::Net::HTTPAlreadyReported (208)
-
Gem::Net::HTTPIMUsed (226)
-
-
-
Gem::Net::HTTPMultipleChoices (300)
-
Gem::Net::HTTPMovedPermanently (301)
-
Gem::Net::HTTPFound (302)
-
Gem::Net::HTTPSeeOther (303)
-
Gem::Net::HTTPNotModified (304)
-
Gem::Net::HTTPUseProxy (305)
-
Gem::Net::HTTPTemporaryRedirect (307)
-
Gem::Net::HTTPPermanentRedirect (308)
-
-
-
Gem::Net::HTTPBadRequest (400)
-
Gem::Net::HTTPUnauthorized (401)
-
Gem::Net::HTTPPaymentRequired (402)
-
Gem::Net::HTTPForbidden (403)
-
Gem::Net::HTTPNotFound (404)
-
Gem::Net::HTTPMethodNotAllowed (405)
-
Gem::Net::HTTPNotAcceptable (406)
-
Gem::Net::HTTPProxyAuthenticationRequired (407)
-
Gem::Net::HTTPRequestTimeOut (408)
-
Gem::Net::HTTPConflict (409)
-
Gem::Net::HTTPGone (410)
-
Gem::Net::HTTPLengthRequired (411)
-
Gem::Net::HTTPPreconditionFailed (412)
-
Gem::Net::HTTPRequestEntityTooLarge (413)
-
Gem::Net::HTTPRequestURITooLong (414)
-
Gem::Net::HTTPUnsupportedMediaType (415)
-
Gem::Net::HTTPRequestedRangeNotSatisfiable (416)
-
Gem::Net::HTTPExpectationFailed (417)
-
Gem::Net::HTTPMisdirectedRequest (421)
-
Gem::Net::HTTPUnprocessableEntity (422)
-
Gem::Net::HTTPLocked (423)
-
Gem::Net::HTTPFailedDependency (424)
-
Gem::Net::HTTPUpgradeRequired (426)
-
Gem::Net::HTTPPreconditionRequired (428)
-
Gem::Net::HTTPTooManyRequests (429)
-
Gem::Net::HTTPRequestHeaderFieldsTooLarge (431)
-
Gem::Net::HTTPUnavailableForLegalReasons (451)
-
-
-
Gem::Net::HTTPInternalServerError (500)
-
Gem::Net::HTTPNotImplemented (501)
-
Gem::Net::HTTPBadGateway (502)
-
Gem::Net::HTTPServiceUnavailable (503)
-
Gem::Net::HTTPGatewayTimeOut (504)
-
Gem::Net::HTTPVersionNotSupported (505)
-
Gem::Net::HTTPVariantAlsoNegotiates (506)
-
Gem::Net::HTTPInsufficientStorage (507)
-
Gem::Net::HTTPLoopDetected (508)
-
Gem::Net::HTTPNotExtended (510)
-
Gem::Net::HTTPNetworkAuthenticationRequired (511)
-
There is also the HTTPBadResponse
exception which is raised when there is a protocol error.
Constant Summary
-
CODE_CLASS_TO_OBJ =
# File 'lib/rubygems/vendor/net-http/lib/net/http/responses.rb', line 1101{ '1' => Gem::Net::HTTPInformation, '2' => Gem::Net::HTTPSuccess, '3' => Gem::Net::HTTPRedirection, '4' => Gem::Net::HTTPClientError, '5' => Gem::Net::HTTPServerError }
-
CODE_TO_OBJ =
# File 'lib/rubygems/vendor/net-http/lib/net/http/responses.rb', line 1108{ '100' => Gem::Net::HTTPContinue, '101' => Gem::Net::HTTPSwitchProtocol, '102' => Gem::Net::HTTPProcessing, '103' => Gem::Net::HTTPEarlyHints, '200' => Gem::Net::HTTPOK, '201' => Gem::Net::HTTPCreated, '202' => Gem::Net::HTTPAccepted, '203' => Gem::Net::HTTPNonAuthoritativeInformation, '204' => Gem::Net::HTTPNoContent, '205' => Gem::Net::HTTPResetContent, '206' => Gem::Net::HTTPPartialContent, '207' => Gem::Net::HTTPMultiStatus, '208' => Gem::Net::HTTPAlreadyReported, '226' => Gem::Net::HTTPIMUsed, '300' => Gem::Net::HTTPMultipleChoices, '301' => Gem::Net::HTTPMovedPermanently, '302' => Gem::Net::HTTPFound, '303' => Gem::Net::HTTPSeeOther, '304' => Gem::Net::HTTPNotModified, '305' => Gem::Net::HTTPUseProxy, '307' => Gem::Net::HTTPTemporaryRedirect, '308' => Gem::Net::HTTPPermanentRedirect, '400' => Gem::Net::HTTPBadRequest, '401' => Gem::Net::HTTPUnauthorized, '402' => Gem::Net::HTTPPaymentRequired, '403' => Gem::Net::HTTPForbidden, '404' => Gem::Net::HTTPNotFound, '405' => Gem::Net::HTTPMethodNotAllowed, '406' => Gem::Net::HTTPNotAcceptable, '407' => Gem::Net::HTTPProxyAuthenticationRequired, '408' => Gem::Net::HTTPRequestTimeout, '409' => Gem::Net::HTTPConflict, '410' => Gem::Net::HTTPGone, '411' => Gem::Net::HTTPLengthRequired, '412' => Gem::Net::HTTPPreconditionFailed, '413' => Gem::Net::HTTPPayloadTooLarge, '414' => Gem::Net::HTTPURITooLong, '415' => Gem::Net::HTTPUnsupportedMediaType, '416' => Gem::Net::HTTPRangeNotSatisfiable, '417' => Gem::Net::HTTPExpectationFailed, '421' => Gem::Net::HTTPMisdirectedRequest, '422' => Gem::Net::HTTPUnprocessableEntity, '423' => Gem::Net::HTTPLocked, '424' => Gem::Net::HTTPFailedDependency, '426' => Gem::Net::HTTPUpgradeRequired, '428' => Gem::Net::HTTPPreconditionRequired, '429' => Gem::Net::HTTPTooManyRequests, '431' => Gem::Net::HTTPRequestHeaderFieldsTooLarge, '451' => Gem::Net::HTTPUnavailableForLegalReasons, '500' => Gem::Net::HTTPInternalServerError, '501' => Gem::Net::HTTPNotImplemented, '502' => Gem::Net::HTTPBadGateway, '503' => Gem::Net::HTTPServiceUnavailable, '504' => Gem::Net::HTTPGatewayTimeout, '505' => Gem::Net::HTTPVersionNotSupported, '506' => Gem::Net::HTTPVariantAlsoNegotiates, '507' => Gem::Net::HTTPInsufficientStorage, '508' => Gem::Net::HTTPLoopDetected, '510' => Gem::Net::HTTPNotExtended, '511' => Gem::Net::HTTPNetworkAuthenticationRequired, }
HTTPHeader
- Included
Class Attribute Summary
-
.body_permitted? ⇒ Boolean
readonly
true if the response has a body.
Class Method Summary
- .each_response_header(sock) {|key, value| ... } private
- .read_status_line(sock) private
- .response_class(code) private
-
.exception_type
Internal use only
internal use only.
-
.new(httpv, code, msg) ⇒ HTTPResponse
constructor
Internal use only
internal use only.
-
.read_new(sock)
Internal use only
internal use only.
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
::Gem::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 |
#connection_close? | Returns whether the |
#connection_keep_alive? | Returns whether the |
#content_length | Returns the value of field |
#content_length= | Sets the value of field |
Instance Method Summary
- #inspect
-
#read_body(dest = nil, &block)
Gets the entity body returned by the remote
HTTP
server. -
#value
Raises an
HTTP
error if the response is not 2xx (success). - #extracting_encodings_from_meta_elements(value) private
- #get_attribute(ss) private
- #procdest(dest, block) private
- #read_body_0(dest) private
- #stream_check private
-
#code_type
Internal use only
response <-> exception relationship.
- #error! Internal use only
- #error_type Internal use only
- #header Internal use only
- #read_header Internal use only
-
#reading_body(sock, reqmethodallowbody)
Internal use only
body.
-
#response
Internal use only
header (for backward compatibility only; DO NOT USE).
- #check_bom(str) private Internal use only
- #detect_encoding(str, encoding = nil) private Internal use only
-
#inflater
private
Internal use only
Checks for a supported Content-Encoding header and yields an Inflate wrapper for this response’s socket when zlib is present.
-
#read_chunked(dest, chunk_data_io)
private
Internal use only
read_chunked reads from
@socket
for chunk-size, chunk-extension, CRLF, etc. - #scanning_meta(str) private Internal use only
- #sniff_encoding(str, encoding = nil) private Internal use only
HTTPHeader
- Included
#[] | Returns the string field value for the case-insensitive field |
#[]= | Sets the value for the case-insensitive |
#add_field | Adds value |
#basic_auth | Sets header |
#canonical_each | Alias for HTTPHeader#each_capitalized. |
#content_range | Returns a Range object representing the value of field |
#content_type | Returns the media type from the value of field |
#content_type= | Alias for HTTPHeader#set_content_type. |
#delete | Removes the header for the given case-insensitive |
#each | Alias for HTTPHeader#each_header. |
#each_capitalized | Like |
#each_capitalized_name | Calls the block with each capitalized field name: |
#each_header | Calls the block with each key/value pair: |
#each_key | Alias for HTTPHeader#each_name. |
#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 |
#form_data= | Alias for HTTPHeader#set_form_data. |
#get_fields | Returns the array field value for the given |
#key? | Returns |
#main_type | Returns the leading (‘type’) part of the media type from the value of field |
#proxy_basic_auth | Sets header |
#range | Returns an array of Range objects that represent the value of field |
#range= | Alias for HTTPHeader#set_range. |
#range_length | Returns the integer representing length of the value of field |
#set_content_type | Sets the value of field |
#set_form | Stores form data to be used in a |
#set_form_data | Sets the request body to a URL-encoded string derived from argument |
#set_range | Sets the value for field |
#sub_type | Returns the trailing (‘subtype’) part of the media type from the value of field |
#to_hash | Returns a hash of the key/value pairs: |
#type_params | Returns the trailing (‘parameters’) part of the value of field |
#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
internal use only
# File 'lib/rubygems/vendor/net-http/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.
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 138
def body_permitted? self::HAS_BODY end
Class Method Details
.each_response_header(sock) {|key, value| ... } (private)
# File 'lib/rubygems/vendor/net-http/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 Gem::Net::HTTPBadResponse, 'wrong header line format' if value.nil? end end yield key, value if key end
.exception_type
internal use only
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 142
def exception_type # :nodoc: internal use only self::EXCEPTION_TYPE end
.read_new(sock)
internal use only
# File 'lib/rubygems/vendor/net-http/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/rubygems/vendor/net-http/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 Gem::Net::HTTPBadResponse, "wrong status line: #{str.dump}" m.captures end
.response_class(code) (private)
[ GitHub ]# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 164
def response_class(code) CODE_TO_OBJ[code] or CODE_CLASS_TO_OBJ[code[0,1]] or Gem::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'
Gem::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/rubygems/vendor/net-http/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.
#body_encoding (rw)
Returns the value set by body_encoding=, or false
if none; see #body_encoding=.
# File 'lib/rubygems/vendor/net-http/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 = Gem::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
#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.
# File 'lib/rubygems/vendor/net-http/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.
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 225
attr_accessor :decode_content
#entity (readonly)
Alias for #body.
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 409
alias entity body #:nodoc: obsolete
#http_version (readonly)
The HTTP version supported by the server.
# File 'lib/rubygems/vendor/net-http/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.
# File 'lib/rubygems/vendor/net-http/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’.
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 216
attr_reader :
#msg (readonly)
Alias for #message.
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 217
alias msg # :nodoc: obsolete
#uri (rw)
The ::Gem::URI
used to fetch this response. The response ::Gem::URI
is only available if a ::Gem::URI
was used to create the request.
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 221
attr_reader :uri
#uri=(uri) (rw)
Instance Method Details
#check_bom(str) (private)
# File 'lib/rubygems/vendor/net-http/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
response <-> exception relationship
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 270
def code_type #:nodoc: self.class end
#detect_encoding(str, encoding = nil) (private)
# File 'lib/rubygems/vendor/net-http/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!
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 274
def error! #:nodoc: = @code = "#{} #{@message.dump}" if @message raise error_type().new(, self) end
#error_type
# File 'lib/rubygems/vendor/net-http/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/rubygems/vendor/net-http/lib/net/http/response.rb', line 540
def (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/rubygems/vendor/net-http/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
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 302
def header #:nodoc: warn "Gem::Net::HTTPResponse#header is obsolete", uplevel: 1 if $VERBOSE self end
#inflater (private)
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.
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 557
def inflater # :nodoc: return yield @socket unless Gem::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/rubygems/vendor/net-http/lib/net/http/response.rb', line 262
def inspect "#<#{self.class} #{@code} #{@message} readbody=#{@read}>" end
#procdest(dest, block) (private)
# File 'lib/rubygems/vendor/net-http/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 Gem::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
}
# File 'lib/rubygems/vendor/net-http/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/rubygems/vendor/net-http/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)
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
# File 'lib/rubygems/vendor/net-http/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 Gem::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
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 307
def read_header #:nodoc: warn "Gem::Net::HTTPResponse#read_header is obsolete", uplevel: 1 if $VERBOSE self end
#reading_body(sock, reqmethodallowbody)
body
# File 'lib/rubygems/vendor/net-http/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
header (for backward compatibility only; DO NOT USE)
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 297
def response #:nodoc: warn "Gem::Net::HTTPResponse#response is obsolete", uplevel: 1 if $VERBOSE self end
#scanning_meta(str) (private)
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 464
def (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 = (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)
# File 'lib/rubygems/vendor/net-http/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 = (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)
# File 'lib/rubygems/vendor/net-http/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).
# File 'lib/rubygems/vendor/net-http/lib/net/http/response.rb', line 285
def value error! unless self.kind_of?(Gem::Net::HTTPSuccess) end