module RestClient::AbstractResponse
Attributes
Public Class Methods
Convert headers hash into canonical form.
Header names will be converted to lowercase symbols with underscores instead of hyphens.
Headers specified multiple times will be joined by comma and space, except for Set-Cookie, which will always be an array.
Per RFC 2616, if a server sends multiple headers with the same key, they MUST be able to be joined into a single header by a comma. However, Set-Cookie (RFC 6265) cannot because commas are valid within cookie definitions. The newer RFC 7230 notes (3.2.2) that Set-Cookie should be handled as a special case.
tools.ietf.org/html/rfc2616#section-4.2 tools.ietf.org/html/rfc7230#section-3.2.2 tools.ietf.org/html/rfc6265
@param headers [Hash] @return [Hash]
# File lib/restclient/abstract_response.rb, line 179 def self.beautify_headers(headers) headers.inject({}) do |out, (key, value)| key_sym = key.tr('-', '_').downcase.to_sym # Handle Set-Cookie specially since it cannot be joined by comma. if key.downcase == 'set-cookie' out[key_sym] = value else out[key_sym] = value.join(', ') end out end end
Public Instance Methods
HTTP status code
# File lib/restclient/abstract_response.rb, line 30 def code @code ||= @net_http_res.code.to_i end
# File lib/restclient/abstract_response.rb, line 138 def description "#{code} #{STATUSES[code]} | #{(headers[:content_type] || '').gsub(/;.*$/, '')} #{size} bytes\n" end
Follow a redirection response, but change the HTTP method to GET and drop the payload from the original request.
# File lib/restclient/abstract_response.rb, line 150 def follow_get_redirection(&block) new_args = request.args.dup new_args[:method] = :get new_args.delete(:payload) _follow_redirection(new_args, &block) end
Follow a redirection response by making a new HTTP request to the redirection target.
# File lib/restclient/abstract_response.rb, line 144 def follow_redirection(&block) _follow_redirection(request.args.dup, &block) end
A hash of the headers, beautified with symbols and underscores. e.g. “Content-type” will become :content_type.
# File lib/restclient/abstract_response.rb, line 40 def headers @headers ||= AbstractResponse.beautify_headers(@net_http_res.to_hash) end
# File lib/restclient/abstract_response.rb, line 34 def history @history ||= request.redirection_history || [] end
# File lib/restclient/abstract_response.rb, line 10 def inspect raise NotImplementedError.new('must override in subclass') end
Logger from the request, potentially nil.
# File lib/restclient/abstract_response.rb, line 15 def log request.log end
# File lib/restclient/abstract_response.rb, line 19 def log_response return unless log code = net_http_res.code res_name = net_http_res.class.to_s.gsub(/\ANet::HTTP/, '') content_type = (net_http_res['Content-type'] || '').gsub(/;.*\z/, '') log << "# => #{code} #{res_name} | #{content_type} #{size} bytes, #{sprintf('%.2f', duration)}s\n" end
The raw headers.
# File lib/restclient/abstract_response.rb, line 45 def raw_headers @raw_headers ||= @net_http_res.to_hash end
@param [Net::HTTPResponse] net_http_res
@param [RestClient::Request] request @param [Time] start_time
# File lib/restclient/abstract_response.rb, line 52 def response_set_vars(net_http_res, request, start_time) @net_http_res = net_http_res @request = request @start_time = start_time @end_time = Time.now if @start_time @duration = @end_time - @start_time else @duration = nil end # prime redirection history history end
Return the default behavior corresponding to the response code:
For 20x status codes: return the response itself
For 30x status codes:
301, 302, 307: redirect GET / HEAD if there is a Location header 303: redirect, changing method to GET, if there is a Location header
For all other responses, raise a response exception
# File lib/restclient/abstract_response.rb, line 113 def return!(&block) case code when 200..207 self when 301, 302, 307 case request.method when 'get', 'head' check_max_redirects follow_redirection(&block) else raise exception_with_response end when 303 check_max_redirects follow_get_redirection(&block) else raise exception_with_response end end
# File lib/restclient/abstract_response.rb, line 133 def to_i warn('warning: calling Response#to_i is not recommended') super end
Private Instance Methods
Follow a redirection
@param new_args [Hash] Start with this hash of arguments for the
redirection request. The hash will be mutated, so be sure to dup any existing hash that should not be modified.
# File lib/restclient/abstract_response.rb, line 202 def _follow_redirection(new_args, &block) # parse location header and merge into existing URL url = headers[:location] # cannot follow redirection if there is no location header unless url raise exception_with_response end # handle relative redirects unless url.start_with?('http') url = URI.parse(request.url).merge(url).to_s end new_args[:url] = url new_args[:password] = request.password new_args[:user] = request.user new_args[:headers] = request.headers new_args[:max_redirects] = request.max_redirects - 1 # pass through our new cookie jar new_args[:cookies] = cookie_jar # prepare new request new_req = Request.new(new_args) # append self to redirection history new_req.redirection_history = history + [self] # execute redirected request new_req.execute(&block) end
# File lib/restclient/abstract_response.rb, line 236 def check_max_redirects if request.max_redirects <= 0 raise exception_with_response end end
# File lib/restclient/abstract_response.rb, line 242 def exception_with_response begin klass = Exceptions::EXCEPTIONS_MAP.fetch(code) rescue KeyError raise RequestFailed.new(self, code) end raise klass.new(self, code) end