faraday 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/faraday.rb +1 -1
- data/lib/faraday/adapter.rb +2 -0
- data/lib/faraday/adapter/net_http.rb +2 -0
- data/lib/faraday/adapter/net_http_persistent.rb +19 -10
- data/lib/faraday/error.rb +6 -3
- data/lib/faraday/request/retry.rb +61 -14
- data/lib/faraday/response/logger.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
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/README.md
CHANGED
@@ -69,7 +69,7 @@ conn = Faraday.new(:url => 'http://sushi.com/api_key=s3cr3t') do |faraday|
|
|
69
69
|
end
|
70
70
|
```
|
71
71
|
|
72
|
-
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:
|
73
73
|
|
74
74
|
```ruby
|
75
75
|
## GET ##
|
data/lib/faraday.rb
CHANGED
data/lib/faraday/adapter.rb
CHANGED
@@ -1,13 +1,23 @@
|
|
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)
|
11
21
|
proxy_uri = nil
|
12
22
|
if (proxy = env[:request][:proxy])
|
13
23
|
proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
|
@@ -18,12 +28,7 @@ module Faraday
|
|
18
28
|
define_method(:password) { proxy[:password] }
|
19
29
|
end if proxy[:user]
|
20
30
|
end
|
21
|
-
|
22
|
-
if Net::HTTP::Persistent.instance_method(:initialize).parameters.first == [:key, :name]
|
23
|
-
Net::HTTP::Persistent.new(name: 'Faraday', proxy: proxy_uri)
|
24
|
-
else
|
25
|
-
Net::HTTP::Persistent.new('Faraday', proxy_uri)
|
26
|
-
end
|
31
|
+
proxy_uri
|
27
32
|
end
|
28
33
|
|
29
34
|
def perform_request(http, env)
|
@@ -49,6 +54,10 @@ module Faraday
|
|
49
54
|
http.ca_file = ssl[:ca_file] if ssl[:ca_file]
|
50
55
|
http.ssl_version = ssl[:version] if ssl[:version]
|
51
56
|
end
|
57
|
+
|
58
|
+
def cached_connection(url, proxy_uri)
|
59
|
+
(@cached_connection ||= {})[[url.scheme, url.host, url.port, proxy_uri]] ||= yield
|
60
|
+
end
|
52
61
|
end
|
53
62
|
end
|
54
63
|
end
|
data/lib/faraday/error.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Faraday
|
2
2
|
class Error < StandardError; end
|
3
|
-
class MissingDependency < Error; end
|
4
3
|
|
5
4
|
class ClientError < Error
|
6
5
|
attr_reader :response, :wrapped_exception
|
@@ -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
|
@@ -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
|
|
@@ -160,5 +183,29 @@ module Faraday
|
|
160
183
|
end
|
161
184
|
end
|
162
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
|
163
210
|
end
|
164
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
|
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: 2018-
|
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.7.
|
95
|
+
rubygems_version: 2.7.6
|
96
96
|
signing_key:
|
97
97
|
specification_version: 4
|
98
98
|
summary: HTTP/REST API client library.
|