avdi-faraday 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +27 -0
- data/LICENSE.md +20 -0
- data/README.md +250 -0
- data/Rakefile +87 -0
- data/config.ru +6 -0
- data/faraday.gemspec +86 -0
- data/lib/faraday.rb +276 -0
- data/lib/faraday/adapter.rb +71 -0
- data/lib/faraday/adapter/em_http.rb +217 -0
- data/lib/faraday/adapter/em_synchrony.rb +89 -0
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +66 -0
- data/lib/faraday/adapter/excon.rb +59 -0
- data/lib/faraday/adapter/httpclient.rb +92 -0
- data/lib/faraday/adapter/net_http.rb +116 -0
- data/lib/faraday/adapter/net_http_persistent.rb +37 -0
- data/lib/faraday/adapter/patron.rb +65 -0
- data/lib/faraday/adapter/rack.rb +57 -0
- data/lib/faraday/adapter/test.rb +162 -0
- data/lib/faraday/adapter/typhoeus.rb +107 -0
- data/lib/faraday/builder.rb +184 -0
- data/lib/faraday/connection.rb +468 -0
- data/lib/faraday/error.rb +40 -0
- data/lib/faraday/middleware.rb +41 -0
- data/lib/faraday/request.rb +101 -0
- data/lib/faraday/request/authorization.rb +40 -0
- data/lib/faraday/request/basic_authentication.rb +13 -0
- data/lib/faraday/request/multipart.rb +62 -0
- data/lib/faraday/request/retry.rb +67 -0
- data/lib/faraday/request/token_authentication.rb +15 -0
- data/lib/faraday/request/url_encoded.rb +35 -0
- data/lib/faraday/response.rb +99 -0
- data/lib/faraday/response/logger.rb +34 -0
- data/lib/faraday/response/raise_error.rb +16 -0
- data/lib/faraday/upload_io.rb +23 -0
- data/lib/faraday/utils.rb +274 -0
- data/script/test +91 -0
- data/test/adapters/default_test.rb +14 -0
- data/test/adapters/em_http_test.rb +19 -0
- data/test/adapters/em_synchrony_test.rb +20 -0
- data/test/adapters/excon_test.rb +15 -0
- data/test/adapters/httpclient_test.rb +16 -0
- data/test/adapters/integration.rb +193 -0
- data/test/adapters/logger_test.rb +37 -0
- data/test/adapters/net_http_persistent_test.rb +11 -0
- data/test/adapters/net_http_test.rb +49 -0
- data/test/adapters/patron_test.rb +17 -0
- data/test/adapters/rack_test.rb +26 -0
- data/test/adapters/test_middleware_test.rb +70 -0
- data/test/adapters/typhoeus_test.rb +20 -0
- data/test/authentication_middleware_test.rb +65 -0
- data/test/connection_test.rb +375 -0
- data/test/env_test.rb +183 -0
- data/test/helper.rb +75 -0
- data/test/live_server.rb +57 -0
- data/test/middleware/retry_test.rb +62 -0
- data/test/middleware_stack_test.rb +203 -0
- data/test/middleware_test.rb +12 -0
- data/test/request_middleware_test.rb +108 -0
- data/test/response_middleware_test.rb +74 -0
- metadata +182 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
module Faraday
|
2
|
+
class Adapter
|
3
|
+
class Patron < Faraday::Adapter
|
4
|
+
dependency 'patron'
|
5
|
+
|
6
|
+
def initialize(app, &block)
|
7
|
+
super(app)
|
8
|
+
@block = block if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
super
|
13
|
+
|
14
|
+
# TODO: support streaming requests
|
15
|
+
env[:body] = env[:body].read if env[:body].respond_to? :read
|
16
|
+
|
17
|
+
session = @session ||= create_session
|
18
|
+
|
19
|
+
if req = env[:request]
|
20
|
+
session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
|
21
|
+
session.connect_timeout = req[:open_timeout] if req[:open_timeout]
|
22
|
+
|
23
|
+
if proxy = req[:proxy]
|
24
|
+
session.proxy = proxy[:uri].to_s
|
25
|
+
if proxy[:user] && proxy[:password]
|
26
|
+
prepend_proxy_auth_string(proxy, session)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
response = begin
|
32
|
+
data = env[:body] ? env[:body].to_s : nil
|
33
|
+
session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
|
34
|
+
rescue Errno::ECONNREFUSED
|
35
|
+
raise Error::ConnectionFailed, $!
|
36
|
+
end
|
37
|
+
|
38
|
+
save_response(env, response.status, response.body, response.headers)
|
39
|
+
|
40
|
+
@app.call env
|
41
|
+
rescue ::Patron::TimeoutError => err
|
42
|
+
raise Faraday::Error::TimeoutError, err
|
43
|
+
end
|
44
|
+
|
45
|
+
if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
|
46
|
+
# HAX: helps but doesn't work completely
|
47
|
+
# https://github.com/toland/patron/issues/34
|
48
|
+
::Patron::Request::VALID_ACTIONS.tap do |actions|
|
49
|
+
actions << :patch unless actions.include? :patch
|
50
|
+
actions << :options unless actions.include? :options
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_session
|
55
|
+
session = ::Patron::Session.new
|
56
|
+
@block.call(session) if @block
|
57
|
+
session
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def prepend_proxy_auth_string(proxy, session)
|
62
|
+
session.proxy.insert(7, "#{proxy[:user]}:#{proxy[:password]}@")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Faraday
|
2
|
+
class Adapter
|
3
|
+
# Sends requests to a Rack app.
|
4
|
+
#
|
5
|
+
# Examples
|
6
|
+
#
|
7
|
+
# class MyRackApp
|
8
|
+
# def call(env)
|
9
|
+
# [200, {'Content-Type' => 'text/html'}, ["hello world"]]
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Faraday.new do |conn|
|
14
|
+
# conn.adapter :rack, MyRackApp
|
15
|
+
# end
|
16
|
+
class Rack < Faraday::Adapter
|
17
|
+
dependency 'rack/test'
|
18
|
+
|
19
|
+
# not prefixed with "HTTP_"
|
20
|
+
SPECIAL_HEADERS = %w[ CONTENT_LENGTH CONTENT_TYPE ]
|
21
|
+
|
22
|
+
def initialize(faraday_app, rack_app)
|
23
|
+
super(faraday_app)
|
24
|
+
mock_session = ::Rack::MockSession.new(rack_app)
|
25
|
+
@session = ::Rack::Test::Session.new(mock_session)
|
26
|
+
end
|
27
|
+
|
28
|
+
def call(env)
|
29
|
+
super
|
30
|
+
rack_env = {
|
31
|
+
:method => env[:method],
|
32
|
+
:input => env[:body].respond_to?(:read) ? env[:body].read : env[:body]
|
33
|
+
}
|
34
|
+
|
35
|
+
env[:request_headers].each do |name, value|
|
36
|
+
name = name.upcase.tr('-', '_')
|
37
|
+
name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
|
38
|
+
rack_env[name] = value
|
39
|
+
end if env[:request_headers]
|
40
|
+
|
41
|
+
timeout = env[:request][:timeout] || env[:request][:open_timeout]
|
42
|
+
response = if timeout
|
43
|
+
Timer.timeout(timeout, Faraday::Error::TimeoutError) { execute_request(env, rack_env) }
|
44
|
+
else
|
45
|
+
execute_request(env, rack_env)
|
46
|
+
end
|
47
|
+
|
48
|
+
save_response(env, response.status, response.body, response.headers)
|
49
|
+
@app.call env
|
50
|
+
end
|
51
|
+
|
52
|
+
def execute_request(env, rack_env)
|
53
|
+
@session.request(env[:url].to_s, rack_env)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
module Faraday
|
2
|
+
class Adapter
|
3
|
+
# test = Faraday::Connection.new do
|
4
|
+
# use Faraday::Adapter::Test do |stub|
|
5
|
+
# stub.get '/nigiri/sake.json' do
|
6
|
+
# [200, {}, 'hi world']
|
7
|
+
# end
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# resp = test.get '/nigiri/sake.json'
|
12
|
+
# resp.body # => 'hi world'
|
13
|
+
#
|
14
|
+
class Test < Faraday::Adapter
|
15
|
+
attr_accessor :stubs
|
16
|
+
|
17
|
+
class Stubs
|
18
|
+
class NotFound < StandardError
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
# {:get => [Stub, Stub]}
|
23
|
+
@stack, @consumed = {}, {}
|
24
|
+
yield self if block_given?
|
25
|
+
end
|
26
|
+
|
27
|
+
def empty?
|
28
|
+
@stack.empty?
|
29
|
+
end
|
30
|
+
|
31
|
+
def match(request_method, path, body)
|
32
|
+
return false if !@stack.key?(request_method)
|
33
|
+
stack = @stack[request_method]
|
34
|
+
consumed = (@consumed[request_method] ||= [])
|
35
|
+
path = normalize_path(path)
|
36
|
+
|
37
|
+
if stub = matches?(stack, path, body)
|
38
|
+
consumed << stack.delete(stub)
|
39
|
+
stub
|
40
|
+
else
|
41
|
+
matches?(consumed, path, body)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def get(path, &block)
|
46
|
+
new_stub(:get, path, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def head(path, &block)
|
50
|
+
new_stub(:head, path, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def post(path, body=nil, &block)
|
54
|
+
new_stub(:post, path, body, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def put(path, body=nil, &block)
|
58
|
+
new_stub(:put, path, body, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
def patch(path, body=nil, &block)
|
62
|
+
new_stub(:patch, path, body, &block)
|
63
|
+
end
|
64
|
+
|
65
|
+
def delete(path, &block)
|
66
|
+
new_stub(:delete, path, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
def options(path, &block)
|
70
|
+
new_stub(:options, path, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Raises an error if any of the stubbed calls have not been made.
|
74
|
+
def verify_stubbed_calls
|
75
|
+
failed_stubs = []
|
76
|
+
@stack.each do |method, stubs|
|
77
|
+
unless stubs.size == 0
|
78
|
+
failed_stubs.concat(stubs.map {|stub|
|
79
|
+
"Expected #{method} #{stub}."
|
80
|
+
})
|
81
|
+
end
|
82
|
+
end
|
83
|
+
raise failed_stubs.join(" ") unless failed_stubs.size == 0
|
84
|
+
end
|
85
|
+
|
86
|
+
protected
|
87
|
+
|
88
|
+
def new_stub(request_method, path, body=nil, &block)
|
89
|
+
(@stack[request_method] ||= []) << Stub.new(normalize_path(path), body, block)
|
90
|
+
end
|
91
|
+
|
92
|
+
def matches?(stack, path, body)
|
93
|
+
stack.detect { |stub| stub.matches?(path, body) }
|
94
|
+
end
|
95
|
+
|
96
|
+
# ensure leading + trailing slash
|
97
|
+
def normalize_path(path)
|
98
|
+
path = '/' + path if path.index('/') != 0
|
99
|
+
path = path.sub('?', '/?')
|
100
|
+
path = path + '/' unless $&
|
101
|
+
path.gsub('//', '/')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class Stub < Struct.new(:path, :params, :body, :block)
|
106
|
+
def initialize(full, body, block)
|
107
|
+
path, query = full.split('?')
|
108
|
+
params = query ?
|
109
|
+
Faraday::Utils.parse_nested_query(query) :
|
110
|
+
{}
|
111
|
+
super path, params, body, block
|
112
|
+
end
|
113
|
+
|
114
|
+
def matches?(request_uri, request_body)
|
115
|
+
request_path, request_query = request_uri.split('?')
|
116
|
+
request_params = request_query ?
|
117
|
+
Faraday::Utils.parse_nested_query(request_query) :
|
118
|
+
{}
|
119
|
+
request_path == path &&
|
120
|
+
params_match?(request_params) &&
|
121
|
+
(body.to_s.size.zero? || request_body == body)
|
122
|
+
end
|
123
|
+
|
124
|
+
def params_match?(request_params)
|
125
|
+
params.keys.all? do |key|
|
126
|
+
request_params[key] == params[key]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def to_s
|
131
|
+
"#{path} #{body}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def initialize(app, stubs=nil, &block)
|
136
|
+
super(app)
|
137
|
+
@stubs = stubs || Stubs.new
|
138
|
+
configure(&block) if block
|
139
|
+
end
|
140
|
+
|
141
|
+
def configure
|
142
|
+
yield stubs
|
143
|
+
end
|
144
|
+
|
145
|
+
def call(env)
|
146
|
+
super
|
147
|
+
normalized_path = Faraday::Utils.normalize_path(env[:url])
|
148
|
+
|
149
|
+
if stub = stubs.match(env[:method], normalized_path, env[:body])
|
150
|
+
env[:params] = (query = env[:url].query) ?
|
151
|
+
Faraday::Utils.parse_nested_query(query) :
|
152
|
+
{}
|
153
|
+
status, headers, body = stub.block.call(env)
|
154
|
+
save_response(env, status, body, headers)
|
155
|
+
else
|
156
|
+
raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
|
157
|
+
end
|
158
|
+
@app.call(env)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Faraday
|
2
|
+
class Adapter
|
3
|
+
class Typhoeus < Faraday::Adapter
|
4
|
+
self.supports_parallel = true
|
5
|
+
|
6
|
+
def self.setup_parallel_manager(options = {})
|
7
|
+
options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
dependency 'typhoeus'
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
super
|
14
|
+
perform_request env
|
15
|
+
@app.call env
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform_request(env)
|
19
|
+
read_body env
|
20
|
+
|
21
|
+
hydra = env[:parallel_manager] || self.class.setup_parallel_manager
|
22
|
+
hydra.queue request(env)
|
23
|
+
hydra.run unless parallel?(env)
|
24
|
+
rescue Errno::ECONNREFUSED
|
25
|
+
raise Error::ConnectionFailed, $!
|
26
|
+
end
|
27
|
+
|
28
|
+
# TODO: support streaming requests
|
29
|
+
def read_body(env)
|
30
|
+
env[:body] = env[:body].read if env[:body].respond_to? :read
|
31
|
+
end
|
32
|
+
|
33
|
+
def request(env)
|
34
|
+
req = ::Typhoeus::Request.new env[:url].to_s,
|
35
|
+
:method => env[:method],
|
36
|
+
:body => env[:body],
|
37
|
+
:headers => env[:request_headers],
|
38
|
+
:disable_ssl_peer_verification => (env[:ssl] && !env[:ssl].fetch(:verify, true))
|
39
|
+
|
40
|
+
configure_ssl req, env
|
41
|
+
configure_proxy req, env
|
42
|
+
configure_timeout req, env
|
43
|
+
configure_socket req, env
|
44
|
+
|
45
|
+
req.on_complete do |resp|
|
46
|
+
if resp.timed_out?
|
47
|
+
if parallel?(env)
|
48
|
+
# TODO: error callback in async mode
|
49
|
+
else
|
50
|
+
raise Faraday::Error::TimeoutError, "request timed out"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
save_response(env, resp.code, resp.body) do |response_headers|
|
55
|
+
response_headers.parse resp.headers
|
56
|
+
end
|
57
|
+
# in async mode, :response is initialized at this point
|
58
|
+
env[:response].finish(env) if parallel?(env)
|
59
|
+
end
|
60
|
+
|
61
|
+
req
|
62
|
+
end
|
63
|
+
|
64
|
+
def configure_ssl(req, env)
|
65
|
+
ssl = env[:ssl]
|
66
|
+
|
67
|
+
req.ssl_version = ssl[:version] if ssl[:version]
|
68
|
+
req.ssl_cert = ssl[:client_cert_file] if ssl[:client_cert_file]
|
69
|
+
req.ssl_key = ssl[:client_key_file] if ssl[:client_key_file]
|
70
|
+
req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
|
71
|
+
req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
|
72
|
+
end
|
73
|
+
|
74
|
+
def configure_proxy(req, env)
|
75
|
+
proxy = request_options(env)[:proxy]
|
76
|
+
return unless proxy
|
77
|
+
|
78
|
+
req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
|
79
|
+
|
80
|
+
if proxy[:username] && proxy[:password]
|
81
|
+
req.proxy_username = proxy[:username]
|
82
|
+
req.proxy_password = proxy[:password]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def configure_timeout(req, env)
|
87
|
+
env_req = request_options(env)
|
88
|
+
req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
|
89
|
+
req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
|
90
|
+
end
|
91
|
+
|
92
|
+
def configure_socket(req, env)
|
93
|
+
if bind = request_options(env)[:bind]
|
94
|
+
req.interface = bind[:host]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def request_options(env)
|
99
|
+
env[:request]
|
100
|
+
end
|
101
|
+
|
102
|
+
def parallel?(env)
|
103
|
+
!!env[:parallel_manager]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
module Faraday
|
2
|
+
# Possibly going to extend this a bit.
|
3
|
+
#
|
4
|
+
# Faraday::Connection.new(:url => 'http://sushi.com') do |builder|
|
5
|
+
# builder.request :url_encoded # Faraday::Request::UrlEncoded
|
6
|
+
# builder.adapter :net_http # Faraday::Adapter::NetHttp
|
7
|
+
# end
|
8
|
+
class Builder
|
9
|
+
attr_accessor :handlers
|
10
|
+
|
11
|
+
# Error raised when trying to modify the stack after calling `lock!`
|
12
|
+
class StackLocked < RuntimeError; end
|
13
|
+
|
14
|
+
# borrowed from ActiveSupport::Dependencies::Reference &
|
15
|
+
# ActionDispatch::MiddlewareStack::Middleware
|
16
|
+
class Handler
|
17
|
+
@@constants = Hash.new { |h, k|
|
18
|
+
h[k] = k.respond_to?(:constantize) ? k.constantize : Object.const_get(k)
|
19
|
+
}
|
20
|
+
|
21
|
+
attr_reader :name, :args
|
22
|
+
|
23
|
+
def initialize(klass, *args, &block)
|
24
|
+
@name = klass.to_s
|
25
|
+
@@constants[@name] = klass if klass.respond_to?(:name)
|
26
|
+
@args, @block = args, block
|
27
|
+
end
|
28
|
+
|
29
|
+
def klass() @@constants[@name] end
|
30
|
+
def inspect() @name end
|
31
|
+
|
32
|
+
def ==(other)
|
33
|
+
if other.is_a? Handler
|
34
|
+
self.name == other.name
|
35
|
+
elsif other.respond_to? :name
|
36
|
+
klass == other
|
37
|
+
else
|
38
|
+
@name == other.to_s
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def build(app)
|
43
|
+
klass.new(app, *@args, &@block)
|
44
|
+
end
|
45
|
+
|
46
|
+
def adapter?
|
47
|
+
klass.respond_to?(:adapter?) && klass.adapter?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize(handlers = [])
|
52
|
+
@handlers = handlers
|
53
|
+
if block_given?
|
54
|
+
build(&Proc.new)
|
55
|
+
elsif @handlers.empty?
|
56
|
+
# default stack, if nothing else is configured
|
57
|
+
self.request :url_encoded
|
58
|
+
self.adapter Faraday.default_adapter
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def build(options = {})
|
63
|
+
raise_if_locked
|
64
|
+
clear unless options[:keep]
|
65
|
+
yield self if block_given?
|
66
|
+
end
|
67
|
+
|
68
|
+
def clear
|
69
|
+
@handlers.clear
|
70
|
+
end
|
71
|
+
|
72
|
+
def [](idx)
|
73
|
+
@handlers[idx]
|
74
|
+
end
|
75
|
+
|
76
|
+
def ==(other)
|
77
|
+
other.is_a?(self.class) && @handlers == other.handlers
|
78
|
+
end
|
79
|
+
|
80
|
+
def dup
|
81
|
+
self.class.new(@handlers.dup)
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_app(inner_app)
|
85
|
+
# last added handler is the deepest and thus closest to the inner app
|
86
|
+
@handlers.reverse.inject(inner_app) { |app, handler| handler.build(app) }
|
87
|
+
end
|
88
|
+
|
89
|
+
# Locks the middleware stack to ensure no further modifications are possible.
|
90
|
+
def lock!
|
91
|
+
@handlers.freeze
|
92
|
+
end
|
93
|
+
|
94
|
+
def locked?
|
95
|
+
@handlers.frozen?
|
96
|
+
end
|
97
|
+
|
98
|
+
def use(klass, *args, &block)
|
99
|
+
if klass.is_a? Symbol
|
100
|
+
use_symbol(Faraday::Middleware, klass, *args, &block)
|
101
|
+
else
|
102
|
+
raise_if_locked
|
103
|
+
@handlers << self.class::Handler.new(klass, *args, &block)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def request(key, *args, &block)
|
108
|
+
use_symbol(Faraday::Request, key, *args, &block)
|
109
|
+
end
|
110
|
+
|
111
|
+
def response(key, *args, &block)
|
112
|
+
use_symbol(Faraday::Response, key, *args, &block)
|
113
|
+
end
|
114
|
+
|
115
|
+
def adapter(key=nil, *args, &block)
|
116
|
+
if [key, *args, block].none?
|
117
|
+
find_adapter
|
118
|
+
else
|
119
|
+
use_symbol(Faraday::Adapter, key, *args, &block)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def has_adapter?
|
124
|
+
!!find_adapter
|
125
|
+
end
|
126
|
+
|
127
|
+
## methods to push onto the various positions in the stack:
|
128
|
+
|
129
|
+
def insert(index, *args, &block)
|
130
|
+
raise_if_locked
|
131
|
+
index = assert_index(index)
|
132
|
+
handler = self.class::Handler.new(*args, &block)
|
133
|
+
@handlers.insert(index, handler)
|
134
|
+
end
|
135
|
+
|
136
|
+
alias_method :insert_before, :insert
|
137
|
+
|
138
|
+
def insert_after(index, *args, &block)
|
139
|
+
index = assert_index(index)
|
140
|
+
insert(index + 1, *args, &block)
|
141
|
+
end
|
142
|
+
|
143
|
+
def swap(index, *args, &block)
|
144
|
+
raise_if_locked
|
145
|
+
index = assert_index(index)
|
146
|
+
@handlers.delete_at(index)
|
147
|
+
insert(index, *args, &block)
|
148
|
+
end
|
149
|
+
|
150
|
+
def delete(handler)
|
151
|
+
raise_if_locked
|
152
|
+
@handlers.delete(handler)
|
153
|
+
end
|
154
|
+
|
155
|
+
def adapter=(adapter_args)
|
156
|
+
clear_adapters
|
157
|
+
adapter(*adapter_args)
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def raise_if_locked
|
163
|
+
raise StackLocked, "can't modify middleware stack after making a request" if locked?
|
164
|
+
end
|
165
|
+
|
166
|
+
def use_symbol(mod, key, *args, &block)
|
167
|
+
use(mod.lookup_middleware(key), *args, &block)
|
168
|
+
end
|
169
|
+
|
170
|
+
def assert_index(index)
|
171
|
+
idx = index.is_a?(Integer) ? index : @handlers.index(index)
|
172
|
+
raise "No such handler: #{index.inspect}" unless idx
|
173
|
+
idx
|
174
|
+
end
|
175
|
+
|
176
|
+
def find_adapter
|
177
|
+
@handlers.detect{|h| h.adapter?}
|
178
|
+
end
|
179
|
+
|
180
|
+
def clear_adapters
|
181
|
+
@handlers.delete_if{|h| h.adapter?}
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|