class HTTParty::Request
Experimental RBS support (using type sampling data from the type_fusion
project).
# sig/httparty/request.rbs class HTTParty::Request def digest_auth?: () -> false end
:nodoc:
def self._load(data)
def self._load(data) http_method, path, options, last_response, last_uri, raw_request = Marshal.load(data) instance = new(http_method, path, options) instance.last_response = last_response instance.last_uri = last_uri instance.instance_variable_set("@raw_request", raw_request) instance end
def _dump(_level)
def _dump(_level) opts = options.dup opts.delete(:logger) opts.delete(:parser) if opts[:parser] && opts[:parser].is_a?(Proc) Marshal.dump([http_method, path, opts, last_response, @last_uri, @raw_request]) end
def assume_utf16_is_big_endian
def assume_utf16_is_big_endian options[:assume_utf16_is_big_endian] end
def base_uri
def base_uri if redirect base_uri = "#{@last_uri.scheme}://#{@last_uri.host}" base_uri = "#{base_uri}:#{@last_uri.port}" if @last_uri.port != 80 base_uri else options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri]) end end
def capture_cookies(response)
def capture_cookies(response) return unless response['Set-Cookie'] cookies_hash = HTTParty::CookieHash.new cookies_hash.add_cookies(options[:headers].to_hash['Cookie']) if options[:headers] && options[:headers].to_hash['Cookie'] response.get_fields('Set-Cookie').each { |cookie| cookies_hash.add_cookies(cookie) } options[:headers] ||= {} options[:headers]['Cookie'] = cookies_hash.to_cookie_string end
def check_duplicate_location_header
def check_duplicate_location_header location = last_response.get_fields('location') if location.is_a?(Array) && location.count > 1 raise DuplicateLocationHeader.new(last_response) end end
def connection_adapter
def connection_adapter options[:connection_adapter] end
def credentials
def credentials (options[:basic_auth] || options[:digest_auth]).to_hash end
def decompress(body, encoding)
def decompress(body, encoding) Decompressor.new(body, encoding).decompress end
def decompress_content?
def decompress_content? !options[:skip_decompression] end
def digest_auth?
Experimental RBS support (using type sampling data from the type_fusion
project).
def digest_auth?: () -> false
This signature was generated using 1 sample from 1 application.
def digest_auth? !!options[:digest_auth] end
def encode_text(text, content_type)
def encode_text(text, content_type) TextEncoder.new( text, content_type: content_type, assume_utf16_is_big_endian: assume_utf16_is_big_endian ).call end
def format
def format options[:format] || (format_from_mimetype(last_response['content-type']) if last_response) end
def format_from_mimetype(mimetype)
response It compares the MIME type returned to the types stored in the
Uses the HTTP Content-Type header to determine the format of the
def format_from_mimetype(mimetype) if mimetype && parser.respond_to?(:format_from_mimetype) parser.format_from_mimetype(mimetype) end end
def handle_host_redirection
def handle_host_redirection check_duplicate_location_header redirect_path = options[:uri_adapter].parse(last_response['location']).normalize return if redirect_path.relative? || path.host == redirect_path.host @changed_hosts = true end
def handle_response(raw_body, &block)
def handle_response(raw_body, &block) if response_redirects? options[:limit] -= 1 if options[:logger] logger = HTTParty::Logger.build(options[:logger], options[:log_level], options[:log_format]) logger.format(self, last_response) end self.path = last_response['location'] self.redirect = true if last_response.class == Net::HTTPSeeOther unless options[:maintain_method_across_redirects] && options[:resend_on_redirect] self.http_method = Net::HTTP::Get end elsif last_response.code != '307' && last_response.code != '308' unless options[:maintain_method_across_redirects] self.http_method = Net::HTTP::Get end end capture_cookies(last_response) perform(&block) else raw_body ||= last_response.body body = decompress(raw_body, last_response['content-encoding']) unless raw_body.nil? unless body.nil? body = encode_text(body, last_response['content-type']) if decompress_content? last_response.delete('content-encoding') raw_body = body end end Response.new(self, last_response, lambda { parse_response(body) }, body: raw_body) end end
def handle_unauthorized(&block)
def handle_unauthorized(&block) return unless digest_auth? && response_unauthorized? && response_has_digest_auth_challenge? return if @credentials_sent @credentials_sent = true perform(&block) end
def http
def http connection_adapter.call(uri, options) end
def initialize(http_method, path, o = {})
def initialize(http_method, path, o = {}) @changed_hosts = false @credentials_sent = false self.http_method = http_method self.options = { limit: o.delete(:no_follow) ? 1 : 5, assume_utf16_is_big_endian: true, default_params: {}, follow_redirects: true, parser: Parser, uri_adapter: URI, connection_adapter: ConnectionAdapter }.merge(o) self.path = path set_basic_auth_from_uri end
def normalize_query(query)
def normalize_query(query) if query_string_normalizer query_string_normalizer.call(query) else HashConversions.to_params(query) end end
def parse_response(body)
def parse_response(body) parser.call(body, format) end
def parser
def parser options[:parser] end
def password
def password credentials[:password] end
def path=(uri)
def path=(uri) uri_adapter = options[:uri_adapter] @path = if uri.is_a?(uri_adapter) uri elsif String.try_convert(uri) uri_adapter.parse(uri).normalize else raise ArgumentError, "bad argument (expected #{uri_adapter} object or URI string)" end end
def perform(&block)
def perform(&block) validate setup_raw_request chunked_body = nil current_http = http self.last_response = current_http.request(@raw_request) do |http_response| if block chunks = [] http_response.read_body do |fragment| encoded_fragment = encode_text(fragment, http_response['content-type']) chunks << encoded_fragment if !options[:stream_body] block.call ResponseFragment.new(encoded_fragment, http_response, current_http) end chunked_body = chunks.join end end handle_host_redirection if response_redirects? result = handle_unauthorized result ||= handle_response(chunked_body, &block) result end
def post?
def post? Net::HTTP::Post == http_method end
def query_string(uri)
def query_string(uri) query_string_parts = [] query_string_parts << uri.query unless uri.query.nil? if options[:query].respond_to?(:to_hash) query_string_parts << normalize_query(options[:default_params].merge(options[:query].to_hash)) else query_string_parts << normalize_query(options[:default_params]) unless options[:default_params].empty? query_string_parts << options[:query] unless options[:query].nil? end query_string_parts.reject!(&:empty?) unless query_string_parts == [''] query_string_parts.size > 0 ? query_string_parts.join('&') : nil end
def query_string_normalizer
def query_string_normalizer options[:query_string_normalizer] end
def raw_body
def raw_body @raw_request.body end
def request_uri(uri)
def request_uri(uri) if uri.respond_to? :request_uri uri.request_uri else uri.path end end
def response_has_digest_auth_challenge?
def response_has_digest_auth_challenge? !last_response['www-authenticate'].nil? && last_response['www-authenticate'].length > 0 end
def response_redirects?
def response_redirects? case last_response when Net::HTTPNotModified # 304 false when Net::HTTPRedirection options[:follow_redirects] && last_response.key?('location') end end
def response_unauthorized?
def response_unauthorized? !!last_response && last_response.code == '401' end
def send_authorization_header?
def send_authorization_header? !@changed_hosts end
def set_basic_auth_from_uri
def set_basic_auth_from_uri if path.userinfo username, password = path.userinfo.split(':') options[:basic_auth] = {username: username, password: password} @credentials_sent = true end end
def setup_digest_auth
def setup_digest_auth @raw_request.digest_auth(username, password, last_response) end
def setup_raw_request
def setup_raw_request if options[:headers].respond_to?(:to_hash) headers_hash = options[:headers].to_hash else headers_hash = nil end @raw_request = http_method.new(request_uri(uri), headers_hash) @raw_request.body_stream = options[:body_stream] if options[:body_stream] if options[:body] body = Body.new( options[:body], query_string_normalizer: query_string_normalizer, force_multipart: options[:multipart] ) if body.multipart? content_type = "multipart/form-data; boundary=#{body.boundary}" @raw_request['Content-Type'] = content_type end @raw_request.body = body.call end @raw_request.instance_variable_set(:@decode_content, decompress_content?) if options[:basic_auth] && send_authorization_header? @raw_request.basic_auth(username, password) @credentials_sent = true end setup_digest_auth if digest_auth? && response_unauthorized? && response_has_digest_auth_challenge? end
def uri
def uri if redirect && path.relative? && path.path[0] != '/' last_uri_host = @last_uri.path.gsub(/[^\/]+$/, '') path.path = "/#{path.path}" if last_uri_host[-1] != '/' path.path = "#{last_uri_host}#{path.path}" end if path.relative? && path.host new_uri = options[:uri_adapter].parse("#{@last_uri.scheme}:#{path}").normalize elsif path.relative? new_uri = options[:uri_adapter].parse("#{base_uri}#{path}").normalize else new_uri = path.clone end # avoid double query string on redirects [#12] unless redirect new_uri.query = query_string(new_uri) end unless SupportedURISchemes.include? new_uri.scheme raise UnsupportedURIScheme, "'#{new_uri}' Must be HTTP, HTTPS or Generic" end @last_uri = new_uri end
def username
def username credentials[:username] end
def validate
def validate raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0 raise ArgumentError, 'only get, post, patch, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method) raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].respond_to?(:to_hash) raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth] raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].respond_to?(:to_hash) raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].respond_to?(:to_hash) raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].respond_to?(:to_hash) end