faraday 0.9.1 → 0.11.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/LICENSE.md +1 -1
- data/README.md +53 -16
- data/lib/faraday/adapter/em_http.rb +8 -2
- data/lib/faraday/adapter/em_http_ssl_patch.rb +1 -1
- data/lib/faraday/adapter/em_synchrony.rb +16 -2
- data/lib/faraday/adapter/excon.rb +7 -7
- data/lib/faraday/adapter/httpclient.rb +27 -5
- data/lib/faraday/adapter/net_http.rb +13 -8
- data/lib/faraday/adapter/net_http_persistent.rb +6 -4
- data/lib/faraday/adapter/patron.rb +13 -9
- data/lib/faraday/adapter/test.rb +64 -21
- data/lib/faraday/adapter.rb +8 -1
- data/lib/faraday/connection.rb +14 -9
- data/lib/faraday/error.rb +11 -1
- data/lib/faraday/options.rb +18 -1
- data/lib/faraday/parameters.rb +54 -38
- data/lib/faraday/rack_builder.rb +3 -2
- data/lib/faraday/request/authorization.rb +1 -2
- data/lib/faraday/request/retry.rb +10 -4
- data/lib/faraday/request.rb +2 -0
- data/lib/faraday/response/logger.rb +27 -6
- data/lib/faraday/response.rb +6 -2
- data/lib/faraday/utils.rb +22 -2
- data/lib/faraday.rb +8 -33
- metadata +7 -93
- data/.document +0 -6
- data/CHANGELOG.md +0 -20
- data/CONTRIBUTING.md +0 -36
- data/Gemfile +0 -25
- data/Rakefile +0 -71
- data/faraday.gemspec +0 -34
- data/script/cached-bundle +0 -46
- data/script/console +0 -7
- data/script/generate_certs +0 -42
- data/script/package +0 -7
- data/script/proxy-server +0 -42
- data/script/release +0 -17
- data/script/s3-put +0 -71
- data/script/server +0 -36
- data/script/test +0 -172
- data/test/adapters/default_test.rb +0 -14
- data/test/adapters/em_http_test.rb +0 -20
- data/test/adapters/em_synchrony_test.rb +0 -20
- data/test/adapters/excon_test.rb +0 -20
- data/test/adapters/httpclient_test.rb +0 -21
- data/test/adapters/integration.rb +0 -254
- data/test/adapters/logger_test.rb +0 -82
- data/test/adapters/net_http_persistent_test.rb +0 -20
- data/test/adapters/net_http_test.rb +0 -14
- data/test/adapters/patron_test.rb +0 -20
- data/test/adapters/rack_test.rb +0 -31
- data/test/adapters/test_middleware_test.rb +0 -114
- data/test/adapters/typhoeus_test.rb +0 -28
- data/test/authentication_middleware_test.rb +0 -65
- data/test/composite_read_io_test.rb +0 -111
- data/test/connection_test.rb +0 -522
- data/test/env_test.rb +0 -218
- data/test/helper.rb +0 -81
- data/test/live_server.rb +0 -67
- data/test/middleware/instrumentation_test.rb +0 -88
- data/test/middleware/retry_test.rb +0 -177
- data/test/middleware_stack_test.rb +0 -173
- data/test/multibyte.txt +0 -1
- data/test/options_test.rb +0 -252
- data/test/parameters_test.rb +0 -64
- data/test/request_middleware_test.rb +0 -142
- data/test/response_middleware_test.rb +0 -72
- data/test/strawberry.rb +0 -2
- data/test/utils_test.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88d17f843f96e641d4cb8b87b360b99adfee6c53
|
4
|
+
data.tar.gz: 3c0031b2fa042939cc5e7f27aefa00f8ebe6a97f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03fa51e8008930909fb2e5f40afe8f3d59d176574a084e364569d256b0c073bd06796bb0fe96f79c42cfacda2ee8417fecb1b3fc13e5b46bbb76f960136d116c
|
7
|
+
data.tar.gz: 16432e693c7c666ac40de8a03ca890f08ee1cba705477afd31d64346282f018abf9ee617e1996330bbe2b2c3352021683e386522d700c49d08246b77d36fb65a
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -6,7 +6,8 @@ processing the request/response cycle.
|
|
6
6
|
|
7
7
|
Faraday supports these adapters:
|
8
8
|
|
9
|
-
* Net::HTTP
|
9
|
+
* [Net::HTTP][net_http] _(default)_
|
10
|
+
* [Net::HTTP::Persistent][persistent]
|
10
11
|
* [Excon][]
|
11
12
|
* [Typhoeus][]
|
12
13
|
* [Patron][]
|
@@ -16,6 +17,10 @@ Faraday supports these adapters:
|
|
16
17
|
It also includes a Rack adapter for hitting loaded Rack applications through
|
17
18
|
Rack::Test, and a Test adapter for stubbing requests by hand.
|
18
19
|
|
20
|
+
## API documentation
|
21
|
+
|
22
|
+
Available at [rubydoc.info](http://www.rubydoc.info/gems/faraday).
|
23
|
+
|
19
24
|
## Usage
|
20
25
|
|
21
26
|
```ruby
|
@@ -25,6 +30,14 @@ conn = Faraday.new(:url => 'http://sushi.com') do |faraday|
|
|
25
30
|
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
26
31
|
end
|
27
32
|
|
33
|
+
# Filter sensitive information from logs with a regex matcher
|
34
|
+
|
35
|
+
conn = Faraday.new(:url => 'http://sushi.com/api_key=s3cr3t') do |faraday|
|
36
|
+
faraday.response :logger do | logger |
|
37
|
+
logger.filter(/(api_key=)(\w+)/,'\1[REMOVED]')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
28
41
|
## GET ##
|
29
42
|
|
30
43
|
response = conn.get '/nigiri/sake.json' # GET http://sushi.com/nigiri/sake.json
|
@@ -64,6 +77,32 @@ stack and default adapter (see [Faraday::RackBuilder#initialize](https://github.
|
|
64
77
|
response = Faraday.get 'http://sushi.com/nigiri/sake.json'
|
65
78
|
```
|
66
79
|
|
80
|
+
### Changing how parameters are serialized
|
81
|
+
|
82
|
+
Sometimes you need to send the same URL parameter multiple times with different
|
83
|
+
values. This requires manually setting the parameter encoder and can be done on
|
84
|
+
either per-connection or per-request basis.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
# per-connection setting
|
88
|
+
conn = Faraday.new :request => { :params_encoder => Faraday::FlatParamsEncoder }
|
89
|
+
|
90
|
+
conn.get do |req|
|
91
|
+
# per-request setting:
|
92
|
+
# req.options.params_encoder = my_encoder
|
93
|
+
req.params['roll'] = ['california', 'philadelphia']
|
94
|
+
end
|
95
|
+
# GET 'http://sushi.com?roll=california&roll=philadelphia'
|
96
|
+
```
|
97
|
+
|
98
|
+
The value of Faraday `params_encoder` can be any object that responds to:
|
99
|
+
|
100
|
+
* `encode(hash) #=> String`
|
101
|
+
* `decode(string) #=> Hash`
|
102
|
+
|
103
|
+
The encoder will affect both how query strings are processed and how POST bodies
|
104
|
+
get serialized. The default encoder is Faraday::NestedParamsEncoder.
|
105
|
+
|
67
106
|
## Advanced middleware usage
|
68
107
|
|
69
108
|
The order in which middleware is stacked is important. Like with Rack, the
|
@@ -183,13 +222,9 @@ stubs.verify_stubbed_calls
|
|
183
222
|
This library aims to support and is [tested against][travis] the following Ruby
|
184
223
|
implementations:
|
185
224
|
|
186
|
-
*
|
187
|
-
*
|
188
|
-
*
|
189
|
-
* MRI 2.0.0
|
190
|
-
* MRI 2.1.0
|
191
|
-
* [JRuby][]
|
192
|
-
* [Rubinius][]
|
225
|
+
* Ruby 1.9.3+
|
226
|
+
* [JRuby][] 1.7+
|
227
|
+
* [Rubinius][] 2+
|
193
228
|
|
194
229
|
If something doesn't work on one of these Ruby versions, it's a bug.
|
195
230
|
|
@@ -209,12 +244,14 @@ of a major release, support for that Ruby version may be dropped.
|
|
209
244
|
Copyright (c) 2009-2013 [Rick Olson](mailto:technoweenie@gmail.com), Zack Hobson.
|
210
245
|
See [LICENSE][] for details.
|
211
246
|
|
212
|
-
[
|
213
|
-
[
|
214
|
-
[
|
215
|
-
[
|
247
|
+
[net_http]: http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html
|
248
|
+
[persistent]: https://github.com/drbrain/net-http-persistent
|
249
|
+
[travis]: https://travis-ci.org/lostisland/faraday
|
250
|
+
[excon]: https://github.com/excon/excon#readme
|
251
|
+
[typhoeus]: https://github.com/typhoeus/typhoeus#readme
|
252
|
+
[patron]: http://toland.github.io/patron/
|
216
253
|
[eventmachine]: https://github.com/igrigorik/em-http-request#readme
|
217
|
-
[httpclient]:
|
218
|
-
[jruby]:
|
219
|
-
[rubinius]:
|
220
|
-
[license]:
|
254
|
+
[httpclient]: https://github.com/nahi/httpclient
|
255
|
+
[jruby]: http://jruby.org/
|
256
|
+
[rubinius]: http://rubini.us/
|
257
|
+
[license]: LICENSE.md
|
@@ -138,9 +138,11 @@ module Faraday
|
|
138
138
|
|
139
139
|
# TODO: reuse the connection to support pipelining
|
140
140
|
def perform_single_request(env)
|
141
|
-
req =
|
141
|
+
req = create_request(env)
|
142
142
|
req.setup_request(env[:method], request_config(env)).callback { |client|
|
143
|
-
|
143
|
+
status = client.response_header.status
|
144
|
+
reason = client.response_header.http_reason
|
145
|
+
save_response(env, status, client.response, nil, reason) do |resp_headers|
|
144
146
|
client.response_header.each do |name, value|
|
145
147
|
resp_headers[name.to_sym] = value
|
146
148
|
end
|
@@ -148,6 +150,10 @@ module Faraday
|
|
148
150
|
}
|
149
151
|
end
|
150
152
|
|
153
|
+
def create_request(env)
|
154
|
+
EventMachine::HttpRequest.new(env[:url], connection_config(env).merge(@connection_options))
|
155
|
+
end
|
156
|
+
|
151
157
|
def error_message(client)
|
152
158
|
client.error or "request failed"
|
153
159
|
end
|
@@ -19,7 +19,7 @@ module Faraday
|
|
19
19
|
|
20
20
|
def call(env)
|
21
21
|
super
|
22
|
-
request =
|
22
|
+
request = create_request(env)
|
23
23
|
|
24
24
|
http_method = env[:method].to_s.downcase.to_sym
|
25
25
|
|
@@ -54,7 +54,9 @@ module Faraday
|
|
54
54
|
|
55
55
|
raise client.error if client.error
|
56
56
|
|
57
|
-
|
57
|
+
status = client.response_header.status
|
58
|
+
reason = client.response_header.http_reason
|
59
|
+
save_response(env, status, client.response, nil, reason) do |resp_headers|
|
58
60
|
client.response_header.each do |name, value|
|
59
61
|
resp_headers[name.to_sym] = value
|
60
62
|
end
|
@@ -70,6 +72,14 @@ module Faraday
|
|
70
72
|
else
|
71
73
|
raise Error::ConnectionFailed, err
|
72
74
|
end
|
75
|
+
rescue Errno::ETIMEDOUT => err
|
76
|
+
raise Error::TimeoutError, err
|
77
|
+
rescue RuntimeError => err
|
78
|
+
if err.message == "connection closed by server"
|
79
|
+
raise Error::ConnectionFailed, err
|
80
|
+
else
|
81
|
+
raise
|
82
|
+
end
|
73
83
|
rescue => err
|
74
84
|
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
75
85
|
raise Faraday::SSLError, err
|
@@ -77,6 +87,10 @@ module Faraday
|
|
77
87
|
raise
|
78
88
|
end
|
79
89
|
end
|
90
|
+
|
91
|
+
def create_request(env)
|
92
|
+
EventMachine::HttpRequest.new(Utils::URI(env[:url].to_s), connection_config(env).merge(@connection_options))
|
93
|
+
end
|
80
94
|
end
|
81
95
|
end
|
82
96
|
end
|
@@ -3,11 +3,6 @@ module Faraday
|
|
3
3
|
class Excon < Faraday::Adapter
|
4
4
|
dependency 'excon'
|
5
5
|
|
6
|
-
def initialize(app, connection_options = {})
|
7
|
-
@connection_options = connection_options
|
8
|
-
super(app)
|
9
|
-
end
|
10
|
-
|
11
6
|
def call(env)
|
12
7
|
super
|
13
8
|
|
@@ -41,6 +36,7 @@ module Faraday
|
|
41
36
|
if req[:proxy]
|
42
37
|
opts[:proxy] = {
|
43
38
|
:host => req[:proxy][:uri].host,
|
39
|
+
:hostname => req[:proxy][:uri].hostname,
|
44
40
|
:port => req[:proxy][:uri].port,
|
45
41
|
:scheme => req[:proxy][:uri].scheme,
|
46
42
|
:user => req[:proxy][:user],
|
@@ -49,14 +45,14 @@ module Faraday
|
|
49
45
|
end
|
50
46
|
end
|
51
47
|
|
52
|
-
conn =
|
48
|
+
conn = create_connection(env, opts)
|
53
49
|
|
54
50
|
resp = conn.request \
|
55
51
|
:method => env[:method].to_s.upcase,
|
56
52
|
:headers => env[:request_headers],
|
57
53
|
:body => read_body(env)
|
58
54
|
|
59
|
-
save_response(env, resp.status.to_i, resp.body, resp.headers)
|
55
|
+
save_response(env, resp.status.to_i, resp.body, resp.headers, resp.reason_phrase)
|
60
56
|
|
61
57
|
@app.call env
|
62
58
|
rescue ::Excon::Errors::SocketError => err
|
@@ -71,6 +67,10 @@ module Faraday
|
|
71
67
|
raise Error::TimeoutError, err
|
72
68
|
end
|
73
69
|
|
70
|
+
def create_connection(env, opts)
|
71
|
+
::Excon.new(env[:url].to_s, opts.merge(@connection_options))
|
72
|
+
end
|
73
|
+
|
74
74
|
# TODO: support streaming requests
|
75
75
|
def read_body(env)
|
76
76
|
env[:body].respond_to?(:read) ? env[:body].read : env[:body]
|
@@ -10,6 +10,9 @@ module Faraday
|
|
10
10
|
def call(env)
|
11
11
|
super
|
12
12
|
|
13
|
+
# enable compression
|
14
|
+
client.transparent_gzip_decompression = true
|
15
|
+
|
13
16
|
if req = env[:request]
|
14
17
|
if proxy = req[:proxy]
|
15
18
|
configure_proxy proxy
|
@@ -26,6 +29,8 @@ module Faraday
|
|
26
29
|
configure_ssl ssl
|
27
30
|
end
|
28
31
|
|
32
|
+
configure_client
|
33
|
+
|
29
34
|
# TODO Don't stream yet.
|
30
35
|
# https://github.com/nahi/httpclient/pull/90
|
31
36
|
env[:body] = env[:body].read if env[:body].respond_to? :read
|
@@ -34,10 +39,10 @@ module Faraday
|
|
34
39
|
:body => env[:body],
|
35
40
|
:header => env[:request_headers]
|
36
41
|
|
37
|
-
save_response env, resp.status, resp.body, resp.headers
|
42
|
+
save_response env, resp.status, resp.body, resp.headers, resp.reason
|
38
43
|
|
39
44
|
@app.call env
|
40
|
-
rescue ::HTTPClient::TimeoutError
|
45
|
+
rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
|
41
46
|
raise Faraday::Error::TimeoutError, $!
|
42
47
|
rescue ::HTTPClient::BadResponseError => err
|
43
48
|
if err.message.include?('status 407')
|
@@ -45,7 +50,7 @@ module Faraday
|
|
45
50
|
else
|
46
51
|
raise Faraday::Error::ClientError, $!
|
47
52
|
end
|
48
|
-
rescue Errno::ECONNREFUSED,
|
53
|
+
rescue Errno::ECONNREFUSED, IOError
|
49
54
|
raise Faraday::Error::ConnectionFailed, $!
|
50
55
|
rescue => err
|
51
56
|
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
@@ -69,14 +74,14 @@ module Faraday
|
|
69
74
|
|
70
75
|
def configure_ssl(ssl)
|
71
76
|
ssl_config = client.ssl_config
|
77
|
+
ssl_config.verify_mode = ssl_verify_mode(ssl)
|
78
|
+
ssl_config.cert_store = ssl_cert_store(ssl)
|
72
79
|
|
73
80
|
ssl_config.add_trust_ca ssl[:ca_file] if ssl[:ca_file]
|
74
81
|
ssl_config.add_trust_ca ssl[:ca_path] if ssl[:ca_path]
|
75
|
-
ssl_config.cert_store = ssl[:cert_store] if ssl[:cert_store]
|
76
82
|
ssl_config.client_cert = ssl[:client_cert] if ssl[:client_cert]
|
77
83
|
ssl_config.client_key = ssl[:client_key] if ssl[:client_key]
|
78
84
|
ssl_config.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
|
79
|
-
ssl_config.verify_mode = ssl_verify_mode(ssl)
|
80
85
|
end
|
81
86
|
|
82
87
|
def configure_timeouts(req)
|
@@ -92,6 +97,23 @@ module Faraday
|
|
92
97
|
end
|
93
98
|
end
|
94
99
|
|
100
|
+
def configure_client
|
101
|
+
@config_block.call(client) if @config_block
|
102
|
+
end
|
103
|
+
|
104
|
+
def ssl_cert_store(ssl)
|
105
|
+
return ssl[:cert_store] if ssl[:cert_store]
|
106
|
+
# Memoize the cert store so that the same one is passed to
|
107
|
+
# HTTPClient each time, to avoid resyncing SSL sesions when
|
108
|
+
# it's changed
|
109
|
+
@cert_store ||= begin
|
110
|
+
# Use the default cert store by default, i.e. system ca certs
|
111
|
+
cert_store = OpenSSL::X509::Store.new
|
112
|
+
cert_store.set_default_paths
|
113
|
+
cert_store
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
95
117
|
def ssl_verify_mode(ssl)
|
96
118
|
ssl[:verify_mode] || begin
|
97
119
|
if ssl.fetch(:verify, true)
|
@@ -10,13 +10,14 @@ module Faraday
|
|
10
10
|
class Adapter
|
11
11
|
class NetHttp < Faraday::Adapter
|
12
12
|
NET_HTTP_EXCEPTIONS = [
|
13
|
-
|
13
|
+
IOError,
|
14
14
|
Errno::ECONNABORTED,
|
15
15
|
Errno::ECONNREFUSED,
|
16
16
|
Errno::ECONNRESET,
|
17
17
|
Errno::EHOSTUNREACH,
|
18
18
|
Errno::EINVAL,
|
19
19
|
Errno::ENETUNREACH,
|
20
|
+
Errno::EPIPE,
|
20
21
|
Net::HTTPBadResponse,
|
21
22
|
Net::HTTPHeaderSyntaxError,
|
22
23
|
Net::ProtocolError,
|
@@ -31,10 +32,7 @@ module Faraday
|
|
31
32
|
super
|
32
33
|
with_net_http_connection(env) do |http|
|
33
34
|
configure_ssl(http, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
|
34
|
-
|
35
|
-
req = env[:request]
|
36
|
-
http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
|
37
|
-
http.open_timeout = req[:open_timeout] if req[:open_timeout]
|
35
|
+
configure_request(http, env[:request])
|
38
36
|
|
39
37
|
begin
|
40
38
|
http_response = perform_request(http, env)
|
@@ -46,7 +44,7 @@ module Faraday
|
|
46
44
|
end
|
47
45
|
end
|
48
46
|
|
49
|
-
save_response(env, http_response.code.to_i, http_response.body || '') do |response_headers|
|
47
|
+
save_response(env, http_response.code.to_i, http_response.body || '', nil, http_response.message) do |response_headers|
|
50
48
|
http_response.each_header do |key, value|
|
51
49
|
response_headers[key] = value
|
52
50
|
end
|
@@ -54,7 +52,7 @@ module Faraday
|
|
54
52
|
end
|
55
53
|
|
56
54
|
@app.call env
|
57
|
-
rescue Timeout::Error => err
|
55
|
+
rescue Timeout::Error, Errno::ETIMEDOUT => err
|
58
56
|
raise Faraday::Error::TimeoutError, err
|
59
57
|
end
|
60
58
|
|
@@ -92,7 +90,7 @@ module Faraday
|
|
92
90
|
Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:user], proxy[:password])
|
93
91
|
else
|
94
92
|
Net::HTTP
|
95
|
-
end.new(env[:url].host, env[:url].port)
|
93
|
+
end.new(env[:url].host, env[:url].port || (env[:url].scheme == 'https' ? 443 : 80))
|
96
94
|
end
|
97
95
|
|
98
96
|
def configure_ssl(http, ssl)
|
@@ -108,6 +106,13 @@ module Faraday
|
|
108
106
|
http.ssl_version = ssl[:version] if ssl[:version]
|
109
107
|
end
|
110
108
|
|
109
|
+
def configure_request(http, req)
|
110
|
+
http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
|
111
|
+
http.open_timeout = req[:open_timeout] if req[:open_timeout]
|
112
|
+
|
113
|
+
@config_block.call(http) if @config_block
|
114
|
+
end
|
115
|
+
|
111
116
|
def ssl_cert_store(ssl)
|
112
117
|
return ssl[:cert_store] if ssl[:cert_store]
|
113
118
|
# Use the default cert store by default, i.e. system ca certs
|
@@ -4,12 +4,11 @@
|
|
4
4
|
|
5
5
|
module Faraday
|
6
6
|
class Adapter
|
7
|
-
# Experimental adapter for net-http-persistent
|
8
7
|
class NetHttpPersistent < NetHttp
|
9
8
|
dependency 'net/http/persistent'
|
10
9
|
|
11
|
-
def
|
12
|
-
if proxy = env[:request][:proxy]
|
10
|
+
def net_http_connection(env)
|
11
|
+
if (proxy = env[:request][:proxy])
|
13
12
|
proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
|
14
13
|
proxy_uri.user = proxy_uri.password = nil
|
15
14
|
# awful patch for net-http-persistent 2.8 not unescaping user/password
|
@@ -17,13 +16,16 @@ module Faraday
|
|
17
16
|
define_method(:user) { proxy[:user] }
|
18
17
|
define_method(:password) { proxy[:password] }
|
19
18
|
end if proxy[:user]
|
19
|
+
return Net::HTTP::Persistent.new 'Faraday', proxy_uri
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
Net::HTTP::Persistent.new 'Faraday'
|
23
23
|
end
|
24
24
|
|
25
25
|
def perform_request(http, env)
|
26
26
|
http.request env[:url], create_request(env)
|
27
|
+
rescue Errno::ETIMEDOUT => error
|
28
|
+
raise Faraday::Error::TimeoutError, error
|
27
29
|
rescue Net::HTTP::Persistent::Error => error
|
28
30
|
if error.message.include? 'Timeout'
|
29
31
|
raise Faraday::Error::TimeoutError, error
|
@@ -3,11 +3,6 @@ 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
|
9
|
-
end
|
10
|
-
|
11
6
|
def call(env)
|
12
7
|
super
|
13
8
|
|
@@ -35,7 +30,10 @@ module Faraday
|
|
35
30
|
raise Error::ConnectionFailed, $!
|
36
31
|
end
|
37
32
|
|
38
|
-
|
33
|
+
# Remove the "HTTP/1.1 200", leaving just the reason phrase
|
34
|
+
reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
|
35
|
+
|
36
|
+
save_response(env, response.status, response.body, response.headers, reason_phrase)
|
39
37
|
|
40
38
|
@app.call env
|
41
39
|
rescue ::Patron::TimeoutError => err
|
@@ -56,15 +54,21 @@ module Faraday
|
|
56
54
|
# HAX: helps but doesn't work completely
|
57
55
|
# https://github.com/toland/patron/issues/34
|
58
56
|
::Patron::Request::VALID_ACTIONS.tap do |actions|
|
59
|
-
|
60
|
-
|
57
|
+
if actions[0].is_a?(Symbol)
|
58
|
+
actions << :patch unless actions.include? :patch
|
59
|
+
actions << :options unless actions.include? :options
|
60
|
+
else
|
61
|
+
# Patron 0.4.20 and up
|
62
|
+
actions << "PATCH" unless actions.include? "PATCH"
|
63
|
+
actions << "OPTIONS" unless actions.include? "OPTIONS"
|
64
|
+
end
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
64
68
|
def create_session
|
65
69
|
session = ::Patron::Session.new
|
66
70
|
session.insecure = true
|
67
|
-
@
|
71
|
+
@config_block.call(session) if @config_block
|
68
72
|
session
|
69
73
|
end
|
70
74
|
end
|
data/lib/faraday/adapter/test.rb
CHANGED
@@ -1,16 +1,41 @@
|
|
1
1
|
module Faraday
|
2
2
|
class Adapter
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
3
|
+
# Examples
|
4
|
+
#
|
5
|
+
# test = Faraday::Connection.new do
|
6
|
+
# use Faraday::Adapter::Test do |stub|
|
7
|
+
# # simply define matcher to match the request
|
8
|
+
# stub.get '/resource.json' do
|
9
|
+
# # return static content
|
10
|
+
# [200, {'Content-Type' => 'application/json'}, 'hi world']
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# # response with content generated based on request
|
14
|
+
# stub.get '/showget' do |env|
|
15
|
+
# [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # regular expression can be used as matching filter
|
19
|
+
# stub.get /\A\/items\/(\d+)\z/ do |env, meta|
|
20
|
+
# # in case regular expression is used an instance of MatchData can be received
|
21
|
+
# [200, {'Content-Type' => 'text/plain'}, "showing item: #{meta[:match_data][1]}"]
|
22
|
+
# end
|
7
23
|
# end
|
8
24
|
# end
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
25
|
+
#
|
26
|
+
# resp = test.get '/resource.json'
|
27
|
+
# resp.body # => 'hi world'
|
28
|
+
#
|
29
|
+
# resp = test.get '/showget'
|
30
|
+
# resp.body # => 'get'
|
31
|
+
#
|
32
|
+
# resp = test.get '/items/1'
|
33
|
+
# resp.body # => 'showing item: 1'
|
34
|
+
#
|
35
|
+
# resp = test.get '/items/2'
|
36
|
+
# resp.body # => 'showing item: 2'
|
13
37
|
#
|
38
|
+
|
14
39
|
class Test < Faraday::Adapter
|
15
40
|
attr_accessor :stubs
|
16
41
|
|
@@ -33,12 +58,12 @@ module Faraday
|
|
33
58
|
stack = @stack[request_method]
|
34
59
|
consumed = (@consumed[request_method] ||= [])
|
35
60
|
|
36
|
-
|
61
|
+
stub, meta = matches?(stack, path, headers, body)
|
62
|
+
if stub
|
37
63
|
consumed << stack.delete(stub)
|
38
|
-
stub
|
39
|
-
else
|
40
|
-
matches?(consumed, path, headers, body)
|
64
|
+
return stub, meta
|
41
65
|
end
|
66
|
+
matches?(consumed, path, headers, body)
|
42
67
|
end
|
43
68
|
|
44
69
|
def get(path, headers = {}, &block)
|
@@ -85,18 +110,22 @@ module Faraday
|
|
85
110
|
protected
|
86
111
|
|
87
112
|
def new_stub(request_method, path, headers = {}, body=nil, &block)
|
88
|
-
normalized_path = Faraday::Utils.normalize_path(path)
|
113
|
+
normalized_path = path.is_a?(Regexp) ? path : Faraday::Utils.normalize_path(path)
|
89
114
|
(@stack[request_method] ||= []) << Stub.new(normalized_path, headers, body, block)
|
90
115
|
end
|
91
116
|
|
92
117
|
def matches?(stack, path, headers, body)
|
93
|
-
stack.
|
118
|
+
stack.each do |stub|
|
119
|
+
match_result, meta = stub.matches?(path, headers, body)
|
120
|
+
return stub, meta if match_result
|
121
|
+
end
|
122
|
+
nil
|
94
123
|
end
|
95
124
|
end
|
96
125
|
|
97
126
|
class Stub < Struct.new(:path, :params, :headers, :body, :block)
|
98
127
|
def initialize(full, headers, body, block)
|
99
|
-
path, query = full.split(
|
128
|
+
path, query = full.respond_to?(:split) ? full.split("?") : full
|
100
129
|
params = query ?
|
101
130
|
Faraday::Utils.parse_nested_query(query) :
|
102
131
|
{}
|
@@ -108,10 +137,21 @@ module Faraday
|
|
108
137
|
request_params = request_query ?
|
109
138
|
Faraday::Utils.parse_nested_query(request_query) :
|
110
139
|
{}
|
111
|
-
|
140
|
+
# meta is a hash use as carrier
|
141
|
+
# that will be yielded to consumer block
|
142
|
+
meta = {}
|
143
|
+
return path_match?(request_path, meta) &&
|
112
144
|
params_match?(request_params) &&
|
113
145
|
(body.to_s.size.zero? || request_body == body) &&
|
114
|
-
headers_match?(request_headers)
|
146
|
+
headers_match?(request_headers), meta
|
147
|
+
end
|
148
|
+
|
149
|
+
def path_match?(request_path, meta)
|
150
|
+
if path.is_a? Regexp
|
151
|
+
!!(meta[:match_data] = path.match(request_path))
|
152
|
+
else
|
153
|
+
path == request_path
|
154
|
+
end
|
115
155
|
end
|
116
156
|
|
117
157
|
def params_match?(request_params)
|
@@ -146,11 +186,14 @@ module Faraday
|
|
146
186
|
normalized_path = Faraday::Utils.normalize_path(env[:url])
|
147
187
|
params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
|
148
188
|
|
149
|
-
|
189
|
+
stub, meta = stubs.match(env[:method], normalized_path, env.request_headers, env[:body])
|
190
|
+
if stub
|
150
191
|
env[:params] = (query = env[:url].query) ?
|
151
|
-
params_encoder.decode(query)
|
152
|
-
|
153
|
-
status, headers, body =
|
192
|
+
params_encoder.decode(query) : {}
|
193
|
+
block_arity = stub.block.arity
|
194
|
+
status, headers, body = (block_arity >= 0) ?
|
195
|
+
stub.block.call(*[env, meta].take(block_arity)) :
|
196
|
+
stub.block.call(env, meta)
|
154
197
|
save_response(env, status, body, headers)
|
155
198
|
else
|
156
199
|
raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
|
data/lib/faraday/adapter.rb
CHANGED
@@ -30,13 +30,20 @@ module Faraday
|
|
30
30
|
extend Parallelism
|
31
31
|
self.supports_parallel = false
|
32
32
|
|
33
|
+
def initialize(app = nil, opts = {}, &block)
|
34
|
+
super(app)
|
35
|
+
@connection_options = opts
|
36
|
+
@config_block = block
|
37
|
+
end
|
38
|
+
|
33
39
|
def call(env)
|
34
40
|
env.clear_body if env.needs_body?
|
35
41
|
end
|
36
42
|
|
37
|
-
def save_response(env, status, body, headers = nil)
|
43
|
+
def save_response(env, status, body, headers = nil, reason_phrase = nil)
|
38
44
|
env.status = status
|
39
45
|
env.body = body
|
46
|
+
env.reason_phrase = reason_phrase && reason_phrase.to_s.strip
|
40
47
|
env.response_headers = Utils::Headers.new.tap do |response_headers|
|
41
48
|
response_headers.update headers unless headers.nil?
|
42
49
|
yield(response_headers) if block_given?
|