faraday 0.8.11 → 0.9.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.
- checksums.yaml +4 -4
- data/.document +6 -0
- data/CHANGELOG.md +15 -0
- data/CONTRIBUTING.md +36 -0
- data/Gemfile +10 -3
- data/LICENSE.md +1 -1
- data/README.md +17 -51
- data/Rakefile +2 -18
- data/faraday.gemspec +34 -0
- data/lib/faraday/adapter/em_http.rb +34 -0
- data/lib/faraday/adapter/em_http_ssl_patch.rb +56 -0
- data/lib/faraday/adapter/em_synchrony.rb +11 -24
- data/lib/faraday/adapter/excon.rb +12 -2
- data/lib/faraday/adapter/httpclient.rb +106 -0
- data/lib/faraday/adapter/net_http.rb +10 -6
- data/lib/faraday/adapter/patron.rb +2 -8
- data/lib/faraday/adapter/rack.rb +0 -2
- data/lib/faraday/adapter/test.rb +39 -39
- data/lib/faraday/adapter/typhoeus.rb +12 -3
- data/lib/faraday/adapter.rb +20 -35
- data/lib/faraday/autoload.rb +85 -0
- data/lib/faraday/connection.rb +232 -125
- data/lib/faraday/error.rb +42 -34
- data/lib/faraday/options.rb +350 -0
- data/lib/faraday/parameters.rb +193 -0
- data/lib/faraday/{builder.rb → rack_builder.rb} +79 -22
- data/lib/faraday/request/authorization.rb +7 -5
- data/lib/faraday/request/basic_authentication.rb +1 -1
- data/lib/faraday/request/instrumentation.rb +36 -0
- data/lib/faraday/request/multipart.rb +10 -9
- data/lib/faraday/request/retry.rb +99 -4
- data/lib/faraday/request/token_authentication.rb +2 -2
- data/lib/faraday/request/url_encoded.rb +7 -6
- data/lib/faraday/request.rb +21 -30
- data/lib/faraday/response/logger.rb +4 -4
- data/lib/faraday/response/raise_error.rb +4 -2
- data/lib/faraday/response.rb +17 -23
- data/lib/faraday/utils.rb +81 -71
- data/lib/faraday.rb +187 -68
- data/script/console +7 -0
- data/script/proxy-server +1 -0
- data/script/release +6 -3
- data/script/test +4 -2
- data/test/adapters/em_http_test.rb +6 -1
- data/test/adapters/em_synchrony_test.rb +7 -1
- data/test/adapters/httpclient_test.rb +21 -0
- data/test/adapters/integration.rb +23 -8
- data/test/adapters/logger_test.rb +1 -1
- data/test/adapters/net_http_persistent_test.rb +10 -1
- data/test/adapters/net_http_test.rb +0 -31
- data/test/adapters/patron_test.rb +4 -1
- data/test/adapters/test_middleware_test.rb +48 -4
- data/test/adapters/typhoeus_test.rb +8 -1
- data/test/authentication_middleware_test.rb +2 -2
- data/test/connection_test.rb +160 -84
- data/test/env_test.rb +51 -24
- data/test/helper.rb +13 -13
- data/test/live_server.rb +8 -0
- data/test/middleware/instrumentation_test.rb +88 -0
- data/test/middleware/retry_test.rb +88 -35
- data/test/middleware_stack_test.rb +13 -12
- data/test/options_test.rb +252 -0
- data/test/request_middleware_test.rb +11 -1
- data/test/response_middleware_test.rb +2 -4
- data/test/strawberry.rb +2 -0
- data/test/utils_test.rb +34 -6
- metadata +71 -11
- data/test/parameters_test.rb +0 -24
data/lib/faraday/adapter/test.rb
CHANGED
@@ -21,53 +21,52 @@ module Faraday
|
|
21
21
|
def initialize
|
22
22
|
# {:get => [Stub, Stub]}
|
23
23
|
@stack, @consumed = {}, {}
|
24
|
-
yield
|
24
|
+
yield(self) if block_given?
|
25
25
|
end
|
26
26
|
|
27
27
|
def empty?
|
28
28
|
@stack.empty?
|
29
29
|
end
|
30
30
|
|
31
|
-
def match(request_method, path, body)
|
31
|
+
def match(request_method, path, headers, body)
|
32
32
|
return false if !@stack.key?(request_method)
|
33
33
|
stack = @stack[request_method]
|
34
34
|
consumed = (@consumed[request_method] ||= [])
|
35
|
-
path = normalize_path(path)
|
36
35
|
|
37
|
-
if stub = matches?(stack, path, body)
|
36
|
+
if stub = matches?(stack, path, headers, body)
|
38
37
|
consumed << stack.delete(stub)
|
39
38
|
stub
|
40
39
|
else
|
41
|
-
matches?(consumed, path, body)
|
40
|
+
matches?(consumed, path, headers, body)
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
|
-
def get(path, &block)
|
46
|
-
new_stub(:get, path, &block)
|
44
|
+
def get(path, headers = {}, &block)
|
45
|
+
new_stub(:get, path, headers, &block)
|
47
46
|
end
|
48
47
|
|
49
|
-
def head(path, &block)
|
50
|
-
new_stub(:head, path, &block)
|
48
|
+
def head(path, headers = {}, &block)
|
49
|
+
new_stub(:head, path, headers, &block)
|
51
50
|
end
|
52
51
|
|
53
|
-
def post(path, body=nil, &block)
|
54
|
-
new_stub(:post, path, body, &block)
|
52
|
+
def post(path, body=nil, headers = {}, &block)
|
53
|
+
new_stub(:post, path, headers, body, &block)
|
55
54
|
end
|
56
55
|
|
57
|
-
def put(path, body=nil, &block)
|
58
|
-
new_stub(:put, path, body, &block)
|
56
|
+
def put(path, body=nil, headers = {}, &block)
|
57
|
+
new_stub(:put, path, headers, body, &block)
|
59
58
|
end
|
60
59
|
|
61
|
-
def patch(path, body=nil, &block)
|
62
|
-
new_stub(:patch, path, body, &block)
|
60
|
+
def patch(path, body=nil, headers = {}, &block)
|
61
|
+
new_stub(:patch, path, headers, body, &block)
|
63
62
|
end
|
64
63
|
|
65
|
-
def delete(path, &block)
|
66
|
-
new_stub(:delete, path, &block)
|
64
|
+
def delete(path, headers = {}, &block)
|
65
|
+
new_stub(:delete, path, headers, &block)
|
67
66
|
end
|
68
67
|
|
69
|
-
def options(path, &block)
|
70
|
-
new_stub(:options, path, &block)
|
68
|
+
def options(path, headers = {}, &block)
|
69
|
+
new_stub(:options, path, headers, &block)
|
71
70
|
end
|
72
71
|
|
73
72
|
# Raises an error if any of the stubbed calls have not been made.
|
@@ -85,40 +84,34 @@ module Faraday
|
|
85
84
|
|
86
85
|
protected
|
87
86
|
|
88
|
-
def new_stub(request_method, path, body=nil, &block)
|
89
|
-
|
87
|
+
def new_stub(request_method, path, headers = {}, body=nil, &block)
|
88
|
+
normalized_path = Faraday::Utils.normalize_path(path)
|
89
|
+
(@stack[request_method] ||= []) << Stub.new(normalized_path, headers, body, block)
|
90
90
|
end
|
91
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('//', '/')
|
92
|
+
def matches?(stack, path, headers, body)
|
93
|
+
stack.detect { |stub| stub.matches?(path, headers, body) }
|
102
94
|
end
|
103
95
|
end
|
104
96
|
|
105
|
-
class Stub < Struct.new(:path, :params, :body, :block)
|
106
|
-
def initialize(full, body, block)
|
97
|
+
class Stub < Struct.new(:path, :params, :headers, :body, :block)
|
98
|
+
def initialize(full, headers, body, block)
|
107
99
|
path, query = full.split('?')
|
108
100
|
params = query ?
|
109
101
|
Faraday::Utils.parse_nested_query(query) :
|
110
102
|
{}
|
111
|
-
super
|
103
|
+
super(path, params, headers, body, block)
|
112
104
|
end
|
113
105
|
|
114
|
-
def matches?(request_uri, request_body)
|
106
|
+
def matches?(request_uri, request_headers, request_body)
|
115
107
|
request_path, request_query = request_uri.split('?')
|
116
108
|
request_params = request_query ?
|
117
109
|
Faraday::Utils.parse_nested_query(request_query) :
|
118
110
|
{}
|
119
111
|
request_path == path &&
|
120
112
|
params_match?(request_params) &&
|
121
|
-
(body.to_s.size.zero? || request_body == body)
|
113
|
+
(body.to_s.size.zero? || request_body == body) &&
|
114
|
+
headers_match?(request_headers)
|
122
115
|
end
|
123
116
|
|
124
117
|
def params_match?(request_params)
|
@@ -127,6 +120,12 @@ module Faraday
|
|
127
120
|
end
|
128
121
|
end
|
129
122
|
|
123
|
+
def headers_match?(request_headers)
|
124
|
+
headers.keys.all? do |key|
|
125
|
+
request_headers[key] == headers[key]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
130
129
|
def to_s
|
131
130
|
"#{path} #{body}"
|
132
131
|
end
|
@@ -139,16 +138,17 @@ module Faraday
|
|
139
138
|
end
|
140
139
|
|
141
140
|
def configure
|
142
|
-
yield
|
141
|
+
yield(stubs)
|
143
142
|
end
|
144
143
|
|
145
144
|
def call(env)
|
146
145
|
super
|
147
146
|
normalized_path = Faraday::Utils.normalize_path(env[:url])
|
147
|
+
params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
|
148
148
|
|
149
|
-
if stub = stubs.match(env[:method], normalized_path, env[:body])
|
149
|
+
if stub = stubs.match(env[:method], normalized_path, env.request_headers, env[:body])
|
150
150
|
env[:params] = (query = env[:url].query) ?
|
151
|
-
|
151
|
+
params_encoder.decode(query) :
|
152
152
|
{}
|
153
153
|
status, headers, body = stub.block.call(env)
|
154
154
|
save_response(env, status, body, headers)
|
@@ -40,11 +40,12 @@ module Faraday
|
|
40
40
|
:method => method,
|
41
41
|
:body => env[:body],
|
42
42
|
:headers => env[:request_headers],
|
43
|
-
:disable_ssl_peer_verification => (env[:ssl] &&
|
43
|
+
:disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
|
44
44
|
|
45
45
|
configure_ssl req, env
|
46
46
|
configure_proxy req, env
|
47
47
|
configure_timeout req, env
|
48
|
+
configure_socket req, env
|
48
49
|
|
49
50
|
req.on_complete do |resp|
|
50
51
|
if resp.timed_out?
|
@@ -60,6 +61,8 @@ module Faraday
|
|
60
61
|
# everything OK
|
61
62
|
when 7
|
62
63
|
raise Error::ConnectionFailed, resp.curl_error_message
|
64
|
+
when 60
|
65
|
+
raise Faraday::SSLError, resp.curl_error_message
|
63
66
|
else
|
64
67
|
raise Error::ClientError, resp.curl_error_message
|
65
68
|
end
|
@@ -78,8 +81,8 @@ module Faraday
|
|
78
81
|
ssl = env[:ssl]
|
79
82
|
|
80
83
|
req.ssl_version = ssl[:version] if ssl[:version]
|
81
|
-
req.ssl_cert = ssl[:
|
82
|
-
req.ssl_key = ssl[:
|
84
|
+
req.ssl_cert = ssl[:client_cert] if ssl[:client_cert]
|
85
|
+
req.ssl_key = ssl[:client_key] if ssl[:client_key]
|
83
86
|
req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
|
84
87
|
req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
|
85
88
|
end
|
@@ -102,6 +105,12 @@ module Faraday
|
|
102
105
|
req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
|
103
106
|
end
|
104
107
|
|
108
|
+
def configure_socket(req, env)
|
109
|
+
if bind = request_options(env)[:bind]
|
110
|
+
req.interface = bind[:host]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
105
114
|
def request_options(env)
|
106
115
|
env[:request]
|
107
116
|
end
|
data/lib/faraday/adapter.rb
CHANGED
@@ -1,32 +1,22 @@
|
|
1
1
|
module Faraday
|
2
|
+
# Public: This is a base class for all Faraday adapters. Adapters are
|
3
|
+
# responsible for fulfilling a Faraday request.
|
2
4
|
class Adapter < Middleware
|
3
5
|
CONTENT_LENGTH = 'Content-Length'.freeze
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
|
17
|
-
|
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
|
-
|
7
|
+
register_middleware File.expand_path('../adapter', __FILE__),
|
8
|
+
:test => [:Test, 'test'],
|
9
|
+
:net_http => [:NetHttp, 'net_http'],
|
10
|
+
:net_http_persistent => [:NetHttpPersistent, 'net_http_persistent'],
|
11
|
+
:typhoeus => [:Typhoeus, 'typhoeus'],
|
12
|
+
:patron => [:Patron, 'patron'],
|
13
|
+
:em_synchrony => [:EMSynchrony, 'em_synchrony'],
|
14
|
+
:em_http => [:EMHttp, 'em_http'],
|
15
|
+
:excon => [:Excon, 'excon'],
|
16
|
+
:rack => [:Rack, 'rack'],
|
17
|
+
:httpclient => [:HTTPClient, 'httpclient']
|
18
|
+
|
19
|
+
# Public: This module marks an Adapter as supporting parallel requests.
|
30
20
|
module Parallelism
|
31
21
|
attr_writer :supports_parallel
|
32
22
|
def supports_parallel?() @supports_parallel end
|
@@ -41,20 +31,15 @@ module Faraday
|
|
41
31
|
self.supports_parallel = false
|
42
32
|
|
43
33
|
def call(env)
|
44
|
-
if
|
45
|
-
# play nice and indicate we're sending an empty body
|
46
|
-
env[:request_headers][CONTENT_LENGTH] = "0"
|
47
|
-
# Typhoeus hangs on PUT requests if body is nil
|
48
|
-
env[:body] = ''
|
49
|
-
end
|
34
|
+
env.clear_body if env.needs_body?
|
50
35
|
end
|
51
36
|
|
52
37
|
def save_response(env, status, body, headers = nil)
|
53
|
-
env
|
54
|
-
env
|
55
|
-
env
|
38
|
+
env.status = status
|
39
|
+
env.body = body
|
40
|
+
env.response_headers = Utils::Headers.new.tap do |response_headers|
|
56
41
|
response_headers.update headers unless headers.nil?
|
57
|
-
yield
|
42
|
+
yield(response_headers) if block_given?
|
58
43
|
end
|
59
44
|
end
|
60
45
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Faraday
|
2
|
+
# Internal: Adds the ability for other modules to manage autoloadable
|
3
|
+
# constants.
|
4
|
+
module AutoloadHelper
|
5
|
+
# Internal: Registers the constants to be auto loaded.
|
6
|
+
#
|
7
|
+
# prefix - The String require prefix. If the path is inside Faraday, then
|
8
|
+
# it will be prefixed with the root path of this loaded Faraday
|
9
|
+
# version.
|
10
|
+
# options - Hash of Symbol => String library names.
|
11
|
+
#
|
12
|
+
# Examples.
|
13
|
+
#
|
14
|
+
# Faraday.autoload_all 'faraday/foo',
|
15
|
+
# :Bar => 'bar'
|
16
|
+
#
|
17
|
+
# # requires faraday/foo/bar to load Faraday::Bar.
|
18
|
+
# Faraday::Bar
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
22
|
+
def autoload_all(prefix, options)
|
23
|
+
if prefix =~ /^faraday(\/|$)/i
|
24
|
+
prefix = File.join(Faraday.root_path, prefix)
|
25
|
+
end
|
26
|
+
options.each do |const_name, path|
|
27
|
+
autoload const_name, File.join(prefix, path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Internal: Loads each autoloaded constant. If thread safety is a concern,
|
32
|
+
# wrap this in a Mutex.
|
33
|
+
#
|
34
|
+
# Returns nothing.
|
35
|
+
def load_autoloaded_constants
|
36
|
+
constants.each do |const|
|
37
|
+
const_get(const) if autoload?(const)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Internal: Filters the module's contents with those that have been already
|
42
|
+
# autoloaded.
|
43
|
+
#
|
44
|
+
# Returns an Array of Class/Module objects.
|
45
|
+
def all_loaded_constants
|
46
|
+
constants.map { |c| const_get(c) }.
|
47
|
+
select { |a| a.respond_to?(:loaded?) && a.loaded? }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Adapter
|
52
|
+
extend AutoloadHelper
|
53
|
+
autoload_all 'faraday/adapter',
|
54
|
+
:NetHttp => 'net_http',
|
55
|
+
:NetHttpPersistent => 'net_http_persistent',
|
56
|
+
:Typhoeus => 'typhoeus',
|
57
|
+
:EMSynchrony => 'em_synchrony',
|
58
|
+
:EMHttp => 'em_http',
|
59
|
+
:Patron => 'patron',
|
60
|
+
:Excon => 'excon',
|
61
|
+
:Test => 'test',
|
62
|
+
:Rack => 'rack',
|
63
|
+
:HTTPClient => 'httpclient'
|
64
|
+
end
|
65
|
+
|
66
|
+
class Request
|
67
|
+
extend AutoloadHelper
|
68
|
+
autoload_all 'faraday/request',
|
69
|
+
:UrlEncoded => 'url_encoded',
|
70
|
+
:Multipart => 'multipart',
|
71
|
+
:Retry => 'retry',
|
72
|
+
:Timeout => 'timeout',
|
73
|
+
:Authorization => 'authorization',
|
74
|
+
:BasicAuthentication => 'basic_authentication',
|
75
|
+
:TokenAuthentication => 'token_authentication',
|
76
|
+
:Instrumentation => 'instrumentation'
|
77
|
+
end
|
78
|
+
|
79
|
+
class Response
|
80
|
+
extend AutoloadHelper
|
81
|
+
autoload_all 'faraday/response',
|
82
|
+
:RaiseError => 'raise_error',
|
83
|
+
:Logger => 'logger'
|
84
|
+
end
|
85
|
+
end
|