class HTTParty::Request

def format_from_mimetype(mimetype) #:nodoc:

:nodoc:
It compares the MIME type returned to the types stored in the AllowedFormats hash
Uses the HTTP Content-Type header to determine the format of the response
def format_from_mimetype(mimetype) #:nodoc:
  AllowedFormats.each { |k, v| return k if mimetype.include?(v) }
end

def get_response(uri) #:nodoc:

:nodoc:
def get_response(uri) #:nodoc:
  request = http_method.new(uri.request_uri)   
  request.set_form_data(options[:query]) if post? && options[:query]
  request.body = options[:body].is_a?(Hash) ? options[:body].to_query : options[:body] unless options[:body].blank?
  request.initialize_http_header options[:headers]
  request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password]) if options[:basic_auth]
  response = http(uri).request(request)
  options[:format] ||= format_from_mimetype(response['content-type'])
  response
end

def handle_response!(response) #:nodoc:

:nodoc:
Raises exception Net::XXX (http error code) if an http error occured
def handle_response!(response) #:nodoc:
  case response
  when Net::HTTPSuccess
    parse_response(response.body)
  when Net::HTTPRedirection
    options[:limit] -= 1
    self.path = response['location']
    perform
  else
    response.instance_eval { class << self; attr_accessor :body_parsed; end }
    begin; response.body_parsed = parse_response(response.body); rescue; end
    response.error! # raises  exception corresponding to http error Net::XXX
  end
end

def http(uri) #:nodoc:

:nodoc:
def http(uri) #:nodoc:
  http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport])
  http.use_ssl = (uri.port == 443)
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  http
end

def initialize(http_method, path, options={})

def initialize(http_method, path, options={})
  self.http_method = http_method
  self.path = path
  self.options = {
    :limit => options.delete(:no_follow) ? 0 : 5, 
    :default_params => {},
  }.merge(options.dup)
end

def parse_response(body) #:nodoc:

:nodoc:
def parse_response(body) #:nodoc:
  return nil if body.nil? or body.empty?
  case options[:format]
  when :xml
    Hash.from_xml(body)
  when :json
    ActiveSupport::JSON.decode(body)
  else
    body
  end
end

def path=(uri)

def path=(uri)
  @path = URI.parse(uri)
end

def perform

def perform
  validate!
  handle_response!(get_response(uri))
end

def post?

def post?
  Net::HTTP::Post == http_method
end

def query_string(uri) #:nodoc:

:nodoc:
def query_string(uri) #:nodoc:
  query_string_parts = []
  query_string_parts << uri.query unless uri.query.blank?
  if options[:query].is_a?(Hash)
    query_string_parts << options[:default_params].merge(options[:query]).to_query
  else
    query_string_parts << options[:default_params].to_query unless options[:default_params].blank?
    query_string_parts << options[:query] unless options[:query].blank?
  end
  
  query_string_parts.size > 0 ? query_string_parts.join('&') : nil
end

def uri

def uri
  uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
  uri.query = query_string(uri)
  uri
end

def validate! #:nodoc:

:nodoc:
def validate! #:nodoc:
  raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0
  raise ArgumentError, 'only get, post, put and delete methods are supported' unless SupportedHTTPMethods.include?(http_method)
  raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
  raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
  raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].is_a?(Hash)
end