mirror of
https://github.com/lostisland/faraday.git
synced 2025-08-29 00:03:58 -04:00
add multipart support
This commit is contained in:
parent
e5a9bdcddb
commit
12b519aedc
@ -49,13 +49,16 @@ module Faraday
|
||||
extend AutoloadHelper
|
||||
|
||||
autoload_all 'faraday',
|
||||
:Adapter => 'adapter',
|
||||
:Connection => 'connection',
|
||||
:Middleware => 'middleware',
|
||||
:Builder => 'builder',
|
||||
:Request => 'request',
|
||||
:Response => 'response',
|
||||
:Error => 'error'
|
||||
:Adapter => 'adapter',
|
||||
:Connection => 'connection',
|
||||
:Middleware => 'middleware',
|
||||
:Builder => 'builder',
|
||||
:Request => 'request',
|
||||
:Response => 'response',
|
||||
:CompositeReadIO => 'upload_io',
|
||||
:UploadIO => 'upload_io',
|
||||
:Parts => 'upload_io',
|
||||
:Error => 'error'
|
||||
end
|
||||
|
||||
# not pulling in active-support JUST for this method.
|
||||
|
@ -1,7 +1,9 @@
|
||||
module Faraday
|
||||
class Adapter < Middleware
|
||||
FORM_TYPE = 'application/x-www-form-urlencoded'.freeze
|
||||
MULTIPART_TYPE = 'multipart/form-data'.freeze
|
||||
FORM_TYPE = 'application/x-www-form-urlencoded'.freeze
|
||||
MULTIPART_TYPE = 'multipart/form-data'.freeze
|
||||
CONTENT_TYPE = 'Content-Type'.freeze
|
||||
DEFAULT_BOUNDARY = "-----------RubyMultipartPost".freeze
|
||||
|
||||
extend AutoloadHelper
|
||||
autoload_all 'faraday/adapter',
|
||||
@ -36,9 +38,24 @@ module Faraday
|
||||
# environment for you.
|
||||
def process_body_for_request(env, body = env[:body], headers = env[:request_headers])
|
||||
return if body.nil? || body.empty? || !body.respond_to?(:each_key)
|
||||
type = headers['Content-Type'].to_s
|
||||
headers['Content-Type'] ||= FORM_TYPE
|
||||
env[:body] = create_form_params(body)
|
||||
if body.values.any? { |v| v.respond_to?(:content_type) }
|
||||
env[:request] ||= {}
|
||||
env[:request][:boundary] ||= DEFAULT_BOUNDARY
|
||||
headers[CONTENT_TYPE] = MULTIPART_TYPE + ";boundary=#{env[:request][:boundary]}"
|
||||
env[:body] = create_multipart(env, body)
|
||||
else
|
||||
type = headers[CONTENT_TYPE]
|
||||
headers[CONTENT_TYPE] = FORM_TYPE if type.nil? || type.empty?
|
||||
env[:body] = create_form_params(body)
|
||||
end
|
||||
end
|
||||
|
||||
def create_multipart(env, params, boundary = nil)
|
||||
boundary ||= env[:request][:boundary]
|
||||
parts = params.map {|k,v| Faraday::Parts::Part.new(boundary, k, v)}
|
||||
parts << Faraday::Parts::EpiloguePart.new(boundary)
|
||||
env[:request_headers]['Content-Length'] = parts.inject(0) {|sum,i| sum + i.length }
|
||||
Faraday::CompositeReadIO.new(*parts.map{|p| p.to_io })
|
||||
end
|
||||
|
||||
def create_form_params(params, base = nil)
|
||||
|
@ -20,6 +20,7 @@ module Faraday
|
||||
def call(env)
|
||||
super
|
||||
full_path = full_path_for(env[:url].path, env[:url].query, env[:url].fragment)
|
||||
body = env[:body].respond_to?(:read) ? env[:body]
|
||||
@session.__send__(env[:method], full_path, env[:body], env[:request_headers])
|
||||
resp = @session.response
|
||||
env.update \
|
||||
@ -28,6 +29,12 @@ module Faraday
|
||||
:body => resp.body
|
||||
@app.call env
|
||||
end
|
||||
|
||||
# TODO: build in support for multipart streaming if action dispatch supports it.
|
||||
def create_multipart(env, params, boundary = nil)
|
||||
stream = super
|
||||
stream.read
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -54,6 +54,12 @@ module Faraday
|
||||
Net::HTTP
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: build in support for multipart streaming
|
||||
def create_multipart(env, params, boundary = nil)
|
||||
stream = super
|
||||
stream.read
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -28,6 +28,12 @@ module Faraday
|
||||
rescue Errno::ECONNREFUSED
|
||||
raise Error::ConnectionFailed, "connection refused"
|
||||
end
|
||||
|
||||
# TODO: build in support for multipart streaming if patron supports it.
|
||||
def create_multipart(env, params, boundary = nil)
|
||||
stream = super
|
||||
stream.read
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -112,6 +112,11 @@ module Faraday
|
||||
end
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def create_multipart(env, params, boundary = nil)
|
||||
stream = super
|
||||
stream.read
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -60,6 +60,12 @@ module Faraday
|
||||
map! { |h| h.split(/:\s+/,2) }. # split key and value
|
||||
map! { |(k, v)| [k.downcase, v] }.flatten!]
|
||||
end
|
||||
|
||||
# TODO: build in support for multipart streaming if typhoeus supports it.
|
||||
def create_multipart(env, params, boundary = nil)
|
||||
stream = super
|
||||
stream.read
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
14
lib/faraday/upload_io.rb
Normal file
14
lib/faraday/upload_io.rb
Normal file
@ -0,0 +1,14 @@
|
||||
begin
|
||||
require 'composite_io'
|
||||
require 'parts'
|
||||
require 'stringio'
|
||||
rescue LoadError
|
||||
puts "Install the multipart-post gem."
|
||||
raise
|
||||
end
|
||||
|
||||
module Faraday
|
||||
CompositeReadIO = ::CompositeReadIO
|
||||
UploadIO = ::UploadIO
|
||||
Parts = ::Parts
|
||||
end
|
35
test/multipart_test.rb
Normal file
35
test/multipart_test.rb
Normal file
@ -0,0 +1,35 @@
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
||||
|
||||
class MultipartTest < Faraday::TestCase
|
||||
def setup
|
||||
@app = Faraday::Adapter.new nil
|
||||
@env = {:request_headers => {}}
|
||||
end
|
||||
|
||||
def test_processes_nested_body
|
||||
@env[:body] = {:a => 1, :b => Faraday::UploadIO.new(__FILE__, 'text/x-ruby')}
|
||||
@app.process_body_for_request @env
|
||||
assert_kind_of CompositeReadIO, @env[:body]
|
||||
assert_equal "%s;boundary=%s" %
|
||||
[Faraday::Adapter::MULTIPART_TYPE, Faraday::Adapter::DEFAULT_BOUNDARY],
|
||||
@env[:request_headers]['Content-Type']
|
||||
end
|
||||
|
||||
def test_processes_nil_body
|
||||
@env[:body] = nil
|
||||
@app.process_body_for_request @env
|
||||
assert_nil @env[:body]
|
||||
end
|
||||
|
||||
def test_processes_empty_body
|
||||
@env[:body] = ''
|
||||
@app.process_body_for_request @env
|
||||
assert_equal '', @env[:body]
|
||||
end
|
||||
|
||||
def test_processes_string_body
|
||||
@env[:body] = 'abc'
|
||||
@app.process_body_for_request @env
|
||||
assert_equal 'abc', @env[:body]
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user