faraday 0.12.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/LICENSE.md +1 -1
- data/README.md +53 -12
- data/lib/faraday/adapter/excon.rb +0 -1
- data/lib/faraday/adapter/httpclient.rb +1 -1
- data/lib/faraday/adapter/net_http.rb +4 -2
- data/lib/faraday/adapter/net_http_persistent.rb +20 -7
- data/lib/faraday/adapter/patron.rb +27 -3
- data/lib/faraday/adapter/test.rb +21 -13
- data/lib/faraday/adapter/typhoeus.rb +4 -115
- data/lib/faraday/adapter.rb +2 -0
- data/lib/faraday/autoload.rb +1 -1
- data/lib/faraday/connection.rb +50 -21
- data/lib/faraday/error.rb +7 -4
- data/lib/faraday/options.rb +3 -3
- data/lib/faraday/rack_builder.rb +24 -0
- data/lib/faraday/request/retry.rb +64 -16
- data/lib/faraday/response/logger.rb +2 -2
- data/lib/faraday/utils.rb +18 -9
- data/lib/faraday.rb +7 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3737507d92b48e4b98e891c5026210048ab70b2b1ee17ea20993b8ffc65eafb5
|
4
|
+
data.tar.gz: caaaa7f7ad1bdda848ac7bc70d4d1b9ba9d06bc85912a61b1ee4082086629a26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 231b96efdd5b0399f204edaeba22d01661b9d301aff6cad7d097c27c1e95f0a0a8adc9184e88f089862fa9db9a833e50a3eb7bfb96034a2df7f1bdd93661f3fb
|
7
|
+
data.tar.gz: f19fca5f59454b7b620160c3e58339e0dff8049be29bda8e8f1a494455dac6c62a1c6cbe4b4e141e999ea3df25cbcdf3ef09d65e93d71a882c318c75c3070dec
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/faraday.svg)](https://rubygems.org/gems/faraday)
|
4
4
|
[![Build Status](https://travis-ci.org/lostisland/faraday.svg)](https://travis-ci.org/lostisland/faraday)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/github/lostisland/faraday/badge.svg?branch=master)](https://coveralls.io/github/lostisland/faraday?branch=master)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/lostisland/faraday/badges/gpa.svg)](https://codeclimate.com/github/lostisland/faraday)
|
5
7
|
[![Gitter](https://badges.gitter.im/lostisland/faraday.svg)](https://gitter.im/lostisland/faraday?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
6
8
|
|
7
9
|
|
@@ -9,7 +11,7 @@ Faraday is an HTTP client lib that provides a common interface over many
|
|
9
11
|
adapters (such as Net::HTTP) and embraces the concept of Rack middleware when
|
10
12
|
processing the request/response cycle.
|
11
13
|
|
12
|
-
Faraday supports these adapters:
|
14
|
+
Faraday supports these adapters out of the box:
|
13
15
|
|
14
16
|
* [Net::HTTP][net_http] _(default)_
|
15
17
|
* [Net::HTTP::Persistent][persistent]
|
@@ -18,6 +20,10 @@ Faraday supports these adapters:
|
|
18
20
|
* [EventMachine][]
|
19
21
|
* [HTTPClient][]
|
20
22
|
|
23
|
+
Adapters are slowly being moved into their own gems, or bundled with HTTP clients:
|
24
|
+
|
25
|
+
* [Typhoeus][]
|
26
|
+
|
21
27
|
It also includes a Rack adapter for hitting loaded Rack applications through
|
22
28
|
Rack::Test, and a Test adapter for stubbing requests by hand.
|
23
29
|
|
@@ -38,11 +44,12 @@ stack and default adapter (see [Faraday::RackBuilder#initialize](https://github.
|
|
38
44
|
A more flexible way to use Faraday is to start with a Connection object. If you want to keep the same defaults, you can use this syntax:
|
39
45
|
|
40
46
|
```ruby
|
41
|
-
conn = Faraday.new(:url => 'http://www.example.com')
|
42
|
-
response = conn.get '/users' # GET http://www.example.com/users'
|
47
|
+
conn = Faraday.new(:url => 'http://www.example.com')
|
48
|
+
response = conn.get '/users' # GET http://www.example.com/users'
|
43
49
|
```
|
44
50
|
|
45
|
-
Connections can also take an options hash as a parameter or be configured by using a block. Checkout the section called [Advanced middleware usage](#advanced-middleware-usage) for more details about how to use this block for configurations.
|
51
|
+
Connections can also take an options hash as a parameter or be configured by using a block. Checkout the section called [Advanced middleware usage](#advanced-middleware-usage) for more details about how to use this block for configurations.
|
52
|
+
Since the default middleware stack uses url\_encoded middleware and default adapter, use them on building your own middleware stack.
|
46
53
|
|
47
54
|
```ruby
|
48
55
|
conn = Faraday.new(:url => 'http://sushi.com') do |faraday|
|
@@ -54,6 +61,7 @@ end
|
|
54
61
|
# Filter sensitive information from logs with a regex matcher
|
55
62
|
|
56
63
|
conn = Faraday.new(:url => 'http://sushi.com/api_key=s3cr3t') do |faraday|
|
64
|
+
faraday.request :url_encoded # form-encode POST params
|
57
65
|
faraday.response :logger do | logger |
|
58
66
|
logger.filter(/(api_key=)(\w+)/,'\1[REMOVED]')
|
59
67
|
end
|
@@ -61,7 +69,7 @@ conn = Faraday.new(:url => 'http://sushi.com/api_key=s3cr3t') do |faraday|
|
|
61
69
|
end
|
62
70
|
```
|
63
71
|
|
64
|
-
Once you have the connection object, use it to make HTTP requests. You can pass
|
72
|
+
Once you have the connection object, use it to make HTTP requests. You can pass parameters to it in a few different ways:
|
65
73
|
|
66
74
|
```ruby
|
67
75
|
## GET ##
|
@@ -140,6 +148,36 @@ The value of Faraday `params_encoder` can be any object that responds to:
|
|
140
148
|
The encoder will affect both how query strings are processed and how POST bodies
|
141
149
|
get serialized. The default encoder is Faraday::NestedParamsEncoder.
|
142
150
|
|
151
|
+
## Authentication
|
152
|
+
|
153
|
+
Basic and Token authentication are handled by Faraday::Request::BasicAuthentication and Faraday::Request::TokenAuthentication respectively. These can be added as middleware manually or through the helper methods.
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
Faraday.new(...) do |conn|
|
157
|
+
conn.basic_auth('username', 'password')
|
158
|
+
end
|
159
|
+
|
160
|
+
Faraday.new(...) do |conn|
|
161
|
+
conn.token_auth('authentication-token')
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
## Proxy
|
166
|
+
|
167
|
+
Faraday will try to automatically infer the proxy settings from your system using `URI#find_proxy`.
|
168
|
+
This will retrieve them from environment variables such as http_proxy, ftp_proxy, no_proxy, etc.
|
169
|
+
If for any reason you want to disable this behaviour, you can do so by setting the global varibale `ignore_env_proxy`:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
Faraday.ignore_env_proxy = true
|
173
|
+
```
|
174
|
+
|
175
|
+
You can also specify a custom proxy when initializing the connection
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
Faraday.new('http://www.example.com', :proxy => 'http://proxy.com')
|
179
|
+
```
|
180
|
+
|
143
181
|
## Advanced middleware usage
|
144
182
|
|
145
183
|
The order in which middleware is stacked is important. Like with Rack, the
|
@@ -152,6 +190,7 @@ Faraday.new(...) do |conn|
|
|
152
190
|
conn.request :multipart
|
153
191
|
conn.request :url_encoded
|
154
192
|
|
193
|
+
# Last middleware must be the adapter:
|
155
194
|
conn.adapter :net_http
|
156
195
|
end
|
157
196
|
```
|
@@ -216,7 +255,7 @@ later, response. Some keys are:
|
|
216
255
|
|
217
256
|
## Ad-hoc adapters customization
|
218
257
|
|
219
|
-
Faraday is intended to be a generic interface between your code and the adapter. However, sometimes you need to access a feature specific to one of the adapters that is not covered in Faraday's interface.
|
258
|
+
Faraday is intended to be a generic interface between your code and the adapter. However, sometimes you need to access a feature specific to one of the adapters that is not covered in Faraday's interface.
|
220
259
|
|
221
260
|
When that happens, you can pass a block when specifying the adapter to customize it. The block parameter will change based on the adapter you're using. See below for some examples.
|
222
261
|
|
@@ -296,11 +335,6 @@ resp = test.get '/else' #=> raises "no such stub" error
|
|
296
335
|
stubs.verify_stubbed_calls
|
297
336
|
```
|
298
337
|
|
299
|
-
## TODO
|
300
|
-
|
301
|
-
* support streaming requests/responses
|
302
|
-
* better stubbing API
|
303
|
-
|
304
338
|
## Supported Ruby versions
|
305
339
|
|
306
340
|
This library aims to support and is [tested against][travis] the following Ruby
|
@@ -323,9 +357,15 @@ implementation, you will be responsible for providing patches in a timely
|
|
323
357
|
fashion. If critical issues for a particular implementation exist at the time
|
324
358
|
of a major release, support for that Ruby version may be dropped.
|
325
359
|
|
360
|
+
## Contribute
|
361
|
+
|
362
|
+
Do you want to contribute to Faraday?
|
363
|
+
Open the issues page and check for the `any volunteer?` label!
|
364
|
+
But before you start coding, please read our [Contributing Guide](https://github.com/lostisland/faraday/blob/master/.github/CONTRIBUTING.md)
|
365
|
+
|
326
366
|
## Copyright
|
327
367
|
|
328
|
-
Copyright (c) 2009-
|
368
|
+
Copyright (c) 2009-2017 [Rick Olson](mailto:technoweenie@gmail.com), Zack Hobson.
|
329
369
|
See [LICENSE][] for details.
|
330
370
|
|
331
371
|
[net_http]: http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html
|
@@ -335,6 +375,7 @@ See [LICENSE][] for details.
|
|
335
375
|
[patron]: http://toland.github.io/patron/
|
336
376
|
[eventmachine]: https://github.com/igrigorik/em-http-request#readme
|
337
377
|
[httpclient]: https://github.com/nahi/httpclient
|
378
|
+
[typhoeus]: https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb
|
338
379
|
[jruby]: http://jruby.org/
|
339
380
|
[rubinius]: http://rubini.us/
|
340
381
|
[license]: LICENSE.md
|
@@ -50,7 +50,7 @@ module Faraday
|
|
50
50
|
else
|
51
51
|
raise Faraday::Error::ClientError, $!
|
52
52
|
end
|
53
|
-
rescue Errno::ECONNREFUSED, IOError
|
53
|
+
rescue Errno::ECONNREFUSED, IOError, SocketError
|
54
54
|
raise Faraday::Error::ConnectionFailed, $!
|
55
55
|
rescue => err
|
56
56
|
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
@@ -56,6 +56,8 @@ module Faraday
|
|
56
56
|
raise Faraday::Error::TimeoutError, err
|
57
57
|
end
|
58
58
|
|
59
|
+
private
|
60
|
+
|
59
61
|
def create_request(env)
|
60
62
|
request = Net::HTTPGenericRequest.new \
|
61
63
|
env[:method].to_s.upcase, # request method
|
@@ -87,10 +89,10 @@ module Faraday
|
|
87
89
|
|
88
90
|
def net_http_connection(env)
|
89
91
|
if proxy = env[:request][:proxy]
|
90
|
-
Net::HTTP::Proxy(proxy[:uri].
|
92
|
+
Net::HTTP::Proxy(proxy[:uri].hostname, proxy[:uri].port, proxy[:user], proxy[:password])
|
91
93
|
else
|
92
94
|
Net::HTTP
|
93
|
-
end.new(env[:url].
|
95
|
+
end.new(env[:url].hostname, env[:url].port || (env[:url].scheme == 'https' ? 443 : 80))
|
94
96
|
end
|
95
97
|
|
96
98
|
def configure_ssl(http, ssl)
|
@@ -1,13 +1,24 @@
|
|
1
|
-
# Rely on autoloading instead of explicit require; helps avoid the "already
|
2
|
-
# initialized constant" warning on Ruby 1.8.7 when NetHttp is refereced below.
|
3
|
-
# require 'faraday/adapter/net_http'
|
4
|
-
|
5
1
|
module Faraday
|
6
2
|
class Adapter
|
7
3
|
class NetHttpPersistent < NetHttp
|
8
4
|
dependency 'net/http/persistent'
|
9
5
|
|
6
|
+
private
|
7
|
+
|
10
8
|
def net_http_connection(env)
|
9
|
+
proxy_uri = proxy_uri(env)
|
10
|
+
|
11
|
+
cached_connection env[:url], proxy_uri do
|
12
|
+
if Net::HTTP::Persistent.instance_method(:initialize).parameters.first == [:key, :name]
|
13
|
+
Net::HTTP::Persistent.new(name: 'Faraday', proxy: proxy_uri)
|
14
|
+
else
|
15
|
+
Net::HTTP::Persistent.new('Faraday', proxy_uri)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def proxy_uri(env)
|
21
|
+
proxy_uri = nil
|
11
22
|
if (proxy = env[:request][:proxy])
|
12
23
|
proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
|
13
24
|
proxy_uri.user = proxy_uri.password = nil
|
@@ -16,10 +27,8 @@ module Faraday
|
|
16
27
|
define_method(:user) { proxy[:user] }
|
17
28
|
define_method(:password) { proxy[:password] }
|
18
29
|
end if proxy[:user]
|
19
|
-
return Net::HTTP::Persistent.new 'Faraday', proxy_uri
|
20
30
|
end
|
21
|
-
|
22
|
-
Net::HTTP::Persistent.new 'Faraday'
|
31
|
+
proxy_uri
|
23
32
|
end
|
24
33
|
|
25
34
|
def perform_request(http, env)
|
@@ -45,6 +54,10 @@ module Faraday
|
|
45
54
|
http.ca_file = ssl[:ca_file] if ssl[:ca_file]
|
46
55
|
http.ssl_version = ssl[:version] if ssl[:version]
|
47
56
|
end
|
57
|
+
|
58
|
+
def cached_connection(url, proxy_uri)
|
59
|
+
(@cached_connection ||= {})[[url.scheme, url.host, url.port, proxy_uri]] ||= yield
|
60
|
+
end
|
48
61
|
end
|
49
62
|
end
|
50
63
|
end
|
@@ -5,11 +5,11 @@ module Faraday
|
|
5
5
|
|
6
6
|
def call(env)
|
7
7
|
super
|
8
|
-
|
9
8
|
# TODO: support streaming requests
|
10
9
|
env[:body] = env[:body].read if env[:body].respond_to? :read
|
11
10
|
|
12
11
|
session = @session ||= create_session
|
12
|
+
configure_ssl(session, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
|
13
13
|
|
14
14
|
if req = env[:request]
|
15
15
|
session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
|
@@ -37,7 +37,7 @@ module Faraday
|
|
37
37
|
|
38
38
|
@app.call env
|
39
39
|
rescue ::Patron::TimeoutError => err
|
40
|
-
if err.message
|
40
|
+
if connection_timed_out_message?(err.message)
|
41
41
|
raise Faraday::Error::ConnectionFailed, err
|
42
42
|
else
|
43
43
|
raise Faraday::Error::TimeoutError, err
|
@@ -67,10 +67,34 @@ module Faraday
|
|
67
67
|
|
68
68
|
def create_session
|
69
69
|
session = ::Patron::Session.new
|
70
|
-
session.insecure = true
|
71
70
|
@config_block.call(session) if @config_block
|
72
71
|
session
|
73
72
|
end
|
73
|
+
|
74
|
+
def configure_ssl(session, ssl)
|
75
|
+
if ssl.fetch(:verify, true)
|
76
|
+
session.cacert = ssl[:ca_file]
|
77
|
+
else
|
78
|
+
session.insecure = true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
CURL_TIMEOUT_MESSAGES = [ "Connection time-out",
|
85
|
+
"Connection timed out",
|
86
|
+
"Timed out before name resolve",
|
87
|
+
"server connect has timed out",
|
88
|
+
"Resolving timed out",
|
89
|
+
"name lookup timed out",
|
90
|
+
"timed out before SSL",
|
91
|
+
"connect() timed out"
|
92
|
+
].freeze
|
93
|
+
|
94
|
+
def connection_timed_out_message?(message)
|
95
|
+
CURL_TIMEOUT_MESSAGES.any? { |curl_message| message.include?(curl_message) }
|
96
|
+
end
|
97
|
+
|
74
98
|
end
|
75
99
|
end
|
76
100
|
end
|
data/lib/faraday/adapter/test.rb
CHANGED
@@ -53,17 +53,17 @@ module Faraday
|
|
53
53
|
@stack.empty?
|
54
54
|
end
|
55
55
|
|
56
|
-
def match(request_method, path, headers, body)
|
56
|
+
def match(request_method, host, path, headers, body)
|
57
57
|
return false if !@stack.key?(request_method)
|
58
58
|
stack = @stack[request_method]
|
59
59
|
consumed = (@consumed[request_method] ||= [])
|
60
60
|
|
61
|
-
stub, meta = matches?(stack, path, headers, body)
|
61
|
+
stub, meta = matches?(stack, host, path, headers, body)
|
62
62
|
if stub
|
63
63
|
consumed << stack.delete(stub)
|
64
64
|
return stub, meta
|
65
65
|
end
|
66
|
-
matches?(consumed, path, headers, body)
|
66
|
+
matches?(consumed, host, path, headers, body)
|
67
67
|
end
|
68
68
|
|
69
69
|
def get(path, headers = {}, &block)
|
@@ -110,29 +110,35 @@ module Faraday
|
|
110
110
|
protected
|
111
111
|
|
112
112
|
def new_stub(request_method, path, headers = {}, body=nil, &block)
|
113
|
-
normalized_path =
|
114
|
-
|
113
|
+
normalized_path, host =
|
114
|
+
if path.is_a?(Regexp)
|
115
|
+
path
|
116
|
+
else
|
117
|
+
[Faraday::Utils.normalize_path(path), Faraday::Utils.URI(path).host]
|
118
|
+
end
|
119
|
+
|
120
|
+
(@stack[request_method] ||= []) << Stub.new(host, normalized_path, headers, body, block)
|
115
121
|
end
|
116
122
|
|
117
|
-
def matches?(stack, path, headers, body)
|
123
|
+
def matches?(stack, host, path, headers, body)
|
118
124
|
stack.each do |stub|
|
119
|
-
match_result, meta = stub.matches?(path, headers, body)
|
125
|
+
match_result, meta = stub.matches?(host, path, headers, body)
|
120
126
|
return stub, meta if match_result
|
121
127
|
end
|
122
128
|
nil
|
123
129
|
end
|
124
130
|
end
|
125
131
|
|
126
|
-
class Stub < Struct.new(:path, :params, :headers, :body, :block)
|
127
|
-
def initialize(full, headers, body, block)
|
132
|
+
class Stub < Struct.new(:host, :path, :params, :headers, :body, :block)
|
133
|
+
def initialize(host, full, headers, body, block)
|
128
134
|
path, query = full.respond_to?(:split) ? full.split("?") : full
|
129
135
|
params = query ?
|
130
136
|
Faraday::Utils.parse_nested_query(query) :
|
131
137
|
{}
|
132
|
-
super(path, params, headers, body, block)
|
138
|
+
super(host, path, params, headers, body, block)
|
133
139
|
end
|
134
140
|
|
135
|
-
def matches?(request_uri, request_headers, request_body)
|
141
|
+
def matches?(request_host, request_uri, request_headers, request_body)
|
136
142
|
request_path, request_query = request_uri.split('?')
|
137
143
|
request_params = request_query ?
|
138
144
|
Faraday::Utils.parse_nested_query(request_query) :
|
@@ -140,7 +146,8 @@ module Faraday
|
|
140
146
|
# meta is a hash use as carrier
|
141
147
|
# that will be yielded to consumer block
|
142
148
|
meta = {}
|
143
|
-
return
|
149
|
+
return (host.nil? || host == request_host) &&
|
150
|
+
path_match?(request_path, meta) &&
|
144
151
|
params_match?(request_params) &&
|
145
152
|
(body.to_s.size.zero? || request_body == body) &&
|
146
153
|
headers_match?(request_headers), meta
|
@@ -183,10 +190,11 @@ module Faraday
|
|
183
190
|
|
184
191
|
def call(env)
|
185
192
|
super
|
193
|
+
host = env[:url].host
|
186
194
|
normalized_path = Faraday::Utils.normalize_path(env[:url])
|
187
195
|
params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
|
188
196
|
|
189
|
-
stub, meta = stubs.match(env[:method], normalized_path, env.request_headers, env[:body])
|
197
|
+
stub, meta = stubs.match(env[:method], host, normalized_path, env.request_headers, env[:body])
|
190
198
|
if stub
|
191
199
|
env[:params] = (query = env[:url].query) ?
|
192
200
|
params_encoder.decode(query) : {}
|
@@ -1,123 +1,12 @@
|
|
1
1
|
module Faraday
|
2
2
|
class Adapter
|
3
|
+
# This class is just a stub, the real adapter is in https://github.com/philsturgeon/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb
|
3
4
|
class Typhoeus < Faraday::Adapter
|
4
|
-
|
5
|
-
|
6
|
-
def self.setup_parallel_manager(options = {})
|
7
|
-
options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
|
8
|
-
end
|
5
|
+
# Needs to define this method in order to support Typhoeus <= 1.3.0
|
6
|
+
def call; end
|
9
7
|
|
10
8
|
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
|
-
method = env[:method]
|
35
|
-
# For some reason, prevents Typhoeus from using "100-continue".
|
36
|
-
# We want this because Webrick 1.3.1 can't seem to handle it w/ PUT.
|
37
|
-
method = method.to_s.upcase if method == :put
|
38
|
-
|
39
|
-
req = ::Typhoeus::Request.new env[:url].to_s,
|
40
|
-
:method => method,
|
41
|
-
:body => env[:body],
|
42
|
-
:headers => env[:request_headers],
|
43
|
-
:disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
|
44
|
-
|
45
|
-
configure_ssl req, env
|
46
|
-
configure_proxy req, env
|
47
|
-
configure_timeout req, env
|
48
|
-
configure_socket req, env
|
49
|
-
|
50
|
-
req.on_complete do |resp|
|
51
|
-
if resp.timed_out?
|
52
|
-
if parallel?(env)
|
53
|
-
# TODO: error callback in async mode
|
54
|
-
else
|
55
|
-
raise Faraday::Error::TimeoutError, "request timed out"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
case resp.curl_return_code
|
60
|
-
when 0
|
61
|
-
# everything OK
|
62
|
-
when 7
|
63
|
-
raise Error::ConnectionFailed, resp.curl_error_message
|
64
|
-
when 60
|
65
|
-
raise Faraday::SSLError, resp.curl_error_message
|
66
|
-
else
|
67
|
-
raise Error::ClientError, resp.curl_error_message
|
68
|
-
end
|
69
|
-
|
70
|
-
save_response(env, resp.code, resp.body) do |response_headers|
|
71
|
-
response_headers.parse resp.headers
|
72
|
-
end
|
73
|
-
# in async mode, :response is initialized at this point
|
74
|
-
env[:response].finish(env) if parallel?(env)
|
75
|
-
end
|
76
|
-
|
77
|
-
req
|
78
|
-
end
|
79
|
-
|
80
|
-
def configure_ssl(req, env)
|
81
|
-
ssl = env[:ssl]
|
82
|
-
|
83
|
-
req.ssl_version = ssl[:version] if ssl[:version]
|
84
|
-
req.ssl_cert = ssl[:client_cert] if ssl[:client_cert]
|
85
|
-
req.ssl_key = ssl[:client_key] if ssl[:client_key]
|
86
|
-
req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
|
87
|
-
req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
|
88
|
-
end
|
89
|
-
|
90
|
-
def configure_proxy(req, env)
|
91
|
-
proxy = request_options(env)[:proxy]
|
92
|
-
return unless proxy
|
93
|
-
|
94
|
-
req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
|
95
|
-
|
96
|
-
if proxy[:user] && proxy[:password]
|
97
|
-
req.proxy_username = proxy[:user]
|
98
|
-
req.proxy_password = proxy[:password]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def configure_timeout(req, env)
|
103
|
-
env_req = request_options(env)
|
104
|
-
req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
|
105
|
-
req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
|
106
|
-
end
|
107
|
-
|
108
|
-
def configure_socket(req, env)
|
109
|
-
if bind = request_options(env)[:bind]
|
110
|
-
req.interface = bind[:host]
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def request_options(env)
|
115
|
-
env[:request]
|
116
|
-
end
|
117
|
-
|
118
|
-
def parallel?(env)
|
119
|
-
!!env[:parallel_manager]
|
120
|
-
end
|
9
|
+
dependency 'typhoeus/adapters/faraday'
|
121
10
|
end
|
122
11
|
end
|
123
12
|
end
|
data/lib/faraday/adapter.rb
CHANGED
data/lib/faraday/autoload.rb
CHANGED
@@ -53,9 +53,9 @@ module Faraday
|
|
53
53
|
autoload_all 'faraday/adapter',
|
54
54
|
:NetHttp => 'net_http',
|
55
55
|
:NetHttpPersistent => 'net_http_persistent',
|
56
|
-
:Typhoeus => 'typhoeus',
|
57
56
|
:EMSynchrony => 'em_synchrony',
|
58
57
|
:EMHttp => 'em_http',
|
58
|
+
:Typhoeus => 'typhoeus',
|
59
59
|
:Patron => 'patron',
|
60
60
|
:Excon => 'excon',
|
61
61
|
:Test => 'test',
|
data/lib/faraday/connection.rb
CHANGED
@@ -39,6 +39,9 @@ module Faraday
|
|
39
39
|
# Public: Sets the default parallel manager for this connection.
|
40
40
|
attr_writer :default_parallel_manager
|
41
41
|
|
42
|
+
# Public: Gets or Sets the Hash proxy options.
|
43
|
+
# attr_reader :proxy
|
44
|
+
|
42
45
|
# Public: Initializes a new Faraday::Connection.
|
43
46
|
#
|
44
47
|
# url - URI or String base URL to use as a prefix for all
|
@@ -57,7 +60,7 @@ module Faraday
|
|
57
60
|
def initialize(url = nil, options = nil)
|
58
61
|
options = ConnectionOptions.from(options)
|
59
62
|
|
60
|
-
if url.is_a?(Hash)
|
63
|
+
if url.is_a?(Hash) || url.is_a?(ConnectionOptions)
|
61
64
|
options = options.merge(url)
|
62
65
|
url = options.url
|
63
66
|
end
|
@@ -79,23 +82,9 @@ module Faraday
|
|
79
82
|
@params.update(options.params) if options.params
|
80
83
|
@headers.update(options.headers) if options.headers
|
81
84
|
|
82
|
-
@
|
83
|
-
proxy(options.
|
84
|
-
|
85
|
-
if URI.parse("").respond_to?(:find_proxy)
|
86
|
-
case url
|
87
|
-
when String
|
88
|
-
uri = URI.parse(url).find_proxy
|
89
|
-
when URI
|
90
|
-
uri = url.find_proxy
|
91
|
-
when nil
|
92
|
-
uri = find_default_proxy
|
93
|
-
end
|
94
|
-
else
|
95
|
-
uri = find_default_proxy
|
96
|
-
end
|
97
|
-
uri
|
98
|
-
})
|
85
|
+
@manual_proxy = !!options.proxy
|
86
|
+
@proxy = options.proxy ? ProxyOptions.from(options.proxy) : proxy_from_env(url)
|
87
|
+
@temp_proxy = @proxy
|
99
88
|
|
100
89
|
yield(self) if block_given?
|
101
90
|
|
@@ -292,9 +281,17 @@ module Faraday
|
|
292
281
|
# Public: Gets or Sets the Hash proxy options.
|
293
282
|
def proxy(arg = nil)
|
294
283
|
return @proxy if arg.nil?
|
284
|
+
warn 'Warning: use of proxy(new_value) to set connection proxy have been DEPRECATED and will be removed in Faraday 1.0'
|
285
|
+
@manual_proxy = true
|
295
286
|
@proxy = ProxyOptions.from(arg)
|
296
287
|
end
|
297
288
|
|
289
|
+
# Public: Sets the Hash proxy options.
|
290
|
+
def proxy=(new_value)
|
291
|
+
@manual_proxy = true
|
292
|
+
@proxy = new_value ? ProxyOptions.from(new_value) : nil
|
293
|
+
end
|
294
|
+
|
298
295
|
def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port=
|
299
296
|
def_delegator :url_prefix, :path, :path_prefix
|
300
297
|
|
@@ -313,7 +310,7 @@ module Faraday
|
|
313
310
|
#
|
314
311
|
# conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
|
315
312
|
#
|
316
|
-
# Returns the parsed URI from
|
313
|
+
# Returns the parsed URI from the given input..
|
317
314
|
def url_prefix=(url, encoder = nil)
|
318
315
|
uri = @url_prefix = Utils.URI(url)
|
319
316
|
self.path_prefix = uri.path
|
@@ -376,7 +373,11 @@ module Faraday
|
|
376
373
|
raise ArgumentError, "unknown http method: #{method}"
|
377
374
|
end
|
378
375
|
|
376
|
+
# Resets temp_proxy
|
377
|
+
@temp_proxy = proxy_for_request(url)
|
378
|
+
|
379
379
|
request = build_request(method) do |req|
|
380
|
+
req.options = req.options.merge(:proxy => @temp_proxy)
|
380
381
|
req.url(url) if url
|
381
382
|
req.headers.update(headers) if headers
|
382
383
|
req.body = body if body
|
@@ -393,7 +394,7 @@ module Faraday
|
|
393
394
|
Request.create(method) do |req|
|
394
395
|
req.params = self.params.dup
|
395
396
|
req.headers = self.headers.dup
|
396
|
-
req.options = self.options
|
397
|
+
req.options = self.options
|
397
398
|
yield(req) if block_given?
|
398
399
|
end
|
399
400
|
end
|
@@ -443,13 +444,41 @@ module Faraday
|
|
443
444
|
headers[Faraday::Request::Authorization::KEY] = header
|
444
445
|
end
|
445
446
|
|
447
|
+
def proxy_from_env(url)
|
448
|
+
return if Faraday.ignore_env_proxy
|
449
|
+
uri = nil
|
450
|
+
if URI.parse('').respond_to?(:find_proxy)
|
451
|
+
case url
|
452
|
+
when String
|
453
|
+
uri = Utils.URI(url)
|
454
|
+
uri = URI.parse("#{uri.scheme}://#{uri.hostname}").find_proxy
|
455
|
+
when URI
|
456
|
+
uri = url.find_proxy
|
457
|
+
when nil
|
458
|
+
uri = find_default_proxy
|
459
|
+
end
|
460
|
+
else
|
461
|
+
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
462
|
+
uri = find_default_proxy
|
463
|
+
end
|
464
|
+
ProxyOptions.from(uri) if uri
|
465
|
+
end
|
466
|
+
|
446
467
|
def find_default_proxy
|
447
|
-
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
448
468
|
uri = ENV['http_proxy']
|
449
469
|
if uri && !uri.empty?
|
450
470
|
uri = 'http://' + uri if uri !~ /^http/i
|
451
471
|
uri
|
452
472
|
end
|
453
473
|
end
|
474
|
+
|
475
|
+
def proxy_for_request(url)
|
476
|
+
return self.proxy if @manual_proxy
|
477
|
+
if url && Utils.URI(url).absolute?
|
478
|
+
proxy_from_env(url)
|
479
|
+
else
|
480
|
+
self.proxy
|
481
|
+
end
|
482
|
+
end
|
454
483
|
end
|
455
484
|
end
|
data/lib/faraday/error.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
module Faraday
|
2
2
|
class Error < StandardError; end
|
3
|
-
class MissingDependency < Error; end
|
4
3
|
|
5
4
|
class ClientError < Error
|
6
|
-
attr_reader :response
|
5
|
+
attr_reader :response, :wrapped_exception
|
7
6
|
|
8
7
|
def initialize(ex, response = nil)
|
9
8
|
@wrapped_exception = nil
|
@@ -56,8 +55,12 @@ module Faraday
|
|
56
55
|
class SSLError < ClientError
|
57
56
|
end
|
58
57
|
|
59
|
-
|
60
|
-
|
58
|
+
class RetriableResponse < ClientError; end
|
59
|
+
|
60
|
+
[:ClientError, :ConnectionFailed, :ResourceNotFound,
|
61
|
+
:ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
|
61
62
|
Error.const_set(const, Faraday.const_get(const))
|
62
63
|
end
|
64
|
+
|
65
|
+
|
63
66
|
end
|
data/lib/faraday/options.rb
CHANGED
@@ -49,7 +49,7 @@ module Faraday
|
|
49
49
|
other.each do |key, other_value|
|
50
50
|
self_value = self.send(key)
|
51
51
|
sub_options = self.class.options_for(key)
|
52
|
-
new_value = sub_options ? self_value.merge(other_value) : other_value
|
52
|
+
new_value = (self_value && sub_options && other_value) ? self_value.merge(other_value) : other_value
|
53
53
|
self.send("#{key}=", new_value) unless new_value.nil?
|
54
54
|
end
|
55
55
|
self
|
@@ -243,8 +243,8 @@ module Faraday
|
|
243
243
|
super(value)
|
244
244
|
end
|
245
245
|
|
246
|
-
memoized(:user) { uri.user && Utils.unescape(uri.user) }
|
247
|
-
memoized(:password) { uri.password && Utils.unescape(uri.password) }
|
246
|
+
memoized(:user) { uri && uri.user && Utils.unescape(uri.user) }
|
247
|
+
memoized(:password) { uri && uri.password && Utils.unescape(uri.password) }
|
248
248
|
end
|
249
249
|
|
250
250
|
class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
|
data/lib/faraday/rack_builder.rb
CHANGED
@@ -84,6 +84,7 @@ module Faraday
|
|
84
84
|
use_symbol(Faraday::Middleware, klass, *args, &block)
|
85
85
|
else
|
86
86
|
raise_if_locked
|
87
|
+
warn_middleware_after_adapter if adapter_set?
|
87
88
|
@handlers << self.class::Handler.new(klass, *args, &block)
|
88
89
|
end
|
89
90
|
end
|
@@ -105,6 +106,7 @@ module Faraday
|
|
105
106
|
def insert(index, *args, &block)
|
106
107
|
raise_if_locked
|
107
108
|
index = assert_index(index)
|
109
|
+
warn_middleware_after_adapter if inserting_after_adapter?(index)
|
108
110
|
handler = self.class::Handler.new(*args, &block)
|
109
111
|
@handlers.insert(index, handler)
|
110
112
|
end
|
@@ -136,6 +138,8 @@ module Faraday
|
|
136
138
|
#
|
137
139
|
# Returns a Faraday::Response.
|
138
140
|
def build_response(connection, request)
|
141
|
+
warn 'WARNING: No adapter was configured for this request' unless adapter_set?
|
142
|
+
|
139
143
|
app.call(build_env(connection, request))
|
140
144
|
end
|
141
145
|
|
@@ -200,6 +204,26 @@ module Faraday
|
|
200
204
|
raise StackLocked, "can't modify middleware stack after making a request" if locked?
|
201
205
|
end
|
202
206
|
|
207
|
+
def warn_middleware_after_adapter
|
208
|
+
warn "WARNING: Unexpected middleware set after the adapter. " \
|
209
|
+
"This won't be supported from Faraday 1.0."
|
210
|
+
end
|
211
|
+
|
212
|
+
def adapter_set?
|
213
|
+
@handlers.any? { |handler| is_adapter?(handler) }
|
214
|
+
end
|
215
|
+
|
216
|
+
def inserting_after_adapter?(index)
|
217
|
+
adapter_index = @handlers.find_index { |handler| is_adapter?(handler) }
|
218
|
+
return false if adapter_index.nil?
|
219
|
+
|
220
|
+
index > adapter_index
|
221
|
+
end
|
222
|
+
|
223
|
+
def is_adapter?(handler)
|
224
|
+
handler.klass.ancestors.include? Faraday::Adapter
|
225
|
+
end
|
226
|
+
|
203
227
|
def use_symbol(mod, key, *args, &block)
|
204
228
|
use(mod.lookup_middleware(key), *args, &block)
|
205
229
|
end
|
@@ -23,7 +23,9 @@ module Faraday
|
|
23
23
|
IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]
|
24
24
|
|
25
25
|
class Options < Faraday::Options.new(:max, :interval, :max_interval, :interval_randomness,
|
26
|
-
:backoff_factor, :exceptions, :methods, :retry_if
|
26
|
+
:backoff_factor, :exceptions, :methods, :retry_if, :retry_block,
|
27
|
+
:retry_statuses)
|
28
|
+
|
27
29
|
DEFAULT_CHECK = lambda { |env,exception| false }
|
28
30
|
|
29
31
|
def self.from(value)
|
@@ -56,7 +58,8 @@ module Faraday
|
|
56
58
|
|
57
59
|
def exceptions
|
58
60
|
Array(self[:exceptions] ||= [Errno::ETIMEDOUT, 'Timeout::Error',
|
59
|
-
Error::TimeoutError
|
61
|
+
Error::TimeoutError,
|
62
|
+
Faraday::Error::RetriableResponse])
|
60
63
|
end
|
61
64
|
|
62
65
|
def methods
|
@@ -67,6 +70,13 @@ module Faraday
|
|
67
70
|
self[:retry_if] ||= DEFAULT_CHECK
|
68
71
|
end
|
69
72
|
|
73
|
+
def retry_block
|
74
|
+
self[:retry_block] ||= Proc.new {}
|
75
|
+
end
|
76
|
+
|
77
|
+
def retry_statuses
|
78
|
+
Array(self[:retry_statuses] ||= [])
|
79
|
+
end
|
70
80
|
end
|
71
81
|
|
72
82
|
# Public: Initialize middleware
|
@@ -83,8 +93,8 @@ module Faraday
|
|
83
93
|
# (default: 1)
|
84
94
|
# exceptions - The list of exceptions to handle. Exceptions can be
|
85
95
|
# given as Class, Module, or String. (default:
|
86
|
-
# [Errno::ETIMEDOUT, Timeout::Error,
|
87
|
-
# Error::TimeoutError])
|
96
|
+
# [Errno::ETIMEDOUT, 'Timeout::Error',
|
97
|
+
# Error::TimeoutError, Faraday::Error::RetriableResponse])
|
88
98
|
# methods - A list of HTTP methods to retry without calling retry_if. Pass
|
89
99
|
# an empty Array to call retry_if for all exceptions.
|
90
100
|
# (defaults to the idempotent HTTP methods in IDEMPOTENT_METHODS)
|
@@ -94,18 +104,21 @@ module Faraday
|
|
94
104
|
# if the exception produced is non-recoverable or if the
|
95
105
|
# the HTTP method called is not idempotent.
|
96
106
|
# (defaults to return false)
|
107
|
+
# retry_block - block that is executed after every retry. Request environment, middleware options,
|
108
|
+
# current number of retries and the exception is passed to the block as parameters.
|
97
109
|
def initialize(app, options = nil)
|
98
110
|
super(app)
|
99
111
|
@options = Options.from(options)
|
100
112
|
@errmatch = build_exception_matcher(@options.exceptions)
|
101
113
|
end
|
102
114
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
115
|
+
def calculate_sleep_amount(retries, env)
|
116
|
+
retry_after = calculate_retry_after(env)
|
117
|
+
retry_interval = calculate_retry_interval(retries)
|
118
|
+
|
119
|
+
return if retry_after && retry_after > @options.max_interval
|
120
|
+
|
121
|
+
retry_after && retry_after >= retry_interval ? retry_after : retry_interval
|
109
122
|
end
|
110
123
|
|
111
124
|
def call(env)
|
@@ -113,15 +126,25 @@ module Faraday
|
|
113
126
|
request_body = env[:body]
|
114
127
|
begin
|
115
128
|
env[:body] = request_body # after failure env[:body] is set to the response body
|
116
|
-
@app.call(env)
|
129
|
+
@app.call(env).tap do |resp|
|
130
|
+
raise Faraday::Error::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
|
131
|
+
end
|
117
132
|
rescue @errmatch => exception
|
118
133
|
if retries > 0 && retry_request?(env, exception)
|
119
134
|
retries -= 1
|
120
135
|
rewind_files(request_body)
|
121
|
-
|
122
|
-
|
136
|
+
@options.retry_block.call(env, @options, retries, exception)
|
137
|
+
if (sleep_amount = calculate_sleep_amount(retries + 1, env))
|
138
|
+
sleep sleep_amount
|
139
|
+
retry
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
if exception.is_a?(Faraday::Error::RetriableResponse)
|
144
|
+
exception.response
|
145
|
+
else
|
146
|
+
raise
|
123
147
|
end
|
124
|
-
raise
|
125
148
|
end
|
126
149
|
end
|
127
150
|
|
@@ -151,13 +174,38 @@ module Faraday
|
|
151
174
|
@options.methods.include?(env[:method]) || @options.retry_if.call(env, exception)
|
152
175
|
end
|
153
176
|
|
154
|
-
def rewind_files(
|
155
|
-
|
177
|
+
def rewind_files(body)
|
178
|
+
return unless body.is_a?(Hash)
|
179
|
+
body.each do |_, value|
|
156
180
|
if value.is_a? UploadIO
|
157
181
|
value.rewind
|
158
182
|
end
|
159
183
|
end
|
160
184
|
end
|
161
185
|
|
186
|
+
# MDN spec for Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
187
|
+
def calculate_retry_after(env)
|
188
|
+
response_headers = env[:response_headers]
|
189
|
+
return unless response_headers
|
190
|
+
|
191
|
+
retry_after_value = env[:response_headers]["Retry-After"]
|
192
|
+
|
193
|
+
# Try to parse date from the header value
|
194
|
+
begin
|
195
|
+
datetime = DateTime.rfc2822(retry_after_value)
|
196
|
+
datetime.to_time - Time.now.utc
|
197
|
+
rescue ArgumentError
|
198
|
+
retry_after_value.to_f
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def calculate_retry_interval(retries)
|
203
|
+
retry_index = @options.max - retries
|
204
|
+
current_interval = @options.interval * (@options.backoff_factor ** retry_index)
|
205
|
+
current_interval = [current_interval, @options.max_interval].min
|
206
|
+
random_interval = rand * @options.interval_randomness.to_f * @options.interval
|
207
|
+
|
208
|
+
current_interval + random_interval
|
209
|
+
end
|
162
210
|
end
|
163
211
|
end
|
@@ -20,14 +20,14 @@ module Faraday
|
|
20
20
|
def_delegators :@logger, :debug, :info, :warn, :error, :fatal
|
21
21
|
|
22
22
|
def call(env)
|
23
|
-
info "#{env.method} #{apply_filters(env.url.to_s)}"
|
23
|
+
info('request') { "#{env.method.upcase} #{apply_filters(env.url.to_s)}" }
|
24
24
|
debug('request') { apply_filters( dump_headers env.request_headers ) } if log_headers?(:request)
|
25
25
|
debug('request') { apply_filters( dump_body(env[:body]) ) } if env[:body] && log_body?(:request)
|
26
26
|
super
|
27
27
|
end
|
28
28
|
|
29
29
|
def on_complete(env)
|
30
|
-
info('
|
30
|
+
info('response') { "Status #{env.status.to_s}" }
|
31
31
|
debug('response') { apply_filters( dump_headers env.response_headers ) } if log_headers?(:response)
|
32
32
|
debug('response') { apply_filters( dump_body env[:body] ) } if env[:body] && log_body?(:response)
|
33
33
|
end
|
data/lib/faraday/utils.rb
CHANGED
@@ -10,12 +10,22 @@ module Faraday
|
|
10
10
|
new(value)
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.allocate
|
14
|
+
new_self = super
|
15
|
+
new_self.initialize_names
|
16
|
+
new_self
|
17
|
+
end
|
18
|
+
|
13
19
|
def initialize(hash = nil)
|
14
20
|
super()
|
15
21
|
@names = {}
|
16
22
|
self.update(hash || {})
|
17
23
|
end
|
18
24
|
|
25
|
+
def initialize_names
|
26
|
+
@names = {}
|
27
|
+
end
|
28
|
+
|
19
29
|
# on dup/clone, we need to duplicate @names hash
|
20
30
|
def initialize_copy(other)
|
21
31
|
super
|
@@ -95,7 +105,14 @@ module Faraday
|
|
95
105
|
|
96
106
|
def parse(header_string)
|
97
107
|
return unless header_string && !header_string.empty?
|
98
|
-
|
108
|
+
|
109
|
+
headers = header_string.split(/\r\n/)
|
110
|
+
|
111
|
+
# Find the last set of response headers.
|
112
|
+
start_index = headers.rindex { |x| x.match(/^HTTP\//) } || 0
|
113
|
+
last_response = headers.slice(start_index, headers.size)
|
114
|
+
|
115
|
+
last_response.
|
99
116
|
tap { |a| a.shift if a.first.index('HTTP/') == 0 }. # drop the HTTP status line
|
100
117
|
map { |h| h.split(/:\s*/, 2) }.reject { |p| p[0].nil? }. # split key and value, ignore blank lines
|
101
118
|
each { |key, value|
|
@@ -108,14 +125,6 @@ module Faraday
|
|
108
125
|
}
|
109
126
|
end
|
110
127
|
|
111
|
-
def init_with(coder)
|
112
|
-
@names = coder['names']
|
113
|
-
end
|
114
|
-
|
115
|
-
def encode_with(coder)
|
116
|
-
coder['names'] = @names
|
117
|
-
end
|
118
|
-
|
119
128
|
protected
|
120
129
|
|
121
130
|
def names
|
data/lib/faraday.rb
CHANGED
@@ -14,7 +14,7 @@ require 'forwardable'
|
|
14
14
|
# conn.get '/'
|
15
15
|
#
|
16
16
|
module Faraday
|
17
|
-
VERSION = "0.
|
17
|
+
VERSION = "0.15.0"
|
18
18
|
|
19
19
|
class << self
|
20
20
|
# Public: Gets or sets the root path that Faraday is being loaded from.
|
@@ -34,6 +34,9 @@ module Faraday
|
|
34
34
|
# Faraday.get "https://faraday.com"
|
35
35
|
attr_writer :default_connection
|
36
36
|
|
37
|
+
# Public: Tells faraday to ignore the environment proxy (http_proxy).
|
38
|
+
attr_accessor :ignore_env_proxy
|
39
|
+
|
37
40
|
# Public: Initializes a new Faraday::Connection.
|
38
41
|
#
|
39
42
|
# url - The optional String base URL to use as a prefix for all
|
@@ -101,6 +104,7 @@ module Faraday
|
|
101
104
|
end
|
102
105
|
end
|
103
106
|
|
107
|
+
self.ignore_env_proxy = false
|
104
108
|
self.root_path = File.expand_path "..", __FILE__
|
105
109
|
self.lib_path = File.expand_path "../faraday", __FILE__
|
106
110
|
self.default_adapter = :net_http
|
@@ -109,7 +113,7 @@ module Faraday
|
|
109
113
|
#
|
110
114
|
# Returns a Faraday::Connection, configured with the #default_adapter.
|
111
115
|
def self.default_connection
|
112
|
-
@default_connection ||= Connection.new
|
116
|
+
@default_connection ||= Connection.new(default_connection_options)
|
113
117
|
end
|
114
118
|
|
115
119
|
# Gets the default connection options used when calling Faraday#new.
|
@@ -121,6 +125,7 @@ module Faraday
|
|
121
125
|
|
122
126
|
# Public: Sets the default options used when calling Faraday#new.
|
123
127
|
def self.default_connection_options=(options)
|
128
|
+
@default_connection = nil
|
124
129
|
@default_connection_options = ConnectionOptions.from(options)
|
125
130
|
end
|
126
131
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faraday
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Olson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multipart-post
|
@@ -92,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
92
|
version: '0'
|
93
93
|
requirements: []
|
94
94
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.
|
95
|
+
rubygems_version: 2.7.6
|
96
96
|
signing_key:
|
97
97
|
specification_version: 4
|
98
98
|
summary: HTTP/REST API client library.
|