faraday 0.16.1 → 0.17.4
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/CHANGELOG.md +232 -0
- data/LICENSE.md +1 -1
- data/README.md +358 -18
- data/Rakefile +13 -0
- data/lib/faraday.rb +174 -93
- data/lib/faraday/adapter.rb +22 -36
- data/lib/faraday/adapter/em_http.rb +97 -140
- data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
- data/lib/faraday/adapter/em_synchrony.rb +60 -104
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
- data/lib/faraday/adapter/excon.rb +55 -100
- data/lib/faraday/adapter/httpclient.rb +39 -61
- data/lib/faraday/adapter/net_http.rb +51 -103
- data/lib/faraday/adapter/net_http_persistent.rb +28 -49
- data/lib/faraday/adapter/patron.rb +35 -54
- data/lib/faraday/adapter/rack.rb +12 -28
- data/lib/faraday/adapter/test.rb +53 -86
- data/lib/faraday/adapter/typhoeus.rb +1 -4
- data/lib/faraday/autoload.rb +36 -47
- data/lib/faraday/connection.rb +179 -321
- data/lib/faraday/deprecate.rb +109 -0
- data/lib/faraday/error.rb +72 -28
- data/lib/faraday/middleware.rb +28 -4
- data/lib/faraday/options.rb +183 -32
- data/lib/faraday/parameters.rb +197 -4
- data/lib/faraday/rack_builder.rb +55 -66
- data/lib/faraday/request.rb +36 -68
- data/lib/faraday/request/authorization.rb +30 -42
- data/lib/faraday/request/basic_authentication.rb +7 -14
- data/lib/faraday/request/instrumentation.rb +27 -45
- data/lib/faraday/request/multipart.rb +48 -79
- data/lib/faraday/request/retry.rb +171 -197
- data/lib/faraday/request/token_authentication.rb +10 -15
- data/lib/faraday/request/url_encoded.rb +23 -41
- data/lib/faraday/response.rb +13 -20
- data/lib/faraday/response/logger.rb +69 -22
- data/lib/faraday/response/raise_error.rb +18 -36
- data/lib/faraday/upload_io.rb +67 -0
- data/lib/faraday/utils.rb +245 -28
- data/spec/faraday/deprecate_spec.rb +147 -0
- data/spec/faraday/error_spec.rb +102 -0
- data/spec/faraday/response/raise_error_spec.rb +106 -0
- data/spec/spec_helper.rb +105 -0
- data/test/adapters/default_test.rb +14 -0
- data/test/adapters/em_http_test.rb +30 -0
- data/test/adapters/em_synchrony_test.rb +32 -0
- data/test/adapters/excon_test.rb +30 -0
- data/test/adapters/httpclient_test.rb +34 -0
- data/test/adapters/integration.rb +263 -0
- data/test/adapters/logger_test.rb +136 -0
- data/test/adapters/net_http_persistent_test.rb +114 -0
- data/test/adapters/net_http_test.rb +79 -0
- data/test/adapters/patron_test.rb +40 -0
- data/test/adapters/rack_test.rb +38 -0
- data/test/adapters/test_middleware_test.rb +157 -0
- data/test/adapters/typhoeus_test.rb +38 -0
- data/test/authentication_middleware_test.rb +65 -0
- data/test/composite_read_io_test.rb +109 -0
- data/test/connection_test.rb +738 -0
- data/test/env_test.rb +268 -0
- data/test/helper.rb +75 -0
- data/test/live_server.rb +67 -0
- data/test/middleware/instrumentation_test.rb +88 -0
- data/test/middleware/retry_test.rb +282 -0
- data/test/middleware_stack_test.rb +260 -0
- data/test/multibyte.txt +1 -0
- data/test/options_test.rb +333 -0
- data/test/parameters_test.rb +157 -0
- data/test/request_middleware_test.rb +126 -0
- data/test/response_middleware_test.rb +72 -0
- data/test/strawberry.rb +2 -0
- data/test/utils_test.rb +98 -0
- metadata +50 -26
- data/lib/faraday/adapter_registry.rb +0 -28
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/deprecated_constant.rb +0 -53
- data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
- data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/logging/formatter.rb +0 -92
- data/lib/faraday/middleware_registry.rb +0 -129
- data/lib/faraday/options/connection_options.rb +0 -22
- data/lib/faraday/options/env.rb +0 -181
- data/lib/faraday/options/proxy_options.rb +0 -28
- data/lib/faraday/options/request_options.rb +0 -21
- data/lib/faraday/options/ssl_options.rb +0 -59
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/utils/headers.rb +0 -139
- data/lib/faraday/utils/params_hash.rb +0 -61
- data/spec/external_adapters/faraday_specs_setup.rb +0 -14
data/Rakefile
ADDED
data/lib/faraday.rb
CHANGED
@@ -1,153 +1,128 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'thread'
|
3
2
|
require 'cgi'
|
4
3
|
require 'set'
|
5
4
|
require 'forwardable'
|
6
|
-
require 'faraday/middleware_registry'
|
7
|
-
require 'faraday/dependency_loader'
|
8
5
|
|
9
|
-
# This is the main namespace for Faraday.
|
6
|
+
# Public: This is the main namespace for Faraday. You can either use it to
|
7
|
+
# create Faraday::Connection objects, or access it directly.
|
10
8
|
#
|
11
|
-
#
|
12
|
-
# methods to use directly.
|
9
|
+
# Examples
|
13
10
|
#
|
14
|
-
# @example Helpful class methods for easy usage
|
15
11
|
# Faraday.get "http://faraday.com"
|
16
12
|
#
|
17
|
-
# @example Helpful class method `.new` to create {Connection} objects.
|
18
13
|
# conn = Faraday.new "http://faraday.com"
|
19
14
|
# conn.get '/'
|
20
15
|
#
|
21
16
|
module Faraday
|
22
|
-
VERSION =
|
23
|
-
METHODS_WITH_QUERY = %w[get head delete connect trace].freeze
|
24
|
-
METHODS_WITH_BODY = %w[post put patch].freeze
|
17
|
+
VERSION = "0.17.4"
|
25
18
|
|
26
19
|
class << self
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# This is the root from where the libraries are auto-loaded.
|
30
|
-
#
|
31
|
-
# @return [String]
|
20
|
+
# Public: Gets or sets the root path that Faraday is being loaded from.
|
21
|
+
# This is the root from where the libraries are auto-loaded from.
|
32
22
|
attr_accessor :root_path
|
33
23
|
|
34
|
-
# Gets or sets the path that the Faraday libs are loaded from.
|
35
|
-
# @return [String]
|
24
|
+
# Public: Gets or sets the path that the Faraday libs are loaded from.
|
36
25
|
attr_accessor :lib_path
|
37
26
|
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# for the default {Faraday::Connection}. Defaults to `:net_http`.
|
41
|
-
# @return [Symbol] the default adapter
|
42
|
-
# @overload default_adapter=(adapter)
|
43
|
-
# Updates default adapter while resetting {.default_connection}.
|
44
|
-
# @return [Symbol] the new default_adapter.
|
27
|
+
# Public: Gets or sets the Symbol key identifying a default Adapter to use
|
28
|
+
# for the default Faraday::Connection.
|
45
29
|
attr_reader :default_adapter
|
46
30
|
|
47
|
-
#
|
31
|
+
# Public: Sets the default Faraday::Connection for simple scripts that
|
32
|
+
# access the Faraday constant directly.
|
33
|
+
#
|
34
|
+
# Faraday.get "https://faraday.com"
|
48
35
|
attr_writer :default_connection
|
49
36
|
|
50
|
-
# Tells
|
51
|
-
# Defaults to `false`.
|
52
|
-
# @return [Boolean]
|
37
|
+
# Public: Tells faraday to ignore the environment proxy (http_proxy).
|
53
38
|
attr_accessor :ignore_env_proxy
|
54
39
|
|
55
|
-
# Initializes a new
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
40
|
+
# Public: Initializes a new Faraday::Connection.
|
41
|
+
#
|
42
|
+
# url - The optional String base URL to use as a prefix for all
|
43
|
+
# requests. Can also be the options Hash.
|
44
|
+
# options - The optional Hash used to configure this Faraday::Connection.
|
45
|
+
# Any of these values will be set on every request made, unless
|
46
|
+
# overridden for a specific request.
|
47
|
+
# :url - String base URL.
|
48
|
+
# :params - Hash of URI query unencoded key/value pairs.
|
49
|
+
# :headers - Hash of unencoded HTTP header key/value pairs.
|
50
|
+
# :request - Hash of request options.
|
51
|
+
# :ssl - Hash of SSL options.
|
52
|
+
# :proxy - Hash of Proxy options.
|
53
|
+
#
|
54
|
+
# Examples
|
55
|
+
#
|
71
56
|
# Faraday.new 'http://faraday.com'
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
# #
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
def new(url = nil, options =
|
83
|
-
options = default_connection_options.merge(options)
|
57
|
+
#
|
58
|
+
# # http://faraday.com?page=1
|
59
|
+
# Faraday.new 'http://faraday.com', :params => {:page => 1}
|
60
|
+
#
|
61
|
+
# # same
|
62
|
+
#
|
63
|
+
# Faraday.new :url => 'http://faraday.com',
|
64
|
+
# :params => {:page => 1}
|
65
|
+
#
|
66
|
+
# Returns a Faraday::Connection.
|
67
|
+
def new(url = nil, options = nil, &block)
|
68
|
+
options = options ? default_connection_options.merge(options) : default_connection_options
|
84
69
|
Faraday::Connection.new(url, options, &block)
|
85
70
|
end
|
86
71
|
|
87
|
-
# @private
|
88
72
|
# Internal: Requires internal Faraday libraries.
|
89
73
|
#
|
90
|
-
#
|
91
|
-
#
|
74
|
+
# *libs - One or more relative String names to Faraday classes.
|
75
|
+
#
|
76
|
+
# Returns nothing.
|
92
77
|
def require_libs(*libs)
|
93
78
|
libs.each do |lib|
|
94
79
|
require "#{lib_path}/#{lib}"
|
95
80
|
end
|
96
81
|
end
|
97
82
|
|
98
|
-
|
99
|
-
|
100
|
-
#
|
83
|
+
# Public: Updates default adapter while resetting
|
84
|
+
# #default_connection.
|
85
|
+
#
|
86
|
+
# Returns the new default_adapter.
|
101
87
|
def default_adapter=(adapter)
|
102
88
|
@default_connection = nil
|
103
89
|
@default_adapter = adapter
|
104
90
|
end
|
105
91
|
|
106
|
-
|
92
|
+
alias require_lib require_libs
|
93
|
+
|
94
|
+
def respond_to?(symbol, include_private = false)
|
107
95
|
default_connection.respond_to?(symbol, include_private) || super
|
108
96
|
end
|
109
97
|
|
110
|
-
|
111
|
-
|
98
|
+
private
|
112
99
|
# Internal: Proxies method calls on the Faraday constant to
|
113
|
-
#
|
100
|
+
# #default_connection.
|
114
101
|
def method_missing(name, *args, &block)
|
115
|
-
|
116
|
-
default_connection.send(name, *args, &block)
|
117
|
-
else
|
118
|
-
super
|
119
|
-
end
|
102
|
+
default_connection.send(name, *args, &block)
|
120
103
|
end
|
121
104
|
end
|
122
105
|
|
123
106
|
self.ignore_env_proxy = false
|
124
|
-
self.root_path = File.expand_path
|
125
|
-
self.lib_path = File.expand_path
|
107
|
+
self.root_path = File.expand_path "..", __FILE__
|
108
|
+
self.lib_path = File.expand_path "../faraday", __FILE__
|
126
109
|
self.default_adapter = :net_http
|
127
110
|
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
# the default_adapter.
|
132
|
-
# @overload default_connection=(connection)
|
133
|
-
# @param connection [Faraday::Connection]
|
134
|
-
# Sets the default {Faraday::Connection} for simple scripts that
|
135
|
-
# access the Faraday constant directly, such as
|
136
|
-
# <code>Faraday.get "https://faraday.com"</code>.
|
111
|
+
# Gets the default connection used for simple scripts.
|
112
|
+
#
|
113
|
+
# Returns a Faraday::Connection, configured with the #default_adapter.
|
137
114
|
def self.default_connection
|
138
115
|
@default_connection ||= Connection.new(default_connection_options)
|
139
116
|
end
|
140
117
|
|
141
|
-
# Gets the default connection options used when calling
|
118
|
+
# Gets the default connection options used when calling Faraday#new.
|
142
119
|
#
|
143
|
-
#
|
120
|
+
# Returns a Faraday::ConnectionOptions.
|
144
121
|
def self.default_connection_options
|
145
122
|
@default_connection_options ||= ConnectionOptions.new
|
146
123
|
end
|
147
124
|
|
148
|
-
# Sets the default options used when calling
|
149
|
-
#
|
150
|
-
# @param options [Hash, Faraday::ConnectionOptions]
|
125
|
+
# Public: Sets the default options used when calling Faraday#new.
|
151
126
|
def self.default_connection_options=(options)
|
152
127
|
@default_connection = nil
|
153
128
|
@default_connection_options = ConnectionOptions.from(options)
|
@@ -158,9 +133,115 @@ module Faraday
|
|
158
133
|
Timer = Timeout
|
159
134
|
end
|
160
135
|
|
161
|
-
|
162
|
-
|
163
|
-
|
136
|
+
# Public: Adds the ability for other modules to register and lookup
|
137
|
+
# middleware classes.
|
138
|
+
module MiddlewareRegistry
|
139
|
+
# Public: Register middleware class(es) on the current module.
|
140
|
+
#
|
141
|
+
# mapping - A Hash mapping Symbol keys to classes. Classes can be expressed
|
142
|
+
# as fully qualified constant, or a Proc that will be lazily
|
143
|
+
# called to return the former.
|
144
|
+
#
|
145
|
+
# Examples
|
146
|
+
#
|
147
|
+
# module Faraday
|
148
|
+
# class Whatever
|
149
|
+
# # Middleware looked up by :foo returns Faraday::Whatever::Foo.
|
150
|
+
# register_middleware :foo => Foo
|
151
|
+
#
|
152
|
+
# # Middleware looked up by :bar returns Faraday::Whatever.const_get(:Bar)
|
153
|
+
# register_middleware :bar => :Bar
|
154
|
+
#
|
155
|
+
# # Middleware looked up by :baz requires 'baz' and returns Faraday::Whatever.const_get(:Baz)
|
156
|
+
# register_middleware :baz => [:Baz, 'baz']
|
157
|
+
# end
|
158
|
+
# end
|
159
|
+
#
|
160
|
+
# Returns nothing.
|
161
|
+
def register_middleware(autoload_path = nil, mapping = nil)
|
162
|
+
if mapping.nil?
|
163
|
+
mapping = autoload_path
|
164
|
+
autoload_path = nil
|
165
|
+
end
|
166
|
+
middleware_mutex do
|
167
|
+
@middleware_autoload_path = autoload_path if autoload_path
|
168
|
+
(@registered_middleware ||= {}).update(mapping)
|
169
|
+
end
|
170
|
+
end
|
164
171
|
|
165
|
-
|
172
|
+
# Public: Lookup middleware class with a registered Symbol shortcut.
|
173
|
+
#
|
174
|
+
# key - The Symbol key for the registered middleware.
|
175
|
+
#
|
176
|
+
# Examples
|
177
|
+
#
|
178
|
+
# module Faraday
|
179
|
+
# class Whatever
|
180
|
+
# register_middleware :foo => Foo
|
181
|
+
# end
|
182
|
+
# end
|
183
|
+
#
|
184
|
+
# Faraday::Whatever.lookup_middleware(:foo)
|
185
|
+
# # => Faraday::Whatever::Foo
|
186
|
+
#
|
187
|
+
# Returns a middleware Class.
|
188
|
+
def lookup_middleware(key)
|
189
|
+
load_middleware(key) ||
|
190
|
+
raise(Faraday::Error.new("#{key.inspect} is not registered on #{self}"))
|
191
|
+
end
|
192
|
+
|
193
|
+
def middleware_mutex(&block)
|
194
|
+
@middleware_mutex ||= begin
|
195
|
+
require 'monitor'
|
196
|
+
Monitor.new
|
197
|
+
end
|
198
|
+
@middleware_mutex.synchronize(&block)
|
199
|
+
end
|
200
|
+
|
201
|
+
def fetch_middleware(key)
|
202
|
+
defined?(@registered_middleware) && @registered_middleware[key]
|
203
|
+
end
|
204
|
+
|
205
|
+
def load_middleware(key)
|
206
|
+
value = fetch_middleware(key)
|
207
|
+
case value
|
208
|
+
when Module
|
209
|
+
value
|
210
|
+
when Symbol, String
|
211
|
+
middleware_mutex do
|
212
|
+
@registered_middleware[key] = const_get(value)
|
213
|
+
end
|
214
|
+
when Proc
|
215
|
+
middleware_mutex do
|
216
|
+
@registered_middleware[key] = value.call
|
217
|
+
end
|
218
|
+
when Array
|
219
|
+
middleware_mutex do
|
220
|
+
const, path = value
|
221
|
+
if root = @middleware_autoload_path
|
222
|
+
path = "#{root}/#{path}"
|
223
|
+
end
|
224
|
+
require(path)
|
225
|
+
@registered_middleware[key] = const
|
226
|
+
end
|
227
|
+
load_middleware(key)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def self.const_missing(name)
|
233
|
+
if name.to_sym == :Builder
|
234
|
+
warn "Faraday::Builder is now Faraday::RackBuilder."
|
235
|
+
const_set name, RackBuilder
|
236
|
+
else
|
237
|
+
super
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
require_libs "utils", "options", "connection", "rack_builder", "parameters",
|
242
|
+
"middleware", "adapter", "request", "response", "upload_io", "error"
|
243
|
+
|
244
|
+
if !ENV["FARADAY_NO_AUTOLOAD"]
|
245
|
+
require_lib 'autoload'
|
246
|
+
end
|
166
247
|
end
|
data/lib/faraday/adapter.rb
CHANGED
@@ -1,54 +1,43 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Faraday
|
4
|
-
#
|
2
|
+
# Public: This is a base class for all Faraday adapters. Adapters are
|
5
3
|
# responsible for fulfilling a Faraday request.
|
6
|
-
class Adapter
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
em_http: [:EMHttp, 'em_http'],
|
23
|
-
excon: [:Excon, 'excon'],
|
24
|
-
rack: [:Rack, 'rack'],
|
25
|
-
httpclient: [:HTTPClient, 'httpclient']
|
26
|
-
|
27
|
-
# This module marks an Adapter as supporting parallel requests.
|
4
|
+
class Adapter < Middleware
|
5
|
+
CONTENT_LENGTH = 'Content-Length'.freeze
|
6
|
+
|
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.
|
28
20
|
module Parallelism
|
29
21
|
attr_writer :supports_parallel
|
30
|
-
def supports_parallel?
|
31
|
-
@supports_parallel
|
32
|
-
end
|
22
|
+
def supports_parallel?() @supports_parallel end
|
33
23
|
|
34
24
|
def inherited(subclass)
|
35
25
|
super
|
36
|
-
subclass.supports_parallel = supports_parallel?
|
26
|
+
subclass.supports_parallel = self.supports_parallel?
|
37
27
|
end
|
38
28
|
end
|
39
29
|
|
40
30
|
extend Parallelism
|
41
31
|
self.supports_parallel = false
|
42
32
|
|
43
|
-
def initialize(
|
44
|
-
|
33
|
+
def initialize(app = nil, opts = {}, &block)
|
34
|
+
super(app)
|
45
35
|
@connection_options = opts
|
46
36
|
@config_block = block
|
47
37
|
end
|
48
38
|
|
49
39
|
def call(env)
|
50
40
|
env.clear_body if env.needs_body?
|
51
|
-
env.response = Response.new
|
52
41
|
end
|
53
42
|
|
54
43
|
private
|
@@ -56,14 +45,11 @@ module Faraday
|
|
56
45
|
def save_response(env, status, body, headers = nil, reason_phrase = nil)
|
57
46
|
env.status = status
|
58
47
|
env.body = body
|
59
|
-
env.reason_phrase = reason_phrase
|
48
|
+
env.reason_phrase = reason_phrase && reason_phrase.to_s.strip
|
60
49
|
env.response_headers = Utils::Headers.new.tap do |response_headers|
|
61
50
|
response_headers.update headers unless headers.nil?
|
62
51
|
yield(response_headers) if block_given?
|
63
52
|
end
|
64
|
-
|
65
|
-
env.response.finish(env) unless env.parallel?
|
66
|
-
env.response
|
67
53
|
end
|
68
54
|
end
|
69
55
|
end
|
@@ -1,15 +1,10 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Faraday
|
4
2
|
class Adapter
|
5
|
-
# EventMachine adapter
|
6
|
-
#
|
3
|
+
# EventMachine adapter is useful for either asynchronous requests
|
4
|
+
# when in EM reactor loop or for making parallel requests in
|
7
5
|
# synchronous code.
|
8
6
|
class EMHttp < Faraday::Adapter
|
9
|
-
# Options is a module containing helpers to convert the Faraday env object
|
10
|
-
# into options hashes for EMHTTP method calls.
|
11
7
|
module Options
|
12
|
-
# @return [Hash]
|
13
8
|
def connection_config(env)
|
14
9
|
options = {}
|
15
10
|
configure_proxy(options, env)
|
@@ -21,10 +16,10 @@ module Faraday
|
|
21
16
|
|
22
17
|
def request_config(env)
|
23
18
|
options = {
|
24
|
-
body
|
25
|
-
head
|
26
|
-
# keepalive
|
27
|
-
# file
|
19
|
+
:body => read_body(env),
|
20
|
+
:head => env[:request_headers],
|
21
|
+
# :keepalive => true,
|
22
|
+
# :file => 'path/to/file', # stream data off disk
|
28
23
|
}
|
29
24
|
configure_compression(options, env)
|
30
25
|
options
|
@@ -35,53 +30,44 @@ module Faraday
|
|
35
30
|
body.respond_to?(:read) ? body.read : body
|
36
31
|
end
|
37
32
|
|
38
|
-
# Reads out proxy settings from env into options
|
39
33
|
def configure_proxy(options, env)
|
40
|
-
proxy = request_options(env)[:proxy]
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
}
|
34
|
+
if proxy = request_options(env)[:proxy]
|
35
|
+
options[:proxy] = {
|
36
|
+
:host => proxy[:uri].host,
|
37
|
+
:port => proxy[:uri].port,
|
38
|
+
:authorization => [proxy[:user], proxy[:password]]
|
39
|
+
}
|
40
|
+
end
|
48
41
|
end
|
49
42
|
|
50
|
-
# Reads out host and port settings from env into options
|
51
43
|
def configure_socket(options, env)
|
52
|
-
bind = request_options(env)[:bind]
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
}
|
44
|
+
if bind = request_options(env)[:bind]
|
45
|
+
options[:bind] = {
|
46
|
+
:host => bind[:host],
|
47
|
+
:port => bind[:port]
|
48
|
+
}
|
49
|
+
end
|
59
50
|
end
|
60
51
|
|
61
|
-
# Reads out SSL certificate settings from env into options
|
62
52
|
def configure_ssl(options, env)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
53
|
+
if env[:url].scheme == 'https' && env[:ssl]
|
54
|
+
options[:ssl] = {
|
55
|
+
:cert_chain_file => env[:ssl][:ca_file],
|
56
|
+
:verify_peer => env[:ssl].fetch(:verify, true)
|
57
|
+
}
|
58
|
+
end
|
69
59
|
end
|
70
60
|
|
71
|
-
# Reads out timeout settings from env into options
|
72
61
|
def configure_timeout(options, env)
|
73
|
-
timeout, open_timeout = request_options(env)
|
74
|
-
.values_at(:timeout, :open_timeout)
|
62
|
+
timeout, open_timeout = request_options(env).values_at(:timeout, :open_timeout)
|
75
63
|
options[:connect_timeout] = options[:inactivity_timeout] = timeout
|
76
64
|
options[:connect_timeout] = open_timeout if open_timeout
|
77
65
|
end
|
78
66
|
|
79
|
-
# Reads out compression header settings from env into options
|
80
67
|
def configure_compression(options, env)
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
options[:head]['accept-encoding'] = 'gzip, compressed'
|
68
|
+
if env[:method] == :get and not options[:head].key? 'accept-encoding'
|
69
|
+
options[:head]['accept-encoding'] = 'gzip, compressed'
|
70
|
+
end
|
85
71
|
end
|
86
72
|
|
87
73
|
def request_options(env)
|
@@ -95,8 +81,7 @@ module Faraday
|
|
95
81
|
|
96
82
|
self.supports_parallel = true
|
97
83
|
|
98
|
-
|
99
|
-
def self.setup_parallel_manager(_options = nil)
|
84
|
+
def self.setup_parallel_manager(options = nil)
|
100
85
|
Manager.new
|
101
86
|
end
|
102
87
|
|
@@ -109,113 +94,95 @@ module Faraday
|
|
109
94
|
def perform_request(env)
|
110
95
|
if parallel?(env)
|
111
96
|
manager = env[:parallel_manager]
|
112
|
-
manager.add
|
113
|
-
perform_single_request(env)
|
114
|
-
|
115
|
-
|
116
|
-
elsif EventMachine.reactor_running?
|
117
|
-
# EM is running: instruct upstream that this is an async request
|
118
|
-
env[:parallel_manager] = true
|
119
|
-
perform_single_request(env)
|
120
|
-
.callback { env[:response].finish(env) }
|
121
|
-
.errback do
|
122
|
-
# TODO: no way to communicate the error in async mode
|
123
|
-
raise NotImplementedError
|
124
|
-
end
|
97
|
+
manager.add {
|
98
|
+
perform_single_request(env).
|
99
|
+
callback { env[:response].finish(env) }
|
100
|
+
}
|
125
101
|
else
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
.
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
102
|
+
unless EventMachine.reactor_running?
|
103
|
+
error = nil
|
104
|
+
# start EM, block until request is completed
|
105
|
+
EventMachine.run do
|
106
|
+
perform_single_request(env).
|
107
|
+
callback { EventMachine.stop }.
|
108
|
+
errback { |client|
|
109
|
+
error = error_message(client)
|
110
|
+
EventMachine.stop
|
111
|
+
}
|
112
|
+
end
|
113
|
+
raise_error(error) if error
|
114
|
+
else
|
115
|
+
# EM is running: instruct upstream that this is an async request
|
116
|
+
env[:parallel_manager] = true
|
117
|
+
perform_single_request(env).
|
118
|
+
callback { env[:response].finish(env) }.
|
119
|
+
errback {
|
120
|
+
# TODO: no way to communicate the error in async mode
|
121
|
+
raise NotImplementedError
|
122
|
+
}
|
135
123
|
end
|
136
|
-
raise_error(error) if error
|
137
124
|
end
|
138
|
-
rescue EventMachine::Connectify::CONNECTError =>
|
139
|
-
if
|
140
|
-
raise Faraday::ConnectionFailed,
|
141
|
-
|
125
|
+
rescue EventMachine::Connectify::CONNECTError => err
|
126
|
+
if err.message.include?("Proxy Authentication Required")
|
127
|
+
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
|
128
|
+
else
|
129
|
+
raise Faraday::ConnectionFailed, err
|
142
130
|
end
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
raise
|
131
|
+
rescue => err
|
132
|
+
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
133
|
+
raise Faraday::SSLError, err
|
134
|
+
else
|
135
|
+
raise
|
148
136
|
end
|
149
|
-
|
150
|
-
raise
|
151
137
|
end
|
152
138
|
|
153
139
|
# TODO: reuse the connection to support pipelining
|
154
140
|
def perform_single_request(env)
|
155
141
|
req = create_request(env)
|
156
|
-
req
|
157
|
-
req.callback do |client|
|
158
|
-
if env[:request].stream_response?
|
159
|
-
warn "Streaming downloads for #{self.class.name} " \
|
160
|
-
'are not yet implemented.'
|
161
|
-
env[:request].on_data.call(
|
162
|
-
client.response,
|
163
|
-
client.response.bytesize
|
164
|
-
)
|
165
|
-
end
|
142
|
+
req.setup_request(env[:method], request_config(env)).callback { |client|
|
166
143
|
status = client.response_header.status
|
167
144
|
reason = client.response_header.http_reason
|
168
|
-
save_response(env, status, client.response, nil, reason) do |
|
145
|
+
save_response(env, status, client.response, nil, reason) do |resp_headers|
|
169
146
|
client.response_header.each do |name, value|
|
170
|
-
|
147
|
+
resp_headers[name.to_sym] = value
|
171
148
|
end
|
172
149
|
end
|
173
|
-
|
150
|
+
}
|
174
151
|
end
|
175
152
|
|
176
153
|
def create_request(env)
|
177
|
-
EventMachine::HttpRequest.new(
|
178
|
-
env[:url], connection_config(env).merge(@connection_options)
|
179
|
-
)
|
154
|
+
EventMachine::HttpRequest.new(env[:url], connection_config(env).merge(@connection_options))
|
180
155
|
end
|
181
156
|
|
182
157
|
def error_message(client)
|
183
|
-
client.error
|
158
|
+
client.error or "request failed"
|
184
159
|
end
|
185
160
|
|
186
161
|
def raise_error(msg)
|
187
|
-
|
188
|
-
if
|
189
|
-
|
190
|
-
msg =
|
162
|
+
errklass = Faraday::ClientError
|
163
|
+
if msg == Errno::ETIMEDOUT
|
164
|
+
errklass = Faraday::TimeoutError
|
165
|
+
msg = "request timed out"
|
191
166
|
elsif msg == Errno::ECONNREFUSED
|
192
|
-
|
193
|
-
msg =
|
194
|
-
elsif msg ==
|
195
|
-
|
167
|
+
errklass = Faraday::ConnectionFailed
|
168
|
+
msg = "connection refused"
|
169
|
+
elsif msg == "connection closed by server"
|
170
|
+
errklass = Faraday::ConnectionFailed
|
196
171
|
end
|
197
|
-
raise
|
172
|
+
raise errklass, msg
|
198
173
|
end
|
199
174
|
|
200
|
-
def timeout_message?(msg)
|
201
|
-
msg == Errno::ETIMEDOUT ||
|
202
|
-
(msg.is_a?(String) && msg.include?('timeout error'))
|
203
|
-
end
|
204
|
-
|
205
|
-
# @return [Boolean]
|
206
175
|
def parallel?(env)
|
207
176
|
!!env[:parallel_manager]
|
208
177
|
end
|
209
178
|
|
210
|
-
#
|
179
|
+
# The parallel manager is designed to start an EventMachine loop
|
211
180
|
# and block until all registered requests have been completed.
|
212
181
|
class Manager
|
213
|
-
# @see reset
|
214
182
|
def initialize
|
215
183
|
reset
|
216
184
|
end
|
217
185
|
|
218
|
-
# Re-initializes instance variables
|
219
186
|
def reset
|
220
187
|
@registered_procs = []
|
221
188
|
@num_registered = 0
|
@@ -224,10 +191,7 @@ module Faraday
|
|
224
191
|
@running = false
|
225
192
|
end
|
226
193
|
|
227
|
-
|
228
|
-
def running?
|
229
|
-
@running
|
230
|
-
end
|
194
|
+
def running?() @running end
|
231
195
|
|
232
196
|
def add(&block)
|
233
197
|
if running?
|
@@ -239,15 +203,15 @@ module Faraday
|
|
239
203
|
end
|
240
204
|
|
241
205
|
def run
|
242
|
-
if @num_registered
|
206
|
+
if @num_registered > 0
|
243
207
|
@running = true
|
244
208
|
EventMachine.run do
|
245
209
|
@registered_procs.each do |proc|
|
246
210
|
perform_request(&proc)
|
247
211
|
end
|
248
212
|
end
|
249
|
-
|
250
|
-
raise Faraday::ClientError, @errors.first ||
|
213
|
+
if @errors.size > 0
|
214
|
+
raise Faraday::ClientError, @errors.first || "connection failed"
|
251
215
|
end
|
252
216
|
end
|
253
217
|
ensure
|
@@ -256,31 +220,24 @@ module Faraday
|
|
256
220
|
|
257
221
|
def perform_request
|
258
222
|
client = yield
|
259
|
-
client.callback
|
260
|
-
|
261
|
-
check_finished
|
262
|
-
end
|
263
|
-
client.errback do
|
264
|
-
@errors << client.error
|
265
|
-
check_finished
|
266
|
-
end
|
223
|
+
client.callback { @num_succeeded += 1; check_finished }
|
224
|
+
client.errback { @errors << client.error; check_finished }
|
267
225
|
end
|
268
226
|
|
269
227
|
def check_finished
|
270
|
-
|
228
|
+
if @num_succeeded + @errors.size == @num_registered
|
229
|
+
EventMachine.stop
|
230
|
+
end
|
271
231
|
end
|
272
232
|
end
|
273
233
|
end
|
274
234
|
end
|
275
235
|
end
|
276
236
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
require 'faraday/adapter/em_http_ssl_patch'
|
285
|
-
end
|
286
|
-
end
|
237
|
+
begin
|
238
|
+
require 'openssl'
|
239
|
+
rescue LoadError
|
240
|
+
warn "Warning: no such file to load -- openssl. Make sure it is installed if you want HTTPS support"
|
241
|
+
else
|
242
|
+
require 'faraday/adapter/em_http_ssl_patch'
|
243
|
+
end if Faraday::Adapter::EMHttp.loaded?
|