1
0
Fork 0
mirror of https://github.com/jnunemaker/httparty synced 2023-03-27 23:23:07 -04:00

Refactor for easier mulipart implementation

This commit is contained in:
Nikita Misharin 2018-01-15 17:24:13 +03:00
parent d59cdf29f9
commit 727a58294a
3 changed files with 95 additions and 17 deletions

View file

@ -24,32 +24,43 @@ module HTTParty
#
# @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones&"
def self.normalize_param(key, value)
param = ''
normalized_keys = normalize_keys(key, value)
normalized_keys.inject('') do |string, (k, v)|
string + "#{k}=#{ERB::Util.url_encode(v.to_s)}&"
end
end
def self.normalize_keys(key, value)
stack = []
normalized_keys = []
if value.respond_to?(:to_ary)
param << if value.empty?
"#{key}[]=&"
else
value.to_ary.map { |element| normalize_param("#{key}[]", element) }.join
end
if value.empty?
normalized_keys << ["#{key}[]", '']
else
normalized_keys = value.to_ary.flat_map { |element| normalize_keys("#{key}[]", element) }
end
elsif value.respond_to?(:to_hash)
stack << [key, value.to_hash]
else
param << "#{key}=#{ERB::Util.url_encode(value.to_s)}&"
normalized_keys << [key.to_s, value]
end
stack.each do |parent, hash|
hash.each do |k, v|
if v.respond_to?(:to_hash)
stack << ["#{parent}[#{k}]", v.to_hash]
hash.each do |key, value|
if value.respond_to?(:to_hash)
stack << ["#{parent}[#{key}]", value.to_hash]
elsif value.respond_to?(:to_ary)
value.to_ary.each { |v| normalized_keys << normalize_keys("#{parent}[#{key}][]", v).flatten }
else
param << normalize_param("#{parent}[#{k}]", v)
normalized_keys << normalize_keys("#{parent}[#{key}]", value).flatten
end
end
end
param
normalized_keys
end
end
end

View file

@ -1,4 +1,5 @@
require 'erb'
require 'httparty/request/body'
module HTTParty
class Request #:nodoc:
@ -176,10 +177,6 @@ module HTTParty
connection_adapter.call(uri, options)
end
def body
options[:body].respond_to?(:to_hash) ? normalize_query(options[:body]) : options[:body]
end
def credentials
(options[:basic_auth] || options[:digest_auth]).to_hash
end
@ -206,8 +203,14 @@ module HTTParty
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[:body]
@raw_request.body = Body.new(
options[:body],
query_string_normalizer: query_string_normalizer
).call
end
if options[:headers].respond_to?(:to_hash)
headers_hash = options[:headers].to_hash

View file

@ -0,0 +1,64 @@
require 'pry'
module HTTParty
class Request
class Body
def initialize(params, query_string_normalizer: nil)
@params = params
@query_string_normalizer = query_string_normalizer
@options = {}
end
def call
if params.respond_to?(:to_hash)
multipart? ? generate_multipart : normalize_query(params)
else
params
end
end
private
def generate_multipart
end
def multipart?
options[:multipart] || has_file?(params)
end
def has_file?(hash)
hash.detect do |key, value|
if value.respond_to?(:to_hash) || includes_hash?(value)
has_file?(value)
elsif value.respond_to?(:to_ary)
value.any? { |e| file?(e) }
else
file?(value)
end
end
end
def file?(object)
object.respond_to?(:path) && object.respond_to?(:read)
end
def includes_hash?(object)
object.respond_to?(:to_ary) && object.any? { |e| e.respond_to?(:hash) }
end
def normalize_query(query)
if query_string_normalizer
query_string_normalizer.call(query)
else
HashConversions.to_params(query)
end
end
def boundary
@boundary ||= "--------------------------#{SecureRandom.urlsafe_base64(12)}"
end
attr_reader :params, :query_string_normalizer, :options
end
end
end