class HTTParty::Request

:nodoc:

def _encode_body(body)

def _encode_body(body)
  charset = get_charset
  if charset.nil?
    return body
  end
  if "utf-16".casecmp(charset) == 0
    encode_utf_16(body)
  else
    encode_with_ruby_encoding(body, charset)
  end
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 += ":#{@last_uri.port}" if @last_uri.port != 80
    base_uri
  else
    options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri])
  end
end

def body

def body
  options[:body].respond_to?(:to_hash) ? normalize_query(options[:body]) : options[:body]
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 digest_auth?

def digest_auth?
  !!options[:digest_auth]
end

def encode_body(body)

def encode_body(body)
  if "".respond_to?(:encoding)
    _encode_body(body)
  else
    body
  end
end

def encode_utf_16(body)

def encode_utf_16(body)
  if body.bytesize >= 2
    if body.getbyte(0) == 0xFF && body.getbyte(1) == 0xFE
      return body.force_encoding("UTF-16LE")
    elsif body.getbyte(0) == 0xFE && body.getbyte(1) == 0xFF
      return body.force_encoding("UTF-16BE")
    end
  end
  if assume_utf16_is_big_endian
    body.force_encoding("UTF-16BE")
  else
    body.force_encoding("UTF-16LE")
  end
end

def encode_with_ruby_encoding(body, charset)

def encode_with_ruby_encoding(body, charset)
  if !body.nil? && Encoding.name_list.include?(charset)
    body.force_encoding(charset)
  else
    body
  end
end

def format

def format
  options[:format] || (format_from_mimetype(last_response['content-type']) if last_response)
end

def format_from_mimetype(mimetype)

SupportedFormats hash
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 get_charset

def get_charset
  content_type = last_response["content-type"]
  if content_type.nil?
    return nil
  end
  if content_type =~ /;\s*charset\s*=\s*([^=,;"\s]+)/i
    return $1
  end
  if content_type =~ /;\s*charset\s*=\s*"((\\.|[^\\"])+)"/i
    return $1.gsub(/\\(.)/, '\1')
  end
  nil
end

def handle_host_redirection

def handle_host_redirection
  check_duplicate_location_header
  redirect_path = options[:uri_adapter].parse last_response['location']
  return if redirect_path.relative? || path.host == redirect_path.host
  @changed_hosts = true
end

def handle_response(body, &block)

def handle_response(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
    body ||= last_response.body
    body = body.nil? ? body : encode_body(body)
    Response.new(self, last_response, lambda { parse_response(body) }, body: 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
  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
  self.last_response = http.request(@raw_request) do |http_response|
    if block
      chunks = []
      http_response.read_body do |fragment|
        chunks << fragment unless options[:stream_body]
        block.call(fragment)
      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
  @raw_request = http_method.new(request_uri(uri))
  @raw_request.body = body if body
  @raw_request.body_stream = options[:body_stream] if options[:body_stream]
  if options[:headers].respond_to?(:to_hash)
    headers_hash = options[:headers].to_hash
    @raw_request.initialize_http_header(headers_hash)
    # If the caller specified a header of 'Accept-Encoding', assume they want to
    # deal with encoding of content. Disable the internal logic in Net:HTTP
    # that handles encoding, if the platform supports it.
    if @raw_request.respond_to?(:decode_content) && (headers_hash.key?('Accept-Encoding') || headers_hash.key?('accept-encoding'))
      # Using the '[]=' sets decode_content to false
      @raw_request['accept-encoding'] = @raw_request['accept-encoding']
    end
  end
  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}")
  elsif path.relative?
    new_uri = options[:uri_adapter].parse("#{base_uri}#{path}")
  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