faraday 0.15.4 → 0.16.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 +18 -344
- data/lib/faraday.rb +93 -175
- data/lib/faraday/adapter.rb +36 -22
- data/lib/faraday/adapter/em_http.rb +142 -99
- data/lib/faraday/adapter/em_http_ssl_patch.rb +23 -17
- data/lib/faraday/adapter/em_synchrony.rb +104 -60
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
- data/lib/faraday/adapter/excon.rb +100 -55
- data/lib/faraday/adapter/httpclient.rb +61 -39
- data/lib/faraday/adapter/net_http.rb +104 -51
- data/lib/faraday/adapter/net_http_persistent.rb +48 -27
- data/lib/faraday/adapter/patron.rb +54 -35
- data/lib/faraday/adapter/rack.rb +28 -12
- data/lib/faraday/adapter/test.rb +86 -53
- data/lib/faraday/adapter/typhoeus.rb +4 -1
- data/lib/faraday/adapter_registry.rb +28 -0
- data/lib/faraday/autoload.rb +47 -36
- data/lib/faraday/connection.rb +321 -179
- data/lib/faraday/dependency_loader.rb +37 -0
- data/lib/faraday/encoders/flat_params_encoder.rb +94 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
- data/lib/faraday/error.rb +67 -33
- data/lib/faraday/file_part.rb +128 -0
- data/lib/faraday/logging/formatter.rb +92 -0
- data/lib/faraday/middleware.rb +4 -28
- data/lib/faraday/middleware_registry.rb +129 -0
- data/lib/faraday/options.rb +35 -186
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +181 -0
- data/lib/faraday/options/proxy_options.rb +28 -0
- data/lib/faraday/options/request_options.rb +21 -0
- data/lib/faraday/options/ssl_options.rb +59 -0
- data/lib/faraday/param_part.rb +53 -0
- data/lib/faraday/parameters.rb +4 -197
- data/lib/faraday/rack_builder.rb +67 -56
- data/lib/faraday/request.rb +68 -36
- data/lib/faraday/request/authorization.rb +42 -30
- data/lib/faraday/request/basic_authentication.rb +14 -7
- data/lib/faraday/request/instrumentation.rb +45 -27
- data/lib/faraday/request/multipart.rb +79 -48
- data/lib/faraday/request/retry.rb +198 -169
- data/lib/faraday/request/token_authentication.rb +15 -10
- data/lib/faraday/request/url_encoded.rb +41 -23
- data/lib/faraday/response.rb +23 -16
- data/lib/faraday/response/logger.rb +22 -69
- data/lib/faraday/response/raise_error.rb +36 -14
- data/lib/faraday/utils.rb +28 -245
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- metadata +21 -5
- data/lib/faraday/upload_io.rb +0 -67
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Faraday
|
2
4
|
class Adapter
|
3
|
-
# This class is just a stub, the real adapter is in
|
5
|
+
# Typhoeus adapter. This class is just a stub, the real adapter is in
|
6
|
+
# https://github.com/philsturgeon/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb
|
4
7
|
class Typhoeus < Faraday::Adapter
|
5
8
|
# Needs to define this method in order to support Typhoeus <= 1.3.0
|
6
9
|
def call; end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'monitor'
|
4
|
+
|
5
|
+
module Faraday
|
6
|
+
# AdapterRegistry registers adapter class names so they can be looked up by a
|
7
|
+
# String or Symbol name.
|
8
|
+
class AdapterRegistry
|
9
|
+
def initialize
|
10
|
+
@lock = Monitor.new
|
11
|
+
@constants = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(name)
|
15
|
+
klass = @constants[name]
|
16
|
+
return klass if klass
|
17
|
+
|
18
|
+
Object.const_get(name).tap { |c| set(c, name) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def set(klass, name = nil)
|
22
|
+
name ||= klass.to_s
|
23
|
+
@lock.synchronize do
|
24
|
+
@constants[name] = klass
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/faraday/autoload.rb
CHANGED
@@ -1,84 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Faraday
|
2
|
-
#
|
4
|
+
# Adds the ability for other modules to manage autoloadable
|
3
5
|
# constants.
|
6
|
+
#
|
7
|
+
# @api private
|
4
8
|
module AutoloadHelper
|
5
|
-
#
|
9
|
+
# Registers the constants to be auto loaded.
|
6
10
|
#
|
7
|
-
# prefix
|
8
|
-
# it will be prefixed with the root path of this loaded
|
9
|
-
# version.
|
10
|
-
# options
|
11
|
+
# @param prefix [String] The require prefix. If the path is inside Faraday,
|
12
|
+
# then it will be prefixed with the root path of this loaded
|
13
|
+
# Faraday version.
|
14
|
+
# @param options [{ Symbol => String }] library names.
|
11
15
|
#
|
12
|
-
#
|
16
|
+
# @example
|
13
17
|
#
|
14
18
|
# Faraday.autoload_all 'faraday/foo',
|
15
|
-
# :
|
19
|
+
# Bar: 'bar'
|
16
20
|
#
|
17
21
|
# # requires faraday/foo/bar to load Faraday::Bar.
|
18
22
|
# Faraday::Bar
|
19
23
|
#
|
20
|
-
#
|
21
|
-
# Returns nothing.
|
24
|
+
# @return [void]
|
22
25
|
def autoload_all(prefix, options)
|
23
|
-
if prefix =~
|
26
|
+
if prefix =~ %r{^faraday(/|$)}i
|
24
27
|
prefix = File.join(Faraday.root_path, prefix)
|
25
28
|
end
|
29
|
+
|
26
30
|
options.each do |const_name, path|
|
27
31
|
autoload const_name, File.join(prefix, path)
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
31
|
-
#
|
35
|
+
# Loads each autoloaded constant. If thread safety is a concern,
|
32
36
|
# wrap this in a Mutex.
|
33
37
|
#
|
34
|
-
#
|
38
|
+
# @return [void]
|
35
39
|
def load_autoloaded_constants
|
36
40
|
constants.each do |const|
|
37
41
|
const_get(const) if autoload?(const)
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
41
|
-
#
|
45
|
+
# Filters the module's contents with those that have been already
|
42
46
|
# autoloaded.
|
43
47
|
#
|
44
|
-
#
|
48
|
+
# @return [Array<Class, Module>]
|
45
49
|
def all_loaded_constants
|
46
|
-
constants
|
47
|
-
|
50
|
+
constants
|
51
|
+
.map { |c| const_get(c) }
|
52
|
+
.select { |a| a.respond_to?(:loaded?) && a.loaded? }
|
48
53
|
end
|
49
54
|
end
|
50
55
|
|
56
|
+
# Adapter is the base class for all Faraday adapters.
|
57
|
+
# @see lib/faraday/adapter.rb Original class location
|
51
58
|
class Adapter
|
52
59
|
extend AutoloadHelper
|
53
60
|
autoload_all 'faraday/adapter',
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
NetHttp: 'net_http',
|
62
|
+
NetHttpPersistent: 'net_http_persistent',
|
63
|
+
EMSynchrony: 'em_synchrony',
|
64
|
+
EMHttp: 'em_http',
|
65
|
+
Typhoeus: 'typhoeus',
|
66
|
+
Patron: 'patron',
|
67
|
+
Excon: 'excon',
|
68
|
+
Test: 'test',
|
69
|
+
Rack: 'rack',
|
70
|
+
HTTPClient: 'httpclient'
|
64
71
|
end
|
65
72
|
|
73
|
+
# Request represents a single HTTP request for a Faraday adapter to make.
|
74
|
+
# @see lib/faraday/request.rb Original class location
|
66
75
|
class Request
|
67
76
|
extend AutoloadHelper
|
68
77
|
autoload_all 'faraday/request',
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
78
|
+
UrlEncoded: 'url_encoded',
|
79
|
+
Multipart: 'multipart',
|
80
|
+
Retry: 'retry',
|
81
|
+
Authorization: 'authorization',
|
82
|
+
BasicAuthentication: 'basic_authentication',
|
83
|
+
TokenAuthentication: 'token_authentication',
|
84
|
+
Instrumentation: 'instrumentation'
|
76
85
|
end
|
77
86
|
|
87
|
+
# Response represents the returned value of a sent Faraday request.
|
88
|
+
# @see lib/faraday/response.rb Original class location
|
78
89
|
class Response
|
79
90
|
extend AutoloadHelper
|
80
91
|
autoload_all 'faraday/response',
|
81
|
-
|
82
|
-
|
92
|
+
RaiseError: 'raise_error',
|
93
|
+
Logger: 'logger'
|
83
94
|
end
|
84
95
|
end
|
data/lib/faraday/connection.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Faraday
|
2
|
-
#
|
4
|
+
# Connection objects manage the default properties and the middleware
|
3
5
|
# stack for fulfilling an HTTP request.
|
4
6
|
#
|
5
|
-
#
|
7
|
+
# @example
|
6
8
|
#
|
7
9
|
# conn = Faraday::Connection.new 'http://sushi.com'
|
8
10
|
#
|
@@ -12,51 +14,51 @@ module Faraday
|
|
12
14
|
#
|
13
15
|
class Connection
|
14
16
|
# A Set of allowed HTTP verbs.
|
15
|
-
METHODS = Set.new [
|
17
|
+
METHODS = Set.new %i[get post put delete head patch options trace connect]
|
16
18
|
|
17
|
-
#
|
19
|
+
# @return [Hash] URI query unencoded key/value pairs.
|
18
20
|
attr_reader :params
|
19
21
|
|
20
|
-
#
|
22
|
+
# @return [Hash] unencoded HTTP header key/value pairs.
|
21
23
|
attr_reader :headers
|
22
24
|
|
23
|
-
#
|
24
|
-
#
|
25
|
+
# @return [String] a URI with the prefix used for all requests from this
|
26
|
+
# Connection. This includes a default host name, scheme, port, and path.
|
25
27
|
attr_reader :url_prefix
|
26
28
|
|
27
|
-
#
|
29
|
+
# @return [Faraday::Builder] Builder for this Connection.
|
28
30
|
attr_reader :builder
|
29
31
|
|
30
|
-
#
|
31
|
-
attr_reader :options
|
32
|
-
|
33
|
-
# Public: Returns a Hash of the SSL options.
|
32
|
+
# @return [Hash] SSL options.
|
34
33
|
attr_reader :ssl
|
35
34
|
|
36
|
-
#
|
35
|
+
# @return [Object] the parallel manager for this Connection.
|
37
36
|
attr_reader :parallel_manager
|
38
37
|
|
39
|
-
#
|
38
|
+
# Sets the default parallel manager for this connection.
|
40
39
|
attr_writer :default_parallel_manager
|
41
40
|
|
42
|
-
#
|
43
|
-
|
41
|
+
# @return [Hash] proxy options.
|
42
|
+
attr_reader :proxy
|
44
43
|
|
45
|
-
#
|
44
|
+
# Initializes a new Faraday::Connection.
|
46
45
|
#
|
47
|
-
# url
|
46
|
+
# @param url [URI, String] URI or String base URL to use as a prefix for all
|
48
47
|
# requests (optional).
|
49
|
-
# options
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
48
|
+
# @param options [Hash, Faraday::ConnectionOptions]
|
49
|
+
# @option options [URI, String] :url ('http:/') URI or String base URL
|
50
|
+
# @option options [Hash<String => String>] :params URI query unencoded
|
51
|
+
# key/value pairs.
|
52
|
+
# @option options [Hash<String => String>] :headers Hash of unencoded HTTP
|
53
|
+
# header key/value pairs.
|
54
|
+
# @option options [Hash] :request Hash of request options.
|
55
|
+
# @option options [Hash] :ssl Hash of SSL options.
|
56
|
+
# @option options [Hash, URI, String] :proxy proxy options, either as a URL
|
57
|
+
# or as a Hash
|
58
|
+
# @option options [URI, String] :proxy[:uri]
|
59
|
+
# @option options [String] :proxy[:user]
|
60
|
+
# @option options [String] :proxy[:password]
|
61
|
+
# @yield [self] after all setup has been done
|
60
62
|
def initialize(url = nil, options = nil)
|
61
63
|
options = ConnectionOptions.from(options)
|
62
64
|
|
@@ -74,7 +76,7 @@ module Faraday
|
|
74
76
|
|
75
77
|
@builder = options.builder || begin
|
76
78
|
# pass an empty block to Builder so it doesn't assume default middleware
|
77
|
-
options.new_builder(block_given? ?
|
79
|
+
options.new_builder(block_given? ? proc { |b| } : nil)
|
78
80
|
end
|
79
81
|
|
80
82
|
self.url_prefix = url || 'http:/'
|
@@ -82,21 +84,32 @@ module Faraday
|
|
82
84
|
@params.update(options.params) if options.params
|
83
85
|
@headers.update(options.headers) if options.headers
|
84
86
|
|
85
|
-
|
86
|
-
@proxy = options.proxy ? ProxyOptions.from(options.proxy) : proxy_from_env(url)
|
87
|
-
@temp_proxy = @proxy
|
87
|
+
initialize_proxy(url, options)
|
88
88
|
|
89
89
|
yield(self) if block_given?
|
90
90
|
|
91
91
|
@headers[:user_agent] ||= "Faraday v#{VERSION}"
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
def initialize_proxy(url, options)
|
95
|
+
@manual_proxy = !!options.proxy
|
96
|
+
@proxy =
|
97
|
+
if options.proxy
|
98
|
+
ProxyOptions.from(options.proxy)
|
99
|
+
else
|
100
|
+
proxy_from_env(url)
|
101
|
+
end
|
102
|
+
@temp_proxy = @proxy
|
103
|
+
end
|
104
|
+
|
105
|
+
# Sets the Hash of URI query unencoded key/value pairs.
|
106
|
+
# @param hash [Hash]
|
95
107
|
def params=(hash)
|
96
108
|
@params.replace hash
|
97
109
|
end
|
98
110
|
|
99
|
-
#
|
111
|
+
# Sets the Hash of unencoded HTTP header key/value pairs.
|
112
|
+
# @param hash [Hash]
|
100
113
|
def headers=(hash)
|
101
114
|
@headers.replace hash
|
102
115
|
end
|
@@ -105,71 +118,171 @@ module Faraday
|
|
105
118
|
|
106
119
|
def_delegators :builder, :build, :use, :request, :response, :adapter, :app
|
107
120
|
|
108
|
-
#
|
121
|
+
# @!method get(url = nil, params = nil, headers = nil)
|
122
|
+
# Makes a GET HTTP request without a body.
|
123
|
+
# @!scope class
|
109
124
|
#
|
110
|
-
# url
|
111
|
-
#
|
112
|
-
# params
|
113
|
-
# headers
|
125
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
126
|
+
# all requests. Can also be the options Hash.
|
127
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
128
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
114
129
|
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
# conn.get '/items', {:page => 1}, :accept => 'application/json'
|
118
|
-
# conn.head '/items/1'
|
130
|
+
# @example
|
131
|
+
# conn.get '/items', { page: 1 }, :accept => 'application/json'
|
119
132
|
#
|
120
133
|
# # ElasticSearch example sending a body with GET.
|
121
134
|
# conn.get '/twitter/tweet/_search' do |req|
|
122
135
|
# req.headers[:content_type] = 'application/json'
|
123
136
|
# req.params[:routing] = 'kimchy'
|
124
|
-
# req.body = JSON.generate(:
|
137
|
+
# req.body = JSON.generate(query: {...})
|
125
138
|
# end
|
126
139
|
#
|
127
|
-
#
|
128
|
-
#
|
140
|
+
# @yield [Faraday::Request] for further request customizations
|
141
|
+
# @return [Faraday::Response]
|
142
|
+
|
143
|
+
# @!method head(url = nil, params = nil, headers = nil)
|
144
|
+
# Makes a HEAD HTTP request without a body.
|
145
|
+
# @!scope class
|
146
|
+
#
|
147
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
148
|
+
# all requests. Can also be the options Hash.
|
149
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
150
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
151
|
+
#
|
152
|
+
# @example
|
153
|
+
# conn.head '/items/1'
|
154
|
+
#
|
155
|
+
# @yield [Faraday::Request] for further request customizations
|
156
|
+
# @return [Faraday::Response]
|
157
|
+
|
158
|
+
# @!method delete(url = nil, params = nil, headers = nil)
|
159
|
+
# Makes a DELETE HTTP request without a body.
|
160
|
+
# @!scope class
|
161
|
+
#
|
162
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
163
|
+
# all requests. Can also be the options Hash.
|
164
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
165
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
166
|
+
#
|
167
|
+
# @example
|
168
|
+
# conn.delete '/items/1'
|
129
169
|
#
|
130
|
-
#
|
170
|
+
# @yield [Faraday::Request] for further request customizations
|
171
|
+
# @return [Faraday::Response]
|
172
|
+
|
173
|
+
# @!method connect(url = nil, params = nil, headers = nil)
|
174
|
+
# Makes a CONNECT HTTP request without a body.
|
175
|
+
# @!scope class
|
131
176
|
#
|
132
|
-
#
|
177
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
178
|
+
# all requests. Can also be the options Hash.
|
179
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
180
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
133
181
|
#
|
134
|
-
#
|
135
|
-
|
182
|
+
# @example
|
183
|
+
# conn.connect '/items/1'
|
184
|
+
#
|
185
|
+
# @yield [Faraday::Request] for further request customizations
|
186
|
+
# @return [Faraday::Response]
|
187
|
+
|
188
|
+
# @!method trace(url = nil, params = nil, headers = nil)
|
189
|
+
# Makes a TRACE HTTP request without a body.
|
190
|
+
# @!scope class
|
191
|
+
#
|
192
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
193
|
+
# all requests. Can also be the options Hash.
|
194
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
195
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
196
|
+
#
|
197
|
+
# @example
|
198
|
+
# conn.connect '/items/1'
|
199
|
+
#
|
200
|
+
# @yield [Faraday::Request] for further request customizations
|
201
|
+
# @return [Faraday::Response]
|
202
|
+
|
203
|
+
# @!visibility private
|
204
|
+
METHODS_WITH_QUERY.each do |method|
|
136
205
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
137
206
|
def #{method}(url = nil, params = nil, headers = nil)
|
138
|
-
run_request(:#{method}, url, nil, headers)
|
207
|
+
run_request(:#{method}, url, nil, headers) do |request|
|
139
208
|
request.params.update(params) if params
|
140
|
-
yield
|
141
|
-
|
209
|
+
yield request if block_given?
|
210
|
+
end
|
142
211
|
end
|
143
212
|
RUBY
|
144
213
|
end
|
145
214
|
|
146
|
-
#
|
215
|
+
# @overload options()
|
216
|
+
# Returns current Connection options.
|
147
217
|
#
|
148
|
-
# url
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
218
|
+
# @overload options(url, params = nil, headers = nil)
|
219
|
+
# Makes an OPTIONS HTTP request to the given URL.
|
220
|
+
# @param url [String] String base URL to sue as a prefix for all requests.
|
221
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
222
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
152
223
|
#
|
153
|
-
#
|
224
|
+
# @example
|
225
|
+
# conn.options '/items/1'
|
154
226
|
#
|
155
|
-
#
|
227
|
+
# @yield [Faraday::Request] for further request customizations
|
228
|
+
# @return [Faraday::Response]
|
229
|
+
def options(*args)
|
230
|
+
return @options if args.size.zero?
|
231
|
+
|
232
|
+
url, params, headers = *args
|
233
|
+
run_request(:options, url, nil, headers) do |request|
|
234
|
+
request.params.update(params) if params
|
235
|
+
yield request if block_given?
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# @!method post(url = nil, body = nil, headers = nil)
|
240
|
+
# Makes a POST HTTP request with a body.
|
241
|
+
# @!scope class
|
242
|
+
#
|
243
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
244
|
+
# all requests. Can also be the options Hash.
|
245
|
+
# @param body [String] body for the request.
|
246
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
247
|
+
#
|
248
|
+
# @example
|
249
|
+
# conn.post '/items', data, content_type: 'application/json'
|
156
250
|
#
|
157
251
|
# # Simple ElasticSearch indexing sample.
|
158
252
|
# conn.post '/twitter/tweet' do |req|
|
159
253
|
# req.headers[:content_type] = 'application/json'
|
160
254
|
# req.params[:routing] = 'kimchy'
|
161
|
-
# req.body = JSON.generate(:
|
255
|
+
# req.body = JSON.generate(user: 'kimchy', ...)
|
162
256
|
# end
|
163
257
|
#
|
164
|
-
#
|
165
|
-
#
|
258
|
+
# @yield [Faraday::Request] for further request customizations
|
259
|
+
# @return [Faraday::Response]
|
260
|
+
|
261
|
+
# @!method put(url = nil, body = nil, headers = nil)
|
262
|
+
# Makes a PUT HTTP request with a body.
|
263
|
+
# @!scope class
|
166
264
|
#
|
167
|
-
#
|
265
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
266
|
+
# all requests. Can also be the options Hash.
|
267
|
+
# @param body [String] body for the request.
|
268
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
168
269
|
#
|
169
|
-
#
|
270
|
+
# @example
|
271
|
+
# # TODO: Make it a PUT example
|
272
|
+
# conn.post '/items', data, content_type: 'application/json'
|
170
273
|
#
|
171
|
-
#
|
172
|
-
|
274
|
+
# # Simple ElasticSearch indexing sample.
|
275
|
+
# conn.post '/twitter/tweet' do |req|
|
276
|
+
# req.headers[:content_type] = 'application/json'
|
277
|
+
# req.params[:routing] = 'kimchy'
|
278
|
+
# req.body = JSON.generate(user: 'kimchy', ...)
|
279
|
+
# end
|
280
|
+
#
|
281
|
+
# @yield [Faraday::Request] for further request customizations
|
282
|
+
# @return [Faraday::Response]
|
283
|
+
|
284
|
+
# @!visibility private
|
285
|
+
METHODS_WITH_BODY.each do |method|
|
173
286
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
174
287
|
def #{method}(url = nil, body = nil, headers = nil, &block)
|
175
288
|
run_request(:#{method}, url, body, headers, &block)
|
@@ -177,116 +290,110 @@ module Faraday
|
|
177
290
|
RUBY
|
178
291
|
end
|
179
292
|
|
180
|
-
#
|
293
|
+
# Sets up the Authorization header with these credentials, encoded
|
181
294
|
# with base64.
|
182
295
|
#
|
183
|
-
# login
|
184
|
-
# pass
|
296
|
+
# @param login [String] The authentication login.
|
297
|
+
# @param pass [String] The authentication password.
|
185
298
|
#
|
186
|
-
#
|
299
|
+
# @example
|
187
300
|
#
|
188
301
|
# conn.basic_auth 'Aladdin', 'open sesame'
|
189
302
|
# conn.headers['Authorization']
|
190
303
|
# # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
|
191
304
|
#
|
192
|
-
#
|
305
|
+
# @return [void]
|
193
306
|
def basic_auth(login, pass)
|
194
307
|
set_authorization_header(:basic_auth, login, pass)
|
195
308
|
end
|
196
309
|
|
197
|
-
#
|
310
|
+
# Sets up the Authorization header with the given token.
|
198
311
|
#
|
199
|
-
# token
|
200
|
-
# options
|
312
|
+
# @param token [String]
|
313
|
+
# @param options [Hash] extra token options.
|
201
314
|
#
|
202
|
-
#
|
315
|
+
# @example
|
203
316
|
#
|
204
|
-
# conn.token_auth 'abcdef', :
|
317
|
+
# conn.token_auth 'abcdef', foo: 'bar'
|
205
318
|
# conn.headers['Authorization']
|
206
319
|
# # => "Token token=\"abcdef\",
|
207
320
|
# foo=\"bar\""
|
208
321
|
#
|
209
|
-
#
|
322
|
+
# @return [void]
|
210
323
|
def token_auth(token, options = nil)
|
211
324
|
set_authorization_header(:token_auth, token, options)
|
212
325
|
end
|
213
326
|
|
214
|
-
#
|
327
|
+
# Sets up a custom Authorization header.
|
215
328
|
#
|
216
|
-
# type
|
217
|
-
# token
|
218
|
-
# a Hash is encoded into comma
|
329
|
+
# @param type [String] authorization type
|
330
|
+
# @param token [String, Hash] token. A String value is taken literally, and
|
331
|
+
# a Hash is encoded into comma-separated key/value pairs.
|
219
332
|
#
|
220
|
-
#
|
333
|
+
# @example
|
221
334
|
#
|
222
335
|
# conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
|
223
336
|
# conn.headers['Authorization']
|
224
337
|
# # => "Bearer mF_9.B5f-4.1JqM"
|
225
338
|
#
|
226
|
-
# conn.authorization :Token, :
|
339
|
+
# conn.authorization :Token, token: 'abcdef', foo: 'bar'
|
227
340
|
# conn.headers['Authorization']
|
228
341
|
# # => "Token token=\"abcdef\",
|
229
342
|
# foo=\"bar\""
|
230
343
|
#
|
231
|
-
#
|
344
|
+
# @return [void]
|
232
345
|
def authorization(type, token)
|
233
346
|
set_authorization_header(:authorization, type, token)
|
234
347
|
end
|
235
348
|
|
236
|
-
#
|
237
|
-
# parallel-capable adapter.
|
349
|
+
# Check if the adapter is parallel-capable.
|
238
350
|
#
|
239
|
-
#
|
351
|
+
# @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
|
240
352
|
#
|
241
|
-
#
|
353
|
+
# @return [Object, nil] a parallel manager or nil if yielded
|
354
|
+
# @api private
|
242
355
|
def default_parallel_manager
|
243
356
|
@default_parallel_manager ||= begin
|
244
|
-
|
245
|
-
h.klass.respond_to?(:supports_parallel?) and h.klass.supports_parallel?
|
246
|
-
end
|
357
|
+
adapter = @builder.adapter.klass if @builder.adapter
|
247
358
|
|
248
|
-
if
|
249
|
-
|
359
|
+
if support_parallel?(adapter)
|
360
|
+
adapter.setup_parallel_manager
|
250
361
|
elsif block_given?
|
251
362
|
yield
|
252
363
|
end
|
253
364
|
end
|
254
365
|
end
|
255
366
|
|
256
|
-
#
|
367
|
+
# Determine if this Faraday::Connection can make parallel requests.
|
257
368
|
#
|
258
|
-
#
|
369
|
+
# @return [Boolean]
|
259
370
|
def in_parallel?
|
260
371
|
!!@parallel_manager
|
261
372
|
end
|
262
373
|
|
263
|
-
#
|
374
|
+
# Sets up the parallel manager to make a set of requests.
|
264
375
|
#
|
265
|
-
# manager
|
376
|
+
# @param manager [Object] The parallel manager that this Connection's
|
377
|
+
# Adapter uses.
|
266
378
|
#
|
267
|
-
#
|
268
|
-
#
|
379
|
+
# @yield a block to execute multiple requests.
|
380
|
+
# @return [void]
|
269
381
|
def in_parallel(manager = nil)
|
270
|
-
@parallel_manager = manager || default_parallel_manager
|
271
|
-
warn
|
272
|
-
|
382
|
+
@parallel_manager = manager || default_parallel_manager do
|
383
|
+
warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \
|
384
|
+
'on Faraday stack'
|
385
|
+
warn caller[2, 10].join("\n")
|
273
386
|
nil
|
274
|
-
|
387
|
+
end
|
275
388
|
yield
|
276
|
-
@parallel_manager
|
389
|
+
@parallel_manager&.run
|
277
390
|
ensure
|
278
391
|
@parallel_manager = nil
|
279
392
|
end
|
280
393
|
|
281
|
-
#
|
282
|
-
|
283
|
-
|
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
|
286
|
-
@proxy = ProxyOptions.from(arg)
|
287
|
-
end
|
288
|
-
|
289
|
-
# Public: Sets the Hash proxy options.
|
394
|
+
# Sets the Hash proxy options.
|
395
|
+
#
|
396
|
+
# @param new_value [Object]
|
290
397
|
def proxy=(new_value)
|
291
398
|
@manual_proxy = true
|
292
399
|
@proxy = new_value ? ProxyOptions.from(new_value) : nil
|
@@ -295,13 +402,14 @@ module Faraday
|
|
295
402
|
def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port=
|
296
403
|
def_delegator :url_prefix, :path, :path_prefix
|
297
404
|
|
298
|
-
#
|
299
|
-
# components in this connection.
|
405
|
+
# Parses the given URL with URI and stores the individual
|
406
|
+
# components in this connection. These components serve as defaults for
|
300
407
|
# requests made by this connection.
|
301
408
|
#
|
302
|
-
# url
|
409
|
+
# @param url [String, URI]
|
410
|
+
# @param encoder [Object]
|
303
411
|
#
|
304
|
-
#
|
412
|
+
# @example
|
305
413
|
#
|
306
414
|
# conn = Faraday::Connection.new { ... }
|
307
415
|
# conn.url_prefix = "https://sushi.com/api"
|
@@ -309,8 +417,6 @@ module Faraday
|
|
309
417
|
# conn.path_prefix # => "/api"
|
310
418
|
#
|
311
419
|
# conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
|
312
|
-
#
|
313
|
-
# Returns the parsed URI from the given input..
|
314
420
|
def url_prefix=(url, encoder = nil)
|
315
421
|
uri = @url_prefix = Utils.URI(url)
|
316
422
|
self.path_prefix = uri.path
|
@@ -322,54 +428,65 @@ module Faraday
|
|
322
428
|
basic_auth user, password
|
323
429
|
uri.user = uri.password = nil
|
324
430
|
end
|
325
|
-
|
326
|
-
uri
|
327
431
|
end
|
328
432
|
|
329
|
-
#
|
433
|
+
# Sets the path prefix and ensures that it always has a leading
|
330
434
|
# slash.
|
331
435
|
#
|
332
|
-
# value
|
436
|
+
# @param value [String]
|
333
437
|
#
|
334
|
-
#
|
438
|
+
# @return [String] the new path prefix
|
335
439
|
def path_prefix=(value)
|
336
440
|
url_prefix.path = if value
|
337
|
-
|
338
|
-
|
339
|
-
|
441
|
+
value = '/' + value unless value[0, 1] == '/'
|
442
|
+
value
|
443
|
+
end
|
340
444
|
end
|
341
445
|
|
342
|
-
#
|
446
|
+
# Takes a relative url for a request and combines it with the defaults
|
343
447
|
# set on the connection instance.
|
344
448
|
#
|
449
|
+
# @param url [String]
|
450
|
+
# @param extra_params [Hash]
|
451
|
+
#
|
452
|
+
# @example
|
345
453
|
# conn = Faraday::Connection.new { ... }
|
346
454
|
# conn.url_prefix = "https://sushi.com/api?token=abc"
|
347
455
|
# conn.scheme # => https
|
348
456
|
# conn.path_prefix # => "/api"
|
349
457
|
#
|
350
|
-
# conn.build_url("nigiri?page=2")
|
351
|
-
#
|
458
|
+
# conn.build_url("nigiri?page=2")
|
459
|
+
# # => https://sushi.com/api/nigiri?token=abc&page=2
|
460
|
+
#
|
461
|
+
# conn.build_url("nigiri", page: 2)
|
462
|
+
# # => https://sushi.com/api/nigiri?token=abc&page=2
|
352
463
|
#
|
353
464
|
def build_url(url = nil, extra_params = nil)
|
354
465
|
uri = build_exclusive_url(url)
|
355
466
|
|
356
467
|
query_values = params.dup.merge_query(uri.query, options.params_encoder)
|
357
|
-
query_values.update
|
358
|
-
uri.query =
|
468
|
+
query_values.update(extra_params) if extra_params
|
469
|
+
uri.query =
|
470
|
+
if query_values.empty?
|
471
|
+
nil
|
472
|
+
else
|
473
|
+
query_values.to_query(options.params_encoder)
|
474
|
+
end
|
359
475
|
|
360
476
|
uri
|
361
477
|
end
|
362
478
|
|
363
479
|
# Builds and runs the Faraday::Request.
|
364
480
|
#
|
365
|
-
# method
|
366
|
-
# url
|
367
|
-
# body
|
368
|
-
#
|
481
|
+
# @param method [Symbol] HTTP method.
|
482
|
+
# @param url [String, URI] String or URI to access.
|
483
|
+
# @param body [Object] The request body that will eventually be converted to
|
484
|
+
# a string.
|
485
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
369
486
|
#
|
370
|
-
#
|
487
|
+
# @return [Faraday::Response]
|
371
488
|
def run_request(method, url, body, headers)
|
372
|
-
|
489
|
+
unless METHODS.include?(method)
|
373
490
|
raise ArgumentError, "unknown http method: #{method}"
|
374
491
|
end
|
375
492
|
|
@@ -377,7 +494,7 @@ module Faraday
|
|
377
494
|
@temp_proxy = proxy_for_request(url)
|
378
495
|
|
379
496
|
request = build_request(method) do |req|
|
380
|
-
req.options = req.options.merge(:
|
497
|
+
req.options = req.options.merge(proxy: @temp_proxy)
|
381
498
|
req.url(url) if url
|
382
499
|
req.headers.update(headers) if headers
|
383
500
|
req.body = body if body
|
@@ -389,73 +506,93 @@ module Faraday
|
|
389
506
|
|
390
507
|
# Creates and configures the request object.
|
391
508
|
#
|
392
|
-
#
|
509
|
+
# @param method [Symbol]
|
510
|
+
#
|
511
|
+
# @yield [Faraday::Request] if block given
|
512
|
+
# @return [Faraday::Request]
|
393
513
|
def build_request(method)
|
394
514
|
Request.create(method) do |req|
|
395
|
-
req.params =
|
396
|
-
req.headers =
|
397
|
-
req.options =
|
515
|
+
req.params = params.dup
|
516
|
+
req.headers = headers.dup
|
517
|
+
req.options = options
|
398
518
|
yield(req) if block_given?
|
399
519
|
end
|
400
520
|
end
|
401
521
|
|
402
|
-
#
|
522
|
+
# Build an absolute URL based on url_prefix.
|
403
523
|
#
|
404
|
-
# url
|
405
|
-
# params
|
524
|
+
# @param url [String, URI]
|
525
|
+
# @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to
|
526
|
+
# replace the query values
|
406
527
|
# of the resulting url (default: nil).
|
407
528
|
#
|
408
|
-
#
|
529
|
+
# @return [URI]
|
409
530
|
def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
|
410
|
-
url = nil if url.respond_to?(:empty?)
|
531
|
+
url = nil if url.respond_to?(:empty?) && url.empty?
|
411
532
|
base = url_prefix
|
412
|
-
if url
|
533
|
+
if url && base.path && base.path !~ %r{/$}
|
413
534
|
base = base.dup
|
414
|
-
base.path = base.path + '/'
|
535
|
+
base.path = base.path + '/' # ensure trailing slash
|
415
536
|
end
|
416
537
|
uri = url ? base + url : base
|
417
|
-
|
418
|
-
|
538
|
+
if params
|
539
|
+
uri.query = params.to_query(params_encoder || options.params_encoder)
|
540
|
+
end
|
541
|
+
# rubocop:disable Style/SafeNavigation
|
542
|
+
uri.query = nil if uri.query && uri.query.empty?
|
543
|
+
# rubocop:enable Style/SafeNavigation
|
419
544
|
uri
|
420
545
|
end
|
421
546
|
|
422
|
-
#
|
547
|
+
# Creates a duplicate of this Faraday::Connection.
|
423
548
|
#
|
424
|
-
#
|
549
|
+
# @api private
|
550
|
+
#
|
551
|
+
# @return [Faraday::Connection]
|
425
552
|
def dup
|
426
553
|
self.class.new(build_exclusive_url,
|
427
|
-
:
|
428
|
-
:
|
429
|
-
:
|
430
|
-
:
|
431
|
-
:
|
554
|
+
headers: headers.dup,
|
555
|
+
params: params.dup,
|
556
|
+
builder: builder.dup,
|
557
|
+
ssl: ssl.dup,
|
558
|
+
request: options.dup)
|
432
559
|
end
|
433
560
|
|
434
|
-
#
|
561
|
+
# Yields username and password extracted from a URI if they both exist.
|
562
|
+
#
|
563
|
+
# @param uri [URI]
|
564
|
+
# @yield [username, password] any username and password
|
565
|
+
# @yieldparam username [String] any username from URI
|
566
|
+
# @yieldparam password [String] any password from URI
|
567
|
+
# @return [void]
|
568
|
+
# @api private
|
435
569
|
def with_uri_credentials(uri)
|
436
|
-
|
437
|
-
|
438
|
-
|
570
|
+
return unless uri.user && uri.password
|
571
|
+
|
572
|
+
yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
|
439
573
|
end
|
440
574
|
|
441
575
|
def set_authorization_header(header_type, *args)
|
442
|
-
header = Faraday::Request
|
443
|
-
|
576
|
+
header = Faraday::Request
|
577
|
+
.lookup_middleware(header_type)
|
578
|
+
.header(*args)
|
579
|
+
|
444
580
|
headers[Faraday::Request::Authorization::KEY] = header
|
445
581
|
end
|
446
582
|
|
447
583
|
def proxy_from_env(url)
|
448
584
|
return if Faraday.ignore_env_proxy
|
585
|
+
|
449
586
|
uri = nil
|
450
587
|
if URI.parse('').respond_to?(:find_proxy)
|
451
588
|
case url
|
452
589
|
when String
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
590
|
+
uri = Utils.URI(url)
|
591
|
+
uri = URI.parse("#{uri.scheme}://#{uri.hostname}").find_proxy
|
592
|
+
when URI
|
593
|
+
uri = url.find_proxy
|
594
|
+
when nil
|
595
|
+
uri = find_default_proxy
|
459
596
|
end
|
460
597
|
else
|
461
598
|
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
@@ -466,19 +603,24 @@ module Faraday
|
|
466
603
|
|
467
604
|
def find_default_proxy
|
468
605
|
uri = ENV['http_proxy']
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
606
|
+
return unless uri && !uri.empty?
|
607
|
+
|
608
|
+
uri = 'http://' + uri if uri !~ /^http/i
|
609
|
+
uri
|
473
610
|
end
|
474
611
|
|
475
612
|
def proxy_for_request(url)
|
476
|
-
return
|
613
|
+
return proxy if @manual_proxy
|
614
|
+
|
477
615
|
if url && Utils.URI(url).absolute?
|
478
616
|
proxy_from_env(url)
|
479
617
|
else
|
480
|
-
|
618
|
+
proxy
|
481
619
|
end
|
482
620
|
end
|
621
|
+
|
622
|
+
def support_parallel?(adapter)
|
623
|
+
adapter&.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
|
624
|
+
end
|
483
625
|
end
|
484
626
|
end
|