faraday 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +22 -15
- data/{LICENSE → LICENSE.md} +1 -1
- data/README.md +216 -146
- data/Rakefile +14 -58
- data/config.ru +6 -0
- data/faraday.gemspec +31 -38
- data/lib/faraday/adapter/em_http.rb +204 -0
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +66 -0
- data/lib/faraday/adapter/em_synchrony.rb +67 -16
- data/lib/faraday/adapter/excon.rb +1 -2
- data/lib/faraday/adapter/net_http.rb +82 -39
- data/lib/faraday/adapter/net_http_persistent.rb +37 -0
- data/lib/faraday/adapter/patron.rb +42 -8
- data/lib/faraday/adapter/rack.rb +59 -0
- data/lib/faraday/adapter/test.rb +49 -9
- data/lib/faraday/adapter/typhoeus.rb +70 -15
- data/lib/faraday/adapter.rb +41 -18
- data/lib/faraday/builder.rb +34 -16
- data/lib/faraday/connection.rb +177 -115
- data/lib/faraday/error.rb +4 -2
- data/lib/faraday/middleware.rb +18 -10
- data/lib/faraday/request/authorization.rb +40 -0
- data/lib/faraday/request/basic_authentication.rb +13 -0
- data/lib/faraday/request/multipart.rb +5 -6
- data/lib/faraday/request/retry.rb +21 -0
- data/lib/faraday/request/token_authentication.rb +15 -0
- data/lib/faraday/request/url_encoded.rb +1 -3
- data/lib/faraday/request.rb +48 -38
- data/lib/faraday/response/raise_error.rb +1 -1
- data/lib/faraday/response.rb +6 -5
- data/lib/faraday/upload_io.rb +1 -1
- data/lib/faraday/utils.rb +196 -29
- data/lib/faraday.rb +69 -13
- data/test/adapters/default_test.rb +14 -0
- data/test/adapters/em_http_test.rb +14 -0
- data/test/adapters/em_synchrony_test.rb +14 -0
- data/test/adapters/excon_test.rb +23 -0
- data/test/adapters/integration.rb +190 -0
- data/test/adapters/logger_test.rb +2 -2
- data/test/adapters/net_http_persistent_test.rb +11 -0
- data/test/adapters/net_http_test.rb +37 -21
- data/test/adapters/patron_test.rb +17 -0
- data/test/adapters/rack_test.rb +26 -0
- data/test/adapters/test_middleware_test.rb +28 -1
- data/test/adapters/typhoeus_test.rb +14 -0
- data/test/authentication_middleware_test.rb +65 -0
- data/test/connection_test.rb +211 -81
- data/test/env_test.rb +80 -31
- data/test/helper.rb +23 -13
- data/test/live_server.rb +38 -29
- data/test/middleware/retry_test.rb +25 -0
- data/test/middleware_stack_test.rb +85 -4
- data/test/request_middleware_test.rb +42 -19
- data/test/response_middleware_test.rb +30 -3
- metadata +104 -110
- data/lib/faraday/adapter/action_dispatch.rb +0 -30
- data/lib/faraday/request/json.rb +0 -31
- data/test/adapters/live_test.rb +0 -186
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'faraday/adapter/net_http'
|
|
2
|
+
|
|
3
|
+
module Faraday
|
|
4
|
+
class Adapter
|
|
5
|
+
# Experimental adapter for net-http-persistent
|
|
6
|
+
class NetHttpPersistent < NetHttp
|
|
7
|
+
dependency 'net/http/persistent'
|
|
8
|
+
|
|
9
|
+
# TODO: investigate is it safe to create a new Persistent instance for
|
|
10
|
+
# every request, or does it defy the purpose of persistent connections
|
|
11
|
+
def net_http_connection(env)
|
|
12
|
+
Net::HTTP::Persistent.new 'Faraday',
|
|
13
|
+
env[:request][:proxy] ? env[:request][:proxy][:uri] : nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def perform_request(http, env)
|
|
17
|
+
http.request env[:url], create_request(env)
|
|
18
|
+
rescue Net::HTTP::Persistent::Error => error
|
|
19
|
+
if error.message.include? 'Timeout::Error'
|
|
20
|
+
raise Faraday::Error::TimeoutError, error
|
|
21
|
+
else
|
|
22
|
+
raise
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def configure_ssl(http, ssl)
|
|
27
|
+
http.verify_mode = ssl_verify_mode(ssl)
|
|
28
|
+
http.cert_store = ssl_cert_store(ssl)
|
|
29
|
+
|
|
30
|
+
http.certificate = ssl[:client_cert] if ssl[:client_cert]
|
|
31
|
+
http.private_key = ssl[:client_key] if ssl[:client_key]
|
|
32
|
+
http.ca_file = ssl[:ca_file] if ssl[:ca_file]
|
|
33
|
+
http.ssl_version = ssl[:version] if ssl[:version]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -3,29 +3,63 @@ module Faraday
|
|
|
3
3
|
class Patron < Faraday::Adapter
|
|
4
4
|
dependency 'patron'
|
|
5
5
|
|
|
6
|
+
def initialize(app, &block)
|
|
7
|
+
super(app)
|
|
8
|
+
@block = block if block_given?
|
|
9
|
+
end
|
|
10
|
+
|
|
6
11
|
def call(env)
|
|
7
12
|
super
|
|
8
13
|
|
|
9
14
|
# TODO: support streaming requests
|
|
10
15
|
env[:body] = env[:body].read if env[:body].respond_to? :read
|
|
11
16
|
|
|
12
|
-
session =
|
|
17
|
+
session = @session ||= create_session
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
19
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)
|
|
20
34
|
rescue Errno::ECONNREFUSED
|
|
21
35
|
raise Error::ConnectionFailed, $!
|
|
22
36
|
end
|
|
23
37
|
|
|
24
|
-
env
|
|
25
|
-
response_headers(env).update response.headers
|
|
38
|
+
save_response(env, response.status, response.body, response.headers)
|
|
26
39
|
|
|
27
40
|
@app.call env
|
|
41
|
+
rescue ::Patron::TimeoutError => err
|
|
42
|
+
raise Faraday::Error::TimeoutError, err
|
|
28
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]}@")
|
|
29
63
|
end
|
|
30
64
|
end
|
|
31
65
|
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'timeout'
|
|
2
|
+
|
|
3
|
+
module Faraday
|
|
4
|
+
class Adapter
|
|
5
|
+
# Sends requests to a Rack app.
|
|
6
|
+
#
|
|
7
|
+
# Examples
|
|
8
|
+
#
|
|
9
|
+
# class MyRackApp
|
|
10
|
+
# def call(env)
|
|
11
|
+
# [200, {'Content-Type' => 'text/html'}, ["hello world"]]
|
|
12
|
+
# end
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# Faraday.new do |conn|
|
|
16
|
+
# conn.adapter :rack, MyRackApp
|
|
17
|
+
# end
|
|
18
|
+
class Rack < Faraday::Adapter
|
|
19
|
+
dependency 'rack/test'
|
|
20
|
+
|
|
21
|
+
# not prefixed with "HTTP_"
|
|
22
|
+
SPECIAL_HEADERS = %w[ CONTENT_LENGTH CONTENT_TYPE ]
|
|
23
|
+
|
|
24
|
+
def initialize(faraday_app, rack_app)
|
|
25
|
+
super(faraday_app)
|
|
26
|
+
mock_session = ::Rack::MockSession.new(rack_app)
|
|
27
|
+
@session = ::Rack::Test::Session.new(mock_session)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def call(env)
|
|
31
|
+
super
|
|
32
|
+
rack_env = {
|
|
33
|
+
:method => env[:method],
|
|
34
|
+
:input => env[:body].respond_to?(:read) ? env[:body].read : env[:body]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
env[:request_headers].each do |name, value|
|
|
38
|
+
name = name.upcase.tr('-', '_')
|
|
39
|
+
name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
|
|
40
|
+
rack_env[name] = value
|
|
41
|
+
end if env[:request_headers]
|
|
42
|
+
|
|
43
|
+
timeout = env[:request][:timeout] || env[:request][:open_timeout]
|
|
44
|
+
response = if timeout
|
|
45
|
+
Timer.timeout(timeout, Faraday::Error::TimeoutError) { execute_request(env, rack_env) }
|
|
46
|
+
else
|
|
47
|
+
execute_request(env, rack_env)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
save_response(env, response.status, response.body, response.headers)
|
|
51
|
+
@app.call env
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def execute_request(env, rack_env)
|
|
55
|
+
@session.request(env[:url].to_s, rack_env)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/faraday/adapter/test.rb
CHANGED
|
@@ -14,9 +14,10 @@ module Faraday
|
|
|
14
14
|
class Test < Faraday::Adapter
|
|
15
15
|
attr_accessor :stubs
|
|
16
16
|
|
|
17
|
-
def self.loaded?() false end
|
|
18
|
-
|
|
19
17
|
class Stubs
|
|
18
|
+
class NotFound < StandardError
|
|
19
|
+
end
|
|
20
|
+
|
|
20
21
|
def initialize
|
|
21
22
|
# {:get => [Stub, Stub]}
|
|
22
23
|
@stack, @consumed = {}, {}
|
|
@@ -31,6 +32,7 @@ module Faraday
|
|
|
31
32
|
return false if !@stack.key?(request_method)
|
|
32
33
|
stack = @stack[request_method]
|
|
33
34
|
consumed = (@consumed[request_method] ||= [])
|
|
35
|
+
path = normalize_path(path)
|
|
34
36
|
|
|
35
37
|
if stub = matches?(stack, path, body)
|
|
36
38
|
consumed << stack.delete(stub)
|
|
@@ -56,10 +58,18 @@ module Faraday
|
|
|
56
58
|
new_stub(:put, path, body, &block)
|
|
57
59
|
end
|
|
58
60
|
|
|
61
|
+
def patch(path, body=nil, &block)
|
|
62
|
+
new_stub(:patch, path, body, &block)
|
|
63
|
+
end
|
|
64
|
+
|
|
59
65
|
def delete(path, &block)
|
|
60
66
|
new_stub(:delete, path, &block)
|
|
61
67
|
end
|
|
62
68
|
|
|
69
|
+
def options(path, &block)
|
|
70
|
+
new_stub(:options, path, &block)
|
|
71
|
+
end
|
|
72
|
+
|
|
63
73
|
# Raises an error if any of the stubbed calls have not been made.
|
|
64
74
|
def verify_stubbed_calls
|
|
65
75
|
failed_stubs = []
|
|
@@ -76,17 +86,45 @@ module Faraday
|
|
|
76
86
|
protected
|
|
77
87
|
|
|
78
88
|
def new_stub(request_method, path, body=nil, &block)
|
|
79
|
-
(@stack[request_method] ||= []) << Stub.new(path, body, block)
|
|
89
|
+
(@stack[request_method] ||= []) << Stub.new(normalize_path(path), body, block)
|
|
80
90
|
end
|
|
81
91
|
|
|
82
92
|
def matches?(stack, path, body)
|
|
83
93
|
stack.detect { |stub| stub.matches?(path, body) }
|
|
84
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
|
|
85
103
|
end
|
|
86
104
|
|
|
87
|
-
class Stub < Struct.new(:path, :body, :block)
|
|
88
|
-
def
|
|
89
|
-
|
|
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
|
|
90
128
|
end
|
|
91
129
|
|
|
92
130
|
def to_s
|
|
@@ -109,11 +147,13 @@ module Faraday
|
|
|
109
147
|
normalized_path = Faraday::Utils.normalize_path(env[:url])
|
|
110
148
|
|
|
111
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
|
+
{}
|
|
112
153
|
status, headers, body = stub.block.call(env)
|
|
113
|
-
env
|
|
114
|
-
response_headers(env).update headers
|
|
154
|
+
save_response(env, status, body, headers)
|
|
115
155
|
else
|
|
116
|
-
raise "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
|
|
156
|
+
raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
|
|
117
157
|
end
|
|
118
158
|
@app.call(env)
|
|
119
159
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Faraday
|
|
2
2
|
class Adapter
|
|
3
3
|
class Typhoeus < Faraday::Adapter
|
|
4
|
-
self.
|
|
4
|
+
self.supports_parallel = true
|
|
5
5
|
|
|
6
6
|
def self.setup_parallel_manager(options = {})
|
|
7
7
|
options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
|
|
@@ -11,34 +11,89 @@ module Faraday
|
|
|
11
11
|
|
|
12
12
|
def call(env)
|
|
13
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
|
|
14
27
|
|
|
15
|
-
|
|
28
|
+
# TODO: support streaming requests
|
|
29
|
+
def read_body(env)
|
|
16
30
|
env[:body] = env[:body].read if env[:body].respond_to? :read
|
|
31
|
+
end
|
|
17
32
|
|
|
33
|
+
def request(env)
|
|
18
34
|
req = ::Typhoeus::Request.new env[:url].to_s,
|
|
19
35
|
:method => env[:method],
|
|
20
36
|
:body => env[:body],
|
|
21
37
|
:headers => env[:request_headers],
|
|
22
38
|
:disable_ssl_peer_verification => (env[:ssl] && !env[:ssl].fetch(:verify, true))
|
|
23
39
|
|
|
24
|
-
|
|
25
|
-
req
|
|
26
|
-
req
|
|
40
|
+
configure_ssl req, env
|
|
41
|
+
configure_proxy req, env
|
|
42
|
+
configure_timeout req, env
|
|
27
43
|
|
|
28
|
-
is_parallel = !!env[:parallel_manager]
|
|
29
44
|
req.on_complete do |resp|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
if resp.timed_out?
|
|
46
|
+
if parallel?(env)
|
|
47
|
+
# TODO: error callback in async mode
|
|
48
|
+
else
|
|
49
|
+
raise Faraday::Error::TimeoutError, "request timed out"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
save_response(env, resp.code, resp.body) do |response_headers|
|
|
54
|
+
response_headers.parse resp.headers
|
|
55
|
+
end
|
|
56
|
+
# in async mode, :response is initialized at this point
|
|
57
|
+
env[:response].finish(env) if parallel?(env)
|
|
33
58
|
end
|
|
34
59
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
hydra.run unless is_parallel
|
|
60
|
+
req
|
|
61
|
+
end
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
63
|
+
def configure_ssl(req, env)
|
|
64
|
+
ssl = env[:ssl]
|
|
65
|
+
|
|
66
|
+
req.ssl_version = ssl[:version] if ssl[:version]
|
|
67
|
+
req.ssl_cert = ssl[:client_cert_file] if ssl[:client_cert_file]
|
|
68
|
+
req.ssl_key = ssl[:client_key_file] if ssl[:client_key_file]
|
|
69
|
+
req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
|
|
70
|
+
req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def configure_proxy(req, env)
|
|
74
|
+
proxy = request_options(env)[:proxy]
|
|
75
|
+
return unless proxy
|
|
76
|
+
|
|
77
|
+
req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
|
|
78
|
+
|
|
79
|
+
if proxy[:username] && proxy[:password]
|
|
80
|
+
req.proxy_username = proxy[:username]
|
|
81
|
+
req.proxy_password = proxy[:password]
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def configure_timeout(req, env)
|
|
86
|
+
env_req = request_options(env)
|
|
87
|
+
req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
|
|
88
|
+
req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def request_options(env)
|
|
92
|
+
env[:request]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def parallel?(env)
|
|
96
|
+
!!env[:parallel_manager]
|
|
42
97
|
end
|
|
43
98
|
end
|
|
44
99
|
end
|
data/lib/faraday/adapter.rb
CHANGED
|
@@ -3,24 +3,42 @@ module Faraday
|
|
|
3
3
|
CONTENT_LENGTH = 'Content-Length'.freeze
|
|
4
4
|
|
|
5
5
|
extend AutoloadHelper
|
|
6
|
+
extend MiddlewareRegistry
|
|
6
7
|
|
|
7
8
|
autoload_all 'faraday/adapter',
|
|
8
|
-
:
|
|
9
|
-
:
|
|
10
|
-
:Typhoeus
|
|
11
|
-
:EMSynchrony
|
|
12
|
-
:
|
|
13
|
-
:
|
|
14
|
-
:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
:
|
|
20
|
-
:
|
|
21
|
-
:
|
|
22
|
-
:
|
|
23
|
-
:
|
|
9
|
+
:NetHttp => 'net_http',
|
|
10
|
+
:NetHttpPersistent => 'net_http_persistent',
|
|
11
|
+
:Typhoeus => 'typhoeus',
|
|
12
|
+
:EMSynchrony => 'em_synchrony',
|
|
13
|
+
:EMHttp => 'em_http',
|
|
14
|
+
:Patron => 'patron',
|
|
15
|
+
:Excon => 'excon',
|
|
16
|
+
:Test => 'test',
|
|
17
|
+
:Rack => 'rack'
|
|
18
|
+
|
|
19
|
+
register_middleware \
|
|
20
|
+
:test => :Test,
|
|
21
|
+
:net_http => :NetHttp,
|
|
22
|
+
:net_http_persistent => :NetHttpPersistent,
|
|
23
|
+
:typhoeus => :Typhoeus,
|
|
24
|
+
:patron => :Patron,
|
|
25
|
+
:em_synchrony => :EMSynchrony,
|
|
26
|
+
:em_http => :EMHttp,
|
|
27
|
+
:excon => :Excon,
|
|
28
|
+
:rack => :Rack
|
|
29
|
+
|
|
30
|
+
module Parallelism
|
|
31
|
+
attr_writer :supports_parallel
|
|
32
|
+
def supports_parallel?() @supports_parallel end
|
|
33
|
+
|
|
34
|
+
def inherited(subclass)
|
|
35
|
+
super
|
|
36
|
+
subclass.supports_parallel = self.supports_parallel?
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
extend Parallelism
|
|
41
|
+
self.supports_parallel = false
|
|
24
42
|
|
|
25
43
|
def call(env)
|
|
26
44
|
if !env[:body] and Connection::METHODS_WITH_BODIES.include? env[:method]
|
|
@@ -31,8 +49,13 @@ module Faraday
|
|
|
31
49
|
end
|
|
32
50
|
end
|
|
33
51
|
|
|
34
|
-
def
|
|
35
|
-
env[:
|
|
52
|
+
def save_response(env, status, body, headers = nil)
|
|
53
|
+
env[:status] = status
|
|
54
|
+
env[:body] = body
|
|
55
|
+
env[:response_headers] = Utils::Headers.new.tap do |response_headers|
|
|
56
|
+
response_headers.update headers unless headers.nil?
|
|
57
|
+
yield response_headers if block_given?
|
|
58
|
+
end
|
|
36
59
|
end
|
|
37
60
|
end
|
|
38
61
|
end
|
data/lib/faraday/builder.rb
CHANGED
|
@@ -8,9 +8,8 @@ module Faraday
|
|
|
8
8
|
class Builder
|
|
9
9
|
attr_accessor :handlers
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
end
|
|
11
|
+
# Error raised when trying to modify the stack after calling `lock!`
|
|
12
|
+
class StackLocked < RuntimeError; end
|
|
14
13
|
|
|
15
14
|
# borrowed from ActiveSupport::Dependencies::Reference &
|
|
16
15
|
# ActionDispatch::MiddlewareStack::Middleware
|
|
@@ -31,7 +30,9 @@ module Faraday
|
|
|
31
30
|
def inspect() @name end
|
|
32
31
|
|
|
33
32
|
def ==(other)
|
|
34
|
-
if other.
|
|
33
|
+
if other.is_a? Handler
|
|
34
|
+
self.name == other.name
|
|
35
|
+
elsif other.respond_to? :name
|
|
35
36
|
klass == other
|
|
36
37
|
else
|
|
37
38
|
@name == other.to_s
|
|
@@ -55,6 +56,7 @@ module Faraday
|
|
|
55
56
|
end
|
|
56
57
|
|
|
57
58
|
def build(options = {})
|
|
59
|
+
raise_if_locked
|
|
58
60
|
@handlers.clear unless options[:keep]
|
|
59
61
|
yield self if block_given?
|
|
60
62
|
end
|
|
@@ -76,29 +78,40 @@ module Faraday
|
|
|
76
78
|
@handlers.reverse.inject(inner_app) { |app, handler| handler.build(app) }
|
|
77
79
|
end
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
@handlers
|
|
81
|
+
# Locks the middleware stack to ensure no further modifications are possible.
|
|
82
|
+
def lock!
|
|
83
|
+
@handlers.freeze
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def locked?
|
|
87
|
+
@handlers.frozen?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def use(klass, *args, &block)
|
|
91
|
+
if klass.is_a? Symbol
|
|
92
|
+
use_symbol(Faraday::Middleware, klass, *args, &block)
|
|
93
|
+
else
|
|
94
|
+
raise_if_locked
|
|
95
|
+
@handlers << self.class::Handler.new(klass, *args, &block)
|
|
96
|
+
end
|
|
82
97
|
end
|
|
83
98
|
|
|
84
|
-
def request(key, *args)
|
|
85
|
-
block = block_given? ? Proc.new : nil
|
|
99
|
+
def request(key, *args, &block)
|
|
86
100
|
use_symbol(Faraday::Request, key, *args, &block)
|
|
87
101
|
end
|
|
88
102
|
|
|
89
|
-
def response(key, *args)
|
|
90
|
-
block = block_given? ? Proc.new : nil
|
|
103
|
+
def response(key, *args, &block)
|
|
91
104
|
use_symbol(Faraday::Response, key, *args, &block)
|
|
92
105
|
end
|
|
93
106
|
|
|
94
|
-
def adapter(key, *args)
|
|
95
|
-
block = block_given? ? Proc.new : nil
|
|
107
|
+
def adapter(key, *args, &block)
|
|
96
108
|
use_symbol(Faraday::Adapter, key, *args, &block)
|
|
97
109
|
end
|
|
98
110
|
|
|
99
111
|
## methods to push onto the various positions in the stack:
|
|
100
112
|
|
|
101
113
|
def insert(index, *args, &block)
|
|
114
|
+
raise_if_locked
|
|
102
115
|
index = assert_index(index)
|
|
103
116
|
handler = self.class::Handler.new(*args, &block)
|
|
104
117
|
@handlers.insert(index, handler)
|
|
@@ -112,20 +125,25 @@ module Faraday
|
|
|
112
125
|
end
|
|
113
126
|
|
|
114
127
|
def swap(index, *args, &block)
|
|
128
|
+
raise_if_locked
|
|
115
129
|
index = assert_index(index)
|
|
116
130
|
@handlers.delete_at(index)
|
|
117
131
|
insert(index, *args, &block)
|
|
118
132
|
end
|
|
119
133
|
|
|
120
134
|
def delete(handler)
|
|
135
|
+
raise_if_locked
|
|
121
136
|
@handlers.delete(handler)
|
|
122
137
|
end
|
|
123
138
|
|
|
124
139
|
private
|
|
125
140
|
|
|
126
|
-
def
|
|
127
|
-
|
|
128
|
-
|
|
141
|
+
def raise_if_locked
|
|
142
|
+
raise StackLocked, "can't modify middleware stack after making a request" if locked?
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def use_symbol(mod, key, *args, &block)
|
|
146
|
+
use(mod.lookup_middleware(key), *args, &block)
|
|
129
147
|
end
|
|
130
148
|
|
|
131
149
|
def assert_index(index)
|