faraday 0.6.0 → 0.9.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 +7 -0
- data/.document +6 -0
- data/CHANGELOG.md +15 -0
- data/CONTRIBUTING.md +36 -0
- data/Gemfile +25 -15
- data/{LICENSE → LICENSE.md} +1 -1
- data/README.md +187 -137
- data/Rakefile +38 -101
- data/faraday.gemspec +26 -81
- data/lib/faraday/adapter/em_http.rb +237 -0
- data/lib/faraday/adapter/em_http_ssl_patch.rb +56 -0
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +66 -0
- data/lib/faraday/adapter/em_synchrony.rb +65 -38
- data/lib/faraday/adapter/excon.rb +60 -9
- data/lib/faraday/adapter/httpclient.rb +106 -0
- data/lib/faraday/adapter/net_http.rb +89 -38
- data/lib/faraday/adapter/net_http_persistent.rb +47 -0
- data/lib/faraday/adapter/patron.rb +46 -9
- data/lib/faraday/adapter/rack.rb +58 -0
- data/lib/faraday/adapter/test.rb +68 -28
- data/lib/faraday/adapter/typhoeus.rb +94 -16
- data/lib/faraday/adapter.rb +33 -25
- data/lib/faraday/autoload.rb +85 -0
- data/lib/faraday/connection.rb +342 -134
- data/lib/faraday/error.rb +44 -29
- data/lib/faraday/middleware.rb +18 -10
- data/lib/faraday/options.rb +350 -0
- data/lib/faraday/parameters.rb +193 -0
- data/lib/faraday/rack_builder.rb +212 -0
- data/lib/faraday/request/authorization.rb +42 -0
- data/lib/faraday/request/basic_authentication.rb +13 -0
- data/lib/faraday/request/instrumentation.rb +36 -0
- data/lib/faraday/request/multipart.rb +15 -15
- data/lib/faraday/request/retry.rb +118 -0
- data/lib/faraday/request/token_authentication.rb +15 -0
- data/lib/faraday/request/url_encoded.rb +8 -9
- data/lib/faraday/request.rb +46 -45
- data/lib/faraday/response/logger.rb +4 -4
- data/lib/faraday/response/raise_error.rb +8 -3
- data/lib/faraday/response.rb +20 -25
- data/lib/faraday/upload_io.rb +51 -7
- data/lib/faraday/utils.rb +240 -44
- data/lib/faraday.rb +218 -38
- data/script/console +7 -0
- data/script/generate_certs +42 -0
- data/script/package +7 -0
- data/script/proxy-server +42 -0
- data/script/release +17 -0
- data/script/server +36 -0
- data/script/test +172 -0
- data/test/adapters/default_test.rb +14 -0
- data/test/adapters/em_http_test.rb +20 -0
- data/test/adapters/em_synchrony_test.rb +20 -0
- data/test/adapters/excon_test.rb +20 -0
- data/test/adapters/httpclient_test.rb +21 -0
- data/test/adapters/integration.rb +254 -0
- data/test/adapters/logger_test.rb +3 -3
- data/test/adapters/net_http_persistent_test.rb +20 -0
- data/test/adapters/net_http_test.rb +6 -25
- data/test/adapters/patron_test.rb +20 -0
- data/test/adapters/rack_test.rb +31 -0
- data/test/adapters/test_middleware_test.rb +74 -3
- data/test/adapters/typhoeus_test.rb +28 -0
- data/test/authentication_middleware_test.rb +65 -0
- data/test/composite_read_io_test.rb +111 -0
- data/test/connection_test.rb +381 -104
- data/test/env_test.rb +116 -40
- data/test/helper.rb +61 -25
- data/test/live_server.rb +55 -29
- data/test/middleware/instrumentation_test.rb +88 -0
- data/test/middleware/retry_test.rb +109 -0
- data/test/middleware_stack_test.rb +87 -5
- data/test/multibyte.txt +1 -0
- data/test/options_test.rb +252 -0
- data/test/request_middleware_test.rb +78 -21
- data/test/response_middleware_test.rb +32 -7
- data/test/strawberry.rb +2 -0
- data/test/utils_test.rb +58 -0
- metadata +116 -117
- data/lib/faraday/adapter/action_dispatch.rb +0 -30
- data/lib/faraday/builder.rb +0 -137
- data/lib/faraday/request/json.rb +0 -31
- data/test/adapters/live_test.rb +0 -186
data/lib/faraday/connection.rb
CHANGED
|
@@ -1,137 +1,302 @@
|
|
|
1
|
-
require 'addressable/uri'
|
|
2
|
-
require 'set'
|
|
3
|
-
require 'base64'
|
|
4
|
-
|
|
5
1
|
module Faraday
|
|
2
|
+
# Public: Connection objects manage the default properties and the middleware
|
|
3
|
+
# stack for fulfilling an HTTP request.
|
|
4
|
+
#
|
|
5
|
+
# Examples
|
|
6
|
+
#
|
|
7
|
+
# conn = Faraday::Connection.new 'http://sushi.com'
|
|
8
|
+
#
|
|
9
|
+
# # GET http://sushi.com/nigiri
|
|
10
|
+
# conn.get 'nigiri'
|
|
11
|
+
# # => #<Faraday::Response>
|
|
12
|
+
#
|
|
6
13
|
class Connection
|
|
7
|
-
|
|
14
|
+
# A Set of allowed HTTP verbs.
|
|
15
|
+
METHODS = Set.new [:get, :post, :put, :delete, :head, :patch, :options]
|
|
16
|
+
|
|
17
|
+
# Public: Returns a Hash of URI query unencoded key/value pairs.
|
|
18
|
+
attr_reader :params
|
|
19
|
+
|
|
20
|
+
# Public: Returns a Hash of unencoded HTTP header key/value pairs.
|
|
21
|
+
attr_reader :headers
|
|
22
|
+
|
|
23
|
+
# Public: Returns a URI with the prefix used for all requests from this
|
|
24
|
+
# Connection. This includes a default host name, scheme, port, and path.
|
|
25
|
+
attr_reader :url_prefix
|
|
26
|
+
|
|
27
|
+
# Public: Returns the Faraday::Builder for this Connection.
|
|
28
|
+
attr_reader :builder
|
|
29
|
+
|
|
30
|
+
# Public: Returns a Hash of the request options.
|
|
31
|
+
attr_reader :options
|
|
32
|
+
|
|
33
|
+
# Public: Returns a Hash of the SSL options.
|
|
34
|
+
attr_reader :ssl
|
|
8
35
|
|
|
9
|
-
|
|
10
|
-
|
|
36
|
+
# Public: Returns the parallel manager for this Connection.
|
|
37
|
+
attr_reader :parallel_manager
|
|
11
38
|
|
|
12
|
-
|
|
13
|
-
|
|
39
|
+
# Public: Sets the default parallel manager for this connection.
|
|
40
|
+
attr_writer :default_parallel_manager
|
|
14
41
|
|
|
15
|
-
# :
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
|
|
42
|
+
# Public: Initializes a new Faraday::Connection.
|
|
43
|
+
#
|
|
44
|
+
# url - URI or String base URL to use as a prefix for all
|
|
45
|
+
# requests (optional).
|
|
46
|
+
# options - Hash or Faraday::ConnectionOptions.
|
|
47
|
+
# :url - URI or String base URL (default: "http:/").
|
|
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 - URI, String or Hash of HTTP proxy options
|
|
53
|
+
# (default: "http_proxy" environment variable).
|
|
54
|
+
# :uri - URI or String
|
|
55
|
+
# :user - String (optional)
|
|
56
|
+
# :password - String (optional)
|
|
57
|
+
def initialize(url = nil, options = nil)
|
|
21
58
|
if url.is_a?(Hash)
|
|
22
|
-
options = url
|
|
23
|
-
url = options
|
|
24
|
-
end
|
|
25
|
-
@headers = Headers.new
|
|
26
|
-
@params = {}
|
|
27
|
-
@options = options[:request] || {}
|
|
28
|
-
@ssl = options[:ssl] || {}
|
|
29
|
-
@parallel_manager = options[:parallel]
|
|
30
|
-
self.url_prefix = url if url
|
|
31
|
-
proxy(options[:proxy])
|
|
32
|
-
merge_params @params, options[:params] if options[:params]
|
|
33
|
-
merge_headers @headers, options[:headers] if options[:headers]
|
|
34
|
-
|
|
35
|
-
if block_given?
|
|
36
|
-
@builder = Builder.create { |b| yield b }
|
|
59
|
+
options = ConnectionOptions.from(url)
|
|
60
|
+
url = options.url
|
|
37
61
|
else
|
|
38
|
-
|
|
62
|
+
options = ConnectionOptions.from(options)
|
|
39
63
|
end
|
|
40
|
-
end
|
|
41
64
|
|
|
42
|
-
|
|
43
|
-
@
|
|
44
|
-
|
|
65
|
+
@parallel_manager = nil
|
|
66
|
+
@headers = Utils::Headers.new
|
|
67
|
+
@params = Utils::ParamsHash.new
|
|
68
|
+
@options = options.request
|
|
69
|
+
@ssl = options.ssl
|
|
70
|
+
@default_parallel_manager = options.parallel_manager
|
|
45
71
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
@builder = options.builder || begin
|
|
73
|
+
# pass an empty block to Builder so it doesn't assume default middleware
|
|
74
|
+
options.new_builder(block_given? ? Proc.new { |b| } : nil)
|
|
75
|
+
end
|
|
49
76
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
77
|
+
self.url_prefix = url || 'http:/'
|
|
78
|
+
|
|
79
|
+
@params.update(options.params) if options.params
|
|
80
|
+
@headers.update(options.headers) if options.headers
|
|
81
|
+
|
|
82
|
+
@proxy = nil
|
|
83
|
+
proxy(options.fetch(:proxy) {
|
|
84
|
+
uri = ENV['http_proxy']
|
|
85
|
+
if uri && !uri.empty?
|
|
86
|
+
uri = 'http://' + uri if uri !~ /^http/i
|
|
87
|
+
uri
|
|
88
|
+
end
|
|
89
|
+
})
|
|
53
90
|
|
|
54
|
-
|
|
55
|
-
|
|
91
|
+
yield(self) if block_given?
|
|
92
|
+
|
|
93
|
+
@headers[:user_agent] ||= "Faraday v#{VERSION}"
|
|
56
94
|
end
|
|
57
95
|
|
|
58
|
-
|
|
59
|
-
|
|
96
|
+
# Public: Sets the Hash of URI query unencoded key/value pairs.
|
|
97
|
+
def params=(hash)
|
|
98
|
+
@params.replace hash
|
|
60
99
|
end
|
|
61
100
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
101
|
+
# Public: Sets the Hash of unencoded HTTP header key/value pairs.
|
|
102
|
+
def headers=(hash)
|
|
103
|
+
@headers.replace hash
|
|
65
104
|
end
|
|
66
105
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
106
|
+
extend Forwardable
|
|
107
|
+
|
|
108
|
+
def_delegators :builder, :build, :use, :request, :response, :adapter, :app
|
|
109
|
+
|
|
110
|
+
# Public: Makes an HTTP request without a body.
|
|
111
|
+
#
|
|
112
|
+
# url - The optional String base URL to use as a prefix for all
|
|
113
|
+
# requests. Can also be the options Hash.
|
|
114
|
+
# params - Hash of URI query unencoded key/value pairs.
|
|
115
|
+
# headers - Hash of unencoded HTTP header key/value pairs.
|
|
116
|
+
#
|
|
117
|
+
# Examples
|
|
118
|
+
#
|
|
119
|
+
# conn.get '/items', {:page => 1}, :accept => 'application/json'
|
|
120
|
+
# conn.head '/items/1'
|
|
121
|
+
#
|
|
122
|
+
# # ElasticSearch example sending a body with GET.
|
|
123
|
+
# conn.get '/twitter/tweet/_search' do |req|
|
|
124
|
+
# req.headers[:content_type] = 'application/json'
|
|
125
|
+
# req.params[:routing] = 'kimchy'
|
|
126
|
+
# req.body = JSON.generate(:query => {...})
|
|
127
|
+
# end
|
|
128
|
+
#
|
|
129
|
+
# Yields a Faraday::Response for further request customizations.
|
|
130
|
+
# Returns a Faraday::Response.
|
|
131
|
+
#
|
|
132
|
+
# Signature
|
|
133
|
+
#
|
|
134
|
+
# <verb>(url = nil, params = nil, headers = nil)
|
|
135
|
+
#
|
|
136
|
+
# verb - An HTTP verb: get, head, or delete.
|
|
137
|
+
%w[get head delete].each do |method|
|
|
138
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
139
|
+
def #{method}(url = nil, params = nil, headers = nil)
|
|
140
|
+
run_request(:#{method}, url, nil, headers) { |request|
|
|
141
|
+
request.params.update(params) if params
|
|
142
|
+
yield(request) if block_given?
|
|
143
|
+
}
|
|
144
|
+
end
|
|
145
|
+
RUBY
|
|
70
146
|
end
|
|
71
147
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
148
|
+
# Public: Makes an HTTP request with a body.
|
|
149
|
+
#
|
|
150
|
+
# url - The optional String base URL to use as a prefix for all
|
|
151
|
+
# requests. Can also be the options Hash.
|
|
152
|
+
# body - The String body for the request.
|
|
153
|
+
# headers - Hash of unencoded HTTP header key/value pairs.
|
|
154
|
+
#
|
|
155
|
+
# Examples
|
|
156
|
+
#
|
|
157
|
+
# conn.post '/items', data, :content_type => 'application/json'
|
|
158
|
+
#
|
|
159
|
+
# # Simple ElasticSearch indexing sample.
|
|
160
|
+
# conn.post '/twitter/tweet' do |req|
|
|
161
|
+
# req.headers[:content_type] = 'application/json'
|
|
162
|
+
# req.params[:routing] = 'kimchy'
|
|
163
|
+
# req.body = JSON.generate(:user => 'kimchy', ...)
|
|
164
|
+
# end
|
|
165
|
+
#
|
|
166
|
+
# Yields a Faraday::Response for further request customizations.
|
|
167
|
+
# Returns a Faraday::Response.
|
|
168
|
+
#
|
|
169
|
+
# Signature
|
|
170
|
+
#
|
|
171
|
+
# <verb>(url = nil, body = nil, headers = nil)
|
|
172
|
+
#
|
|
173
|
+
# verb - An HTTP verb: post, put, or patch.
|
|
174
|
+
%w[post put patch].each do |method|
|
|
175
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
176
|
+
def #{method}(url = nil, body = nil, headers = nil, &block)
|
|
177
|
+
run_request(:#{method}, url, body, headers, &block)
|
|
178
|
+
end
|
|
179
|
+
RUBY
|
|
75
180
|
end
|
|
76
181
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
182
|
+
# Public: Sets up the Authorization header with these credentials, encoded
|
|
183
|
+
# with base64.
|
|
184
|
+
#
|
|
185
|
+
# login - The authentication login.
|
|
186
|
+
# pass - The authentication password.
|
|
187
|
+
#
|
|
188
|
+
# Examples
|
|
189
|
+
#
|
|
190
|
+
# conn.basic_auth 'Aladdin', 'open sesame'
|
|
191
|
+
# conn.headers['Authorization']
|
|
192
|
+
# # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
|
|
193
|
+
#
|
|
194
|
+
# Returns nothing.
|
|
195
|
+
def basic_auth(login, pass)
|
|
196
|
+
set_authorization_header(:basic_auth, login, pass)
|
|
80
197
|
end
|
|
81
198
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
199
|
+
# Public: Sets up the Authorization header with the given token.
|
|
200
|
+
#
|
|
201
|
+
# token - The String token.
|
|
202
|
+
# options - Optional Hash of extra token options.
|
|
203
|
+
#
|
|
204
|
+
# Examples
|
|
205
|
+
#
|
|
206
|
+
# conn.token_auth 'abcdef', :foo => 'bar'
|
|
207
|
+
# conn.headers['Authorization']
|
|
208
|
+
# # => "Token token=\"abcdef\",
|
|
209
|
+
# foo=\"bar\""
|
|
210
|
+
#
|
|
211
|
+
# Returns nothing.
|
|
212
|
+
def token_auth(token, options = nil)
|
|
213
|
+
set_authorization_header(:token_auth, token, options)
|
|
85
214
|
end
|
|
86
215
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
216
|
+
# Public: Sets up a custom Authorization header.
|
|
217
|
+
#
|
|
218
|
+
# type - The String authorization type.
|
|
219
|
+
# token - The String or Hash token. A String value is taken literally, and
|
|
220
|
+
# a Hash is encoded into comma separated key/value pairs.
|
|
221
|
+
#
|
|
222
|
+
# Examples
|
|
223
|
+
#
|
|
224
|
+
# conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
|
|
225
|
+
# conn.headers['Authorization']
|
|
226
|
+
# # => "Bearer mF_9.B5f-4.1JqM"
|
|
227
|
+
#
|
|
228
|
+
# conn.authorization :Token, :token => 'abcdef', :foo => 'bar'
|
|
229
|
+
# conn.headers['Authorization']
|
|
230
|
+
# # => "Token token=\"abcdef\",
|
|
231
|
+
# foo=\"bar\""
|
|
232
|
+
#
|
|
233
|
+
# Returns nothing.
|
|
234
|
+
def authorization(type, token)
|
|
235
|
+
set_authorization_header(:authorization, type, token)
|
|
91
236
|
end
|
|
92
237
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
238
|
+
# Internal: Traverse the middleware stack in search of a
|
|
239
|
+
# parallel-capable adapter.
|
|
240
|
+
#
|
|
241
|
+
# Yields in case of not found.
|
|
242
|
+
#
|
|
243
|
+
# Returns a parallel manager or nil if not found.
|
|
244
|
+
def default_parallel_manager
|
|
245
|
+
@default_parallel_manager ||= begin
|
|
246
|
+
handler = @builder.handlers.detect do |h|
|
|
247
|
+
h.klass.respond_to?(:supports_parallel?) and h.klass.supports_parallel?
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
if handler
|
|
251
|
+
handler.klass.setup_parallel_manager
|
|
252
|
+
elsif block_given?
|
|
253
|
+
yield
|
|
254
|
+
end
|
|
97
255
|
end
|
|
98
|
-
# 21 = "Authorization: Token ".size
|
|
99
|
-
comma = ",\n#{' ' * 21}"
|
|
100
|
-
@headers['authorization'] = "Token #{values * comma}"
|
|
101
256
|
end
|
|
102
257
|
|
|
258
|
+
# Public: Determine if this Faraday::Connection can make parallel requests.
|
|
259
|
+
#
|
|
260
|
+
# Returns true or false.
|
|
103
261
|
def in_parallel?
|
|
104
262
|
!!@parallel_manager
|
|
105
263
|
end
|
|
106
264
|
|
|
107
|
-
|
|
108
|
-
|
|
265
|
+
# Public: Sets up the parallel manager to make a set of requests.
|
|
266
|
+
#
|
|
267
|
+
# manager - The parallel manager that this Connection's Adapter uses.
|
|
268
|
+
#
|
|
269
|
+
# Yields a block to execute multiple requests.
|
|
270
|
+
# Returns nothing.
|
|
271
|
+
def in_parallel(manager = nil)
|
|
272
|
+
@parallel_manager = manager || default_parallel_manager {
|
|
273
|
+
warn "Warning: `in_parallel` called but no parallel-capable adapter on Faraday stack"
|
|
274
|
+
warn caller[2,10].join("\n")
|
|
275
|
+
nil
|
|
276
|
+
}
|
|
109
277
|
yield
|
|
110
278
|
@parallel_manager && @parallel_manager.run
|
|
111
279
|
ensure
|
|
112
280
|
@parallel_manager = nil
|
|
113
281
|
end
|
|
114
282
|
|
|
283
|
+
# Public: Gets or Sets the Hash proxy options.
|
|
115
284
|
def proxy(arg = nil)
|
|
116
285
|
return @proxy if arg.nil?
|
|
117
|
-
|
|
118
|
-
@proxy =
|
|
119
|
-
case arg
|
|
120
|
-
when String then {:uri => proxy_arg_to_uri(arg)}
|
|
121
|
-
when URI then {:uri => arg}
|
|
122
|
-
when Hash
|
|
123
|
-
if arg[:uri] = proxy_arg_to_uri(arg[:uri])
|
|
124
|
-
arg
|
|
125
|
-
else
|
|
126
|
-
raise ArgumentError, "no :uri option."
|
|
127
|
-
end
|
|
128
|
-
end
|
|
286
|
+
@proxy = ProxyOptions.from(arg)
|
|
129
287
|
end
|
|
130
288
|
|
|
131
|
-
|
|
289
|
+
def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port=
|
|
290
|
+
def_delegator :url_prefix, :path, :path_prefix
|
|
291
|
+
|
|
292
|
+
# Public: Parses the giving url with URI and stores the individual
|
|
132
293
|
# components in this connection. These components serve as defaults for
|
|
133
294
|
# requests made by this connection.
|
|
134
295
|
#
|
|
296
|
+
# url - A String or URI.
|
|
297
|
+
#
|
|
298
|
+
# Examples
|
|
299
|
+
#
|
|
135
300
|
# conn = Faraday::Connection.new { ... }
|
|
136
301
|
# conn.url_prefix = "https://sushi.com/api"
|
|
137
302
|
# conn.scheme # => https
|
|
@@ -139,86 +304,129 @@ module Faraday
|
|
|
139
304
|
#
|
|
140
305
|
# conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
|
|
141
306
|
#
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
self.host = uri.host
|
|
146
|
-
self.port = uri.port
|
|
307
|
+
# Returns the parsed URI from teh given input..
|
|
308
|
+
def url_prefix=(url, encoder = nil)
|
|
309
|
+
uri = @url_prefix = Utils.URI(url)
|
|
147
310
|
self.path_prefix = uri.path
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
311
|
+
|
|
312
|
+
params.merge_query(uri.query, encoder)
|
|
313
|
+
uri.query = nil
|
|
314
|
+
|
|
315
|
+
with_uri_credentials(uri) do |user, password|
|
|
316
|
+
basic_auth user, password
|
|
317
|
+
uri.user = uri.password = nil
|
|
153
318
|
end
|
|
319
|
+
|
|
320
|
+
uri
|
|
154
321
|
end
|
|
155
322
|
|
|
156
|
-
#
|
|
323
|
+
# Public: Sets the path prefix and ensures that it always has a leading
|
|
324
|
+
# slash.
|
|
325
|
+
#
|
|
326
|
+
# value - A String.
|
|
327
|
+
#
|
|
328
|
+
# Returns the new String path prefix.
|
|
157
329
|
def path_prefix=(value)
|
|
158
|
-
if value
|
|
159
|
-
value
|
|
160
|
-
value
|
|
330
|
+
url_prefix.path = if value
|
|
331
|
+
value = '/' + value unless value[0,1] == '/'
|
|
332
|
+
value
|
|
161
333
|
end
|
|
162
|
-
@path_prefix = value
|
|
163
334
|
end
|
|
164
335
|
|
|
336
|
+
# Public: Takes a relative url for a request and combines it with the defaults
|
|
337
|
+
# set on the connection instance.
|
|
338
|
+
#
|
|
339
|
+
# conn = Faraday::Connection.new { ... }
|
|
340
|
+
# conn.url_prefix = "https://sushi.com/api?token=abc"
|
|
341
|
+
# conn.scheme # => https
|
|
342
|
+
# conn.path_prefix # => "/api"
|
|
343
|
+
#
|
|
344
|
+
# conn.build_url("nigiri?page=2") # => https://sushi.com/api/nigiri?token=abc&page=2
|
|
345
|
+
# conn.build_url("nigiri", :page => 2) # => https://sushi.com/api/nigiri?token=abc&page=2
|
|
346
|
+
#
|
|
347
|
+
def build_url(url = nil, extra_params = nil)
|
|
348
|
+
uri = build_exclusive_url(url)
|
|
349
|
+
|
|
350
|
+
query_values = params.dup.merge_query(uri.query, options.params_encoder)
|
|
351
|
+
query_values.update extra_params if extra_params
|
|
352
|
+
uri.query = query_values.empty? ? nil : query_values.to_query(options.params_encoder)
|
|
353
|
+
|
|
354
|
+
uri
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# Builds and runs the Faraday::Request.
|
|
358
|
+
#
|
|
359
|
+
# method - The Symbol HTTP method.
|
|
360
|
+
# url - The String or URI to access.
|
|
361
|
+
# body - The String body
|
|
362
|
+
# headers - Hash of unencoded HTTP header key/value pairs.
|
|
363
|
+
#
|
|
364
|
+
# Returns a Faraday::Response.
|
|
165
365
|
def run_request(method, url, body, headers)
|
|
166
366
|
if !METHODS.include?(method)
|
|
167
367
|
raise ArgumentError, "unknown http method: #{method}"
|
|
168
368
|
end
|
|
169
369
|
|
|
170
|
-
|
|
370
|
+
request = build_request(method) do |req|
|
|
171
371
|
req.url(url) if url
|
|
172
372
|
req.headers.update(headers) if headers
|
|
173
373
|
req.body = body if body
|
|
174
|
-
yield
|
|
374
|
+
yield(req) if block_given?
|
|
175
375
|
end
|
|
376
|
+
|
|
377
|
+
builder.build_response(self, request)
|
|
176
378
|
end
|
|
177
379
|
|
|
178
|
-
#
|
|
179
|
-
# set on the connection instance.
|
|
380
|
+
# Creates and configures the request object.
|
|
180
381
|
#
|
|
181
|
-
#
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
382
|
+
# Returns the new Request.
|
|
383
|
+
def build_request(method)
|
|
384
|
+
Request.create(method) do |req|
|
|
385
|
+
req.params = self.params.dup
|
|
386
|
+
req.headers = self.headers.dup
|
|
387
|
+
req.options = self.options.merge(:proxy => self.proxy)
|
|
388
|
+
yield(req) if block_given?
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# Internal: Build an absolute URL based on url_prefix.
|
|
185
393
|
#
|
|
186
|
-
#
|
|
187
|
-
#
|
|
394
|
+
# url - A String or URI-like object
|
|
395
|
+
# params - A Faraday::Utils::ParamsHash to replace the query values
|
|
396
|
+
# of the resulting url (default: nil).
|
|
188
397
|
#
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
398
|
+
# Returns the resulting URI instance.
|
|
399
|
+
def build_exclusive_url(url = nil, params = nil)
|
|
400
|
+
url = nil if url.respond_to?(:empty?) and url.empty?
|
|
401
|
+
base = url_prefix
|
|
402
|
+
if url and base.path and base.path !~ /\/$/
|
|
403
|
+
base = base.dup
|
|
404
|
+
base.path = base.path + '/' # ensure trailing slash
|
|
193
405
|
end
|
|
194
|
-
uri
|
|
195
|
-
uri.
|
|
196
|
-
uri.
|
|
197
|
-
replace_query(uri, params)
|
|
406
|
+
uri = url ? base + url : base
|
|
407
|
+
uri.query = params.to_query(options.params_encoder) if params
|
|
408
|
+
uri.query = nil if uri.query and uri.query.empty?
|
|
198
409
|
uri
|
|
199
410
|
end
|
|
200
411
|
|
|
412
|
+
# Internal: Creates a duplicate of this Faraday::Connection.
|
|
413
|
+
#
|
|
414
|
+
# Returns a Faraday::Connection.
|
|
201
415
|
def dup
|
|
202
|
-
self.class.new(
|
|
416
|
+
self.class.new(build_exclusive_url, :headers => headers.dup, :params => params.dup, :builder => builder.dup, :ssl => ssl.dup)
|
|
203
417
|
end
|
|
204
418
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if uri.
|
|
208
|
-
|
|
419
|
+
# Internal: Yields username and password extracted from a URI if they both exist.
|
|
420
|
+
def with_uri_credentials(uri)
|
|
421
|
+
if uri.user and uri.password
|
|
422
|
+
yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
|
|
209
423
|
end
|
|
210
|
-
if params && !params.empty?
|
|
211
|
-
merge_params(url_params, params)
|
|
212
|
-
end
|
|
213
|
-
uri.query = url_params.empty? ? nil : build_query(url_params)
|
|
214
|
-
uri
|
|
215
424
|
end
|
|
216
425
|
|
|
217
|
-
def
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
end
|
|
426
|
+
def set_authorization_header(header_type, *args)
|
|
427
|
+
header = Faraday::Request.lookup_middleware(header_type).
|
|
428
|
+
header(*args)
|
|
429
|
+
headers[Faraday::Request::Authorization::KEY] = header
|
|
222
430
|
end
|
|
223
431
|
end
|
|
224
432
|
end
|
data/lib/faraday/error.rb
CHANGED
|
@@ -1,38 +1,53 @@
|
|
|
1
1
|
module Faraday
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@wrapped_exception = nil
|
|
8
|
-
@response = nil
|
|
9
|
-
|
|
10
|
-
if ex.respond_to?(:backtrace)
|
|
11
|
-
super(ex.message)
|
|
12
|
-
@wrapped_exception = ex
|
|
13
|
-
elsif ex.respond_to?(:each_key)
|
|
14
|
-
super("the server responded with status #{ex[:status]}")
|
|
15
|
-
@response = ex
|
|
16
|
-
else
|
|
17
|
-
super(ex.to_s)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
2
|
+
class Error < StandardError; end
|
|
3
|
+
class MissingDependency < Error; end
|
|
4
|
+
|
|
5
|
+
class ClientError < Error
|
|
6
|
+
attr_reader :response
|
|
20
7
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
8
|
+
def initialize(ex, response = nil)
|
|
9
|
+
@wrapped_exception = nil
|
|
10
|
+
@response = response
|
|
11
|
+
|
|
12
|
+
if ex.respond_to?(:backtrace)
|
|
13
|
+
super(ex.message)
|
|
14
|
+
@wrapped_exception = ex
|
|
15
|
+
elsif ex.respond_to?(:each_key)
|
|
16
|
+
super("the server responded with status #{ex[:status]}")
|
|
17
|
+
@response = ex
|
|
18
|
+
else
|
|
19
|
+
super(ex.to_s)
|
|
27
20
|
end
|
|
21
|
+
end
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
def backtrace
|
|
24
|
+
if @wrapped_exception
|
|
25
|
+
@wrapped_exception.backtrace
|
|
26
|
+
else
|
|
27
|
+
super
|
|
31
28
|
end
|
|
32
29
|
end
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
def inspect
|
|
32
|
+
%(#<#{self.class}>)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class ConnectionFailed < ClientError; end
|
|
37
|
+
class ResourceNotFound < ClientError; end
|
|
38
|
+
class ParsingError < ClientError; end
|
|
39
|
+
|
|
40
|
+
class TimeoutError < ClientError
|
|
41
|
+
def initialize(ex = nil)
|
|
42
|
+
super(ex || "timeout")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class SSLError < ClientError
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
[:MissingDependency, :ClientError, :ConnectionFailed, :ResourceNotFound,
|
|
50
|
+
:ParsingError, :TimeoutError, :SSLError].each do |const|
|
|
51
|
+
Error.const_set(const, Faraday.const_get(const))
|
|
37
52
|
end
|
|
38
53
|
end
|