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