faraday 0.17.3 → 1.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +52 -8
- data/LICENSE.md +1 -1
- data/README.md +18 -358
- data/Rakefile +1 -7
- data/examples/client_spec.rb +65 -0
- data/examples/client_test.rb +79 -0
- data/lib/faraday.rb +94 -175
- data/lib/faraday/adapter.rb +82 -22
- data/lib/faraday/adapter/em_http.rb +142 -99
- data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
- 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 +98 -56
- data/lib/faraday/adapter/httpclient.rb +83 -59
- data/lib/faraday/adapter/net_http.rb +130 -63
- data/lib/faraday/adapter/net_http_persistent.rb +50 -27
- data/lib/faraday/adapter/patron.rb +80 -43
- data/lib/faraday/adapter/rack.rb +30 -13
- data/lib/faraday/adapter/test.rb +86 -53
- data/lib/faraday/adapter/typhoeus.rb +4 -1
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/autoload.rb +47 -36
- data/lib/faraday/connection.rb +312 -182
- data/lib/faraday/dependency_loader.rb +37 -0
- data/lib/faraday/encoders/flat_params_encoder.rb +98 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
- data/lib/faraday/error.rb +9 -35
- data/lib/faraday/file_part.rb +128 -0
- data/lib/faraday/logging/formatter.rb +105 -0
- data/lib/faraday/middleware.rb +12 -28
- data/lib/faraday/middleware_registry.rb +129 -0
- data/lib/faraday/options.rb +32 -183
- 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 +22 -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 +66 -55
- data/lib/faraday/request.rb +68 -36
- data/lib/faraday/request/authorization.rb +44 -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 +197 -171
- data/lib/faraday/request/token_authentication.rb +15 -10
- data/lib/faraday/request/url_encoded.rb +43 -23
- data/lib/faraday/response.rb +24 -14
- data/lib/faraday/response/logger.rb +22 -69
- data/lib/faraday/response/raise_error.rb +38 -18
- data/lib/faraday/utils.rb +36 -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
- data/spec/faraday/adapter/em_http_spec.rb +47 -0
- data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
- data/spec/faraday/adapter/excon_spec.rb +49 -0
- data/spec/faraday/adapter/httpclient_spec.rb +73 -0
- data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
- data/spec/faraday/adapter/net_http_spec.rb +64 -0
- data/spec/faraday/adapter/patron_spec.rb +18 -0
- data/spec/faraday/adapter/rack_spec.rb +8 -0
- data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/composite_read_io_spec.rb +80 -0
- data/spec/faraday/connection_spec.rb +691 -0
- data/spec/faraday/error_spec.rb +0 -57
- data/spec/faraday/middleware_spec.rb +26 -0
- data/spec/faraday/options/env_spec.rb +70 -0
- data/spec/faraday/options/options_spec.rb +297 -0
- data/spec/faraday/options/proxy_options_spec.rb +37 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +34 -0
- data/spec/faraday/params_encoders/nested_spec.rb +134 -0
- data/spec/faraday/rack_builder_spec.rb +196 -0
- data/spec/faraday/request/authorization_spec.rb +88 -0
- data/spec/faraday/request/instrumentation_spec.rb +76 -0
- data/spec/faraday/request/multipart_spec.rb +274 -0
- data/spec/faraday/request/retry_spec.rb +242 -0
- data/spec/faraday/request/url_encoded_spec.rb +83 -0
- data/spec/faraday/request_spec.rb +109 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/middleware_spec.rb +68 -0
- data/spec/faraday/response/raise_error_spec.rb +15 -15
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +56 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +63 -36
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +133 -0
- data/spec/support/shared_examples/adapter.rb +104 -0
- data/spec/support/shared_examples/params_encoder.rb +18 -0
- data/spec/support/shared_examples/request_method.rb +234 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- data/spec/support/webmock_rack_app.rb +68 -0
- metadata +66 -38
- data/lib/faraday/deprecate.rb +0 -107
- data/lib/faraday/upload_io.rb +0 -67
- data/spec/faraday/deprecate_spec.rb +0 -69
- data/test/adapters/default_test.rb +0 -14
- data/test/adapters/em_http_test.rb +0 -30
- data/test/adapters/em_synchrony_test.rb +0 -32
- data/test/adapters/excon_test.rb +0 -30
- data/test/adapters/httpclient_test.rb +0 -34
- data/test/adapters/integration.rb +0 -263
- data/test/adapters/logger_test.rb +0 -136
- data/test/adapters/net_http_persistent_test.rb +0 -114
- data/test/adapters/net_http_test.rb +0 -79
- data/test/adapters/patron_test.rb +0 -40
- data/test/adapters/rack_test.rb +0 -38
- data/test/adapters/test_middleware_test.rb +0 -157
- data/test/adapters/typhoeus_test.rb +0 -38
- data/test/authentication_middleware_test.rb +0 -65
- data/test/composite_read_io_test.rb +0 -109
- data/test/connection_test.rb +0 -738
- data/test/env_test.rb +0 -268
- data/test/helper.rb +0 -75
- data/test/live_server.rb +0 -67
- data/test/middleware/instrumentation_test.rb +0 -88
- data/test/middleware/retry_test.rb +0 -282
- data/test/middleware_stack_test.rb +0 -260
- data/test/multibyte.txt +0 -1
- data/test/options_test.rb +0 -333
- data/test/parameters_test.rb +0 -157
- data/test/request_middleware_test.rb +0 -126
- data/test/response_middleware_test.rb +0 -72
- data/test/strawberry.rb +0 -2
- data/test/utils_test.rb +0 -98
@@ -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/typhoeus/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,30 @@
|
|
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 = @lock.synchronize do
|
16
|
+
@constants[name]
|
17
|
+
end
|
18
|
+
return klass if klass
|
19
|
+
|
20
|
+
Object.const_get(name).tap { |c| set(c, name) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def set(klass, name = nil)
|
24
|
+
name ||= klass.to_s
|
25
|
+
@lock.synchronize do
|
26
|
+
@constants[name] = klass
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
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]
|
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,31 @@ 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
|
+
end
|
103
|
+
|
104
|
+
# Sets the Hash of URI query unencoded key/value pairs.
|
105
|
+
# @param hash [Hash]
|
95
106
|
def params=(hash)
|
96
107
|
@params.replace hash
|
97
108
|
end
|
98
109
|
|
99
|
-
#
|
110
|
+
# Sets the Hash of unencoded HTTP header key/value pairs.
|
111
|
+
# @param hash [Hash]
|
100
112
|
def headers=(hash)
|
101
113
|
@headers.replace hash
|
102
114
|
end
|
@@ -105,71 +117,163 @@ module Faraday
|
|
105
117
|
|
106
118
|
def_delegators :builder, :build, :use, :request, :response, :adapter, :app
|
107
119
|
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
|
112
|
-
|
113
|
-
|
120
|
+
# Closes the underlying resources and/or connections. In the case of
|
121
|
+
# persistent connections, this closes all currently open connections
|
122
|
+
# but does not prevent new connections from being made.
|
123
|
+
def close
|
124
|
+
app.close
|
125
|
+
end
|
126
|
+
|
127
|
+
# @!method get(url = nil, params = nil, headers = nil)
|
128
|
+
# Makes a GET HTTP request without a body.
|
129
|
+
# @!scope class
|
114
130
|
#
|
115
|
-
#
|
131
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
132
|
+
# all requests. Can also be the options Hash.
|
133
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
134
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
116
135
|
#
|
117
|
-
#
|
118
|
-
# conn.
|
136
|
+
# @example
|
137
|
+
# conn.get '/items', { page: 1 }, :accept => 'application/json'
|
119
138
|
#
|
120
139
|
# # ElasticSearch example sending a body with GET.
|
121
140
|
# conn.get '/twitter/tweet/_search' do |req|
|
122
141
|
# req.headers[:content_type] = 'application/json'
|
123
142
|
# req.params[:routing] = 'kimchy'
|
124
|
-
# req.body = JSON.generate(:
|
143
|
+
# req.body = JSON.generate(query: {...})
|
125
144
|
# end
|
126
145
|
#
|
127
|
-
#
|
128
|
-
#
|
146
|
+
# @yield [Faraday::Request] for further request customizations
|
147
|
+
# @return [Faraday::Response]
|
148
|
+
|
149
|
+
# @!method head(url = nil, params = nil, headers = nil)
|
150
|
+
# Makes a HEAD HTTP request without a body.
|
151
|
+
# @!scope class
|
152
|
+
#
|
153
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
154
|
+
# all requests. Can also be the options Hash.
|
155
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
156
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
157
|
+
#
|
158
|
+
# @example
|
159
|
+
# conn.head '/items/1'
|
160
|
+
#
|
161
|
+
# @yield [Faraday::Request] for further request customizations
|
162
|
+
# @return [Faraday::Response]
|
163
|
+
|
164
|
+
# @!method delete(url = nil, params = nil, headers = nil)
|
165
|
+
# Makes a DELETE HTTP request without a body.
|
166
|
+
# @!scope class
|
167
|
+
#
|
168
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
169
|
+
# all requests. Can also be the options Hash.
|
170
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
171
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
172
|
+
#
|
173
|
+
# @example
|
174
|
+
# conn.delete '/items/1'
|
175
|
+
#
|
176
|
+
# @yield [Faraday::Request] for further request customizations
|
177
|
+
# @return [Faraday::Response]
|
178
|
+
|
179
|
+
# @!method trace(url = nil, params = nil, headers = nil)
|
180
|
+
# Makes a TRACE HTTP request without a body.
|
181
|
+
# @!scope class
|
129
182
|
#
|
130
|
-
#
|
183
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
184
|
+
# all requests. Can also be the options Hash.
|
185
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
186
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
131
187
|
#
|
132
|
-
#
|
188
|
+
# @example
|
189
|
+
# conn.connect '/items/1'
|
133
190
|
#
|
134
|
-
#
|
135
|
-
|
191
|
+
# @yield [Faraday::Request] for further request customizations
|
192
|
+
# @return [Faraday::Response]
|
193
|
+
|
194
|
+
# @!visibility private
|
195
|
+
METHODS_WITH_QUERY.each do |method|
|
136
196
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
137
197
|
def #{method}(url = nil, params = nil, headers = nil)
|
138
|
-
run_request(:#{method}, url, nil, headers)
|
198
|
+
run_request(:#{method}, url, nil, headers) do |request|
|
139
199
|
request.params.update(params) if params
|
140
|
-
yield
|
141
|
-
|
200
|
+
yield request if block_given?
|
201
|
+
end
|
142
202
|
end
|
143
203
|
RUBY
|
144
204
|
end
|
145
205
|
|
146
|
-
#
|
206
|
+
# @overload options()
|
207
|
+
# Returns current Connection options.
|
208
|
+
#
|
209
|
+
# @overload options(url, params = nil, headers = nil)
|
210
|
+
# Makes an OPTIONS HTTP request to the given URL.
|
211
|
+
# @param url [String] String base URL to sue as a prefix for all requests.
|
212
|
+
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
213
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
214
|
+
#
|
215
|
+
# @example
|
216
|
+
# conn.options '/items/1'
|
147
217
|
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
|
151
|
-
|
218
|
+
# @yield [Faraday::Request] for further request customizations
|
219
|
+
# @return [Faraday::Response]
|
220
|
+
def options(*args)
|
221
|
+
return @options if args.size.zero?
|
222
|
+
|
223
|
+
url, params, headers = *args
|
224
|
+
run_request(:options, url, nil, headers) do |request|
|
225
|
+
request.params.update(params) if params
|
226
|
+
yield request if block_given?
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# @!method post(url = nil, body = nil, headers = nil)
|
231
|
+
# Makes a POST HTTP request with a body.
|
232
|
+
# @!scope class
|
152
233
|
#
|
153
|
-
#
|
234
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
235
|
+
# all requests. Can also be the options Hash.
|
236
|
+
# @param body [String] body for the request.
|
237
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
154
238
|
#
|
155
|
-
#
|
239
|
+
# @example
|
240
|
+
# conn.post '/items', data, content_type: 'application/json'
|
156
241
|
#
|
157
242
|
# # Simple ElasticSearch indexing sample.
|
158
243
|
# conn.post '/twitter/tweet' do |req|
|
159
244
|
# req.headers[:content_type] = 'application/json'
|
160
245
|
# req.params[:routing] = 'kimchy'
|
161
|
-
# req.body = JSON.generate(:
|
246
|
+
# req.body = JSON.generate(user: 'kimchy', ...)
|
162
247
|
# end
|
163
248
|
#
|
164
|
-
#
|
165
|
-
#
|
249
|
+
# @yield [Faraday::Request] for further request customizations
|
250
|
+
# @return [Faraday::Response]
|
251
|
+
|
252
|
+
# @!method put(url = nil, body = nil, headers = nil)
|
253
|
+
# Makes a PUT HTTP request with a body.
|
254
|
+
# @!scope class
|
255
|
+
#
|
256
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
257
|
+
# all requests. Can also be the options Hash.
|
258
|
+
# @param body [String] body for the request.
|
259
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
166
260
|
#
|
167
|
-
#
|
261
|
+
# @example
|
262
|
+
# # TODO: Make it a PUT example
|
263
|
+
# conn.post '/items', data, content_type: 'application/json'
|
168
264
|
#
|
169
|
-
#
|
265
|
+
# # Simple ElasticSearch indexing sample.
|
266
|
+
# conn.post '/twitter/tweet' do |req|
|
267
|
+
# req.headers[:content_type] = 'application/json'
|
268
|
+
# req.params[:routing] = 'kimchy'
|
269
|
+
# req.body = JSON.generate(user: 'kimchy', ...)
|
270
|
+
# end
|
170
271
|
#
|
171
|
-
#
|
172
|
-
|
272
|
+
# @yield [Faraday::Request] for further request customizations
|
273
|
+
# @return [Faraday::Response]
|
274
|
+
|
275
|
+
# @!visibility private
|
276
|
+
METHODS_WITH_BODY.each do |method|
|
173
277
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
174
278
|
def #{method}(url = nil, body = nil, headers = nil, &block)
|
175
279
|
run_request(:#{method}, url, body, headers, &block)
|
@@ -177,116 +281,110 @@ module Faraday
|
|
177
281
|
RUBY
|
178
282
|
end
|
179
283
|
|
180
|
-
#
|
284
|
+
# Sets up the Authorization header with these credentials, encoded
|
181
285
|
# with base64.
|
182
286
|
#
|
183
|
-
# login
|
184
|
-
# pass
|
287
|
+
# @param login [String] The authentication login.
|
288
|
+
# @param pass [String] The authentication password.
|
185
289
|
#
|
186
|
-
#
|
290
|
+
# @example
|
187
291
|
#
|
188
292
|
# conn.basic_auth 'Aladdin', 'open sesame'
|
189
293
|
# conn.headers['Authorization']
|
190
294
|
# # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
|
191
295
|
#
|
192
|
-
#
|
296
|
+
# @return [void]
|
193
297
|
def basic_auth(login, pass)
|
194
298
|
set_authorization_header(:basic_auth, login, pass)
|
195
299
|
end
|
196
300
|
|
197
|
-
#
|
301
|
+
# Sets up the Authorization header with the given token.
|
198
302
|
#
|
199
|
-
# token
|
200
|
-
# options
|
303
|
+
# @param token [String]
|
304
|
+
# @param options [Hash] extra token options.
|
201
305
|
#
|
202
|
-
#
|
306
|
+
# @example
|
203
307
|
#
|
204
|
-
# conn.token_auth 'abcdef', :
|
308
|
+
# conn.token_auth 'abcdef', foo: 'bar'
|
205
309
|
# conn.headers['Authorization']
|
206
310
|
# # => "Token token=\"abcdef\",
|
207
311
|
# foo=\"bar\""
|
208
312
|
#
|
209
|
-
#
|
313
|
+
# @return [void]
|
210
314
|
def token_auth(token, options = nil)
|
211
315
|
set_authorization_header(:token_auth, token, options)
|
212
316
|
end
|
213
317
|
|
214
|
-
#
|
318
|
+
# Sets up a custom Authorization header.
|
215
319
|
#
|
216
|
-
# type
|
217
|
-
# token
|
218
|
-
# a Hash is encoded into comma
|
320
|
+
# @param type [String] authorization type
|
321
|
+
# @param token [String, Hash] token. A String value is taken literally, and
|
322
|
+
# a Hash is encoded into comma-separated key/value pairs.
|
219
323
|
#
|
220
|
-
#
|
324
|
+
# @example
|
221
325
|
#
|
222
326
|
# conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
|
223
327
|
# conn.headers['Authorization']
|
224
328
|
# # => "Bearer mF_9.B5f-4.1JqM"
|
225
329
|
#
|
226
|
-
# conn.authorization :Token, :
|
330
|
+
# conn.authorization :Token, token: 'abcdef', foo: 'bar'
|
227
331
|
# conn.headers['Authorization']
|
228
332
|
# # => "Token token=\"abcdef\",
|
229
333
|
# foo=\"bar\""
|
230
334
|
#
|
231
|
-
#
|
335
|
+
# @return [void]
|
232
336
|
def authorization(type, token)
|
233
337
|
set_authorization_header(:authorization, type, token)
|
234
338
|
end
|
235
339
|
|
236
|
-
#
|
237
|
-
# parallel-capable adapter.
|
340
|
+
# Check if the adapter is parallel-capable.
|
238
341
|
#
|
239
|
-
#
|
342
|
+
# @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
|
240
343
|
#
|
241
|
-
#
|
344
|
+
# @return [Object, nil] a parallel manager or nil if yielded
|
345
|
+
# @api private
|
242
346
|
def default_parallel_manager
|
243
347
|
@default_parallel_manager ||= begin
|
244
|
-
|
245
|
-
h.klass.respond_to?(:supports_parallel?) and h.klass.supports_parallel?
|
246
|
-
end
|
348
|
+
adapter = @builder.adapter.klass if @builder.adapter
|
247
349
|
|
248
|
-
if
|
249
|
-
|
350
|
+
if support_parallel?(adapter)
|
351
|
+
adapter.setup_parallel_manager
|
250
352
|
elsif block_given?
|
251
353
|
yield
|
252
354
|
end
|
253
355
|
end
|
254
356
|
end
|
255
357
|
|
256
|
-
#
|
358
|
+
# Determine if this Faraday::Connection can make parallel requests.
|
257
359
|
#
|
258
|
-
#
|
360
|
+
# @return [Boolean]
|
259
361
|
def in_parallel?
|
260
362
|
!!@parallel_manager
|
261
363
|
end
|
262
364
|
|
263
|
-
#
|
365
|
+
# Sets up the parallel manager to make a set of requests.
|
264
366
|
#
|
265
|
-
# manager
|
367
|
+
# @param manager [Object] The parallel manager that this Connection's
|
368
|
+
# Adapter uses.
|
266
369
|
#
|
267
|
-
#
|
268
|
-
#
|
370
|
+
# @yield a block to execute multiple requests.
|
371
|
+
# @return [void]
|
269
372
|
def in_parallel(manager = nil)
|
270
|
-
@parallel_manager = manager || default_parallel_manager
|
271
|
-
warn
|
272
|
-
|
373
|
+
@parallel_manager = manager || default_parallel_manager do
|
374
|
+
warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \
|
375
|
+
'on Faraday stack'
|
376
|
+
warn caller[2, 10].join("\n")
|
273
377
|
nil
|
274
|
-
|
378
|
+
end
|
275
379
|
yield
|
276
|
-
@parallel_manager
|
380
|
+
@parallel_manager&.run
|
277
381
|
ensure
|
278
382
|
@parallel_manager = nil
|
279
383
|
end
|
280
384
|
|
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.
|
385
|
+
# Sets the Hash proxy options.
|
386
|
+
#
|
387
|
+
# @param new_value [Object]
|
290
388
|
def proxy=(new_value)
|
291
389
|
@manual_proxy = true
|
292
390
|
@proxy = new_value ? ProxyOptions.from(new_value) : nil
|
@@ -295,13 +393,14 @@ module Faraday
|
|
295
393
|
def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port=
|
296
394
|
def_delegator :url_prefix, :path, :path_prefix
|
297
395
|
|
298
|
-
#
|
299
|
-
# components in this connection.
|
396
|
+
# Parses the given URL with URI and stores the individual
|
397
|
+
# components in this connection. These components serve as defaults for
|
300
398
|
# requests made by this connection.
|
301
399
|
#
|
302
|
-
# url
|
400
|
+
# @param url [String, URI]
|
401
|
+
# @param encoder [Object]
|
303
402
|
#
|
304
|
-
#
|
403
|
+
# @example
|
305
404
|
#
|
306
405
|
# conn = Faraday::Connection.new { ... }
|
307
406
|
# conn.url_prefix = "https://sushi.com/api"
|
@@ -309,8 +408,6 @@ module Faraday
|
|
309
408
|
# conn.path_prefix # => "/api"
|
310
409
|
#
|
311
410
|
# conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
|
312
|
-
#
|
313
|
-
# Returns the parsed URI from the given input..
|
314
411
|
def url_prefix=(url, encoder = nil)
|
315
412
|
uri = @url_prefix = Utils.URI(url)
|
316
413
|
self.path_prefix = uri.path
|
@@ -322,62 +419,70 @@ module Faraday
|
|
322
419
|
basic_auth user, password
|
323
420
|
uri.user = uri.password = nil
|
324
421
|
end
|
325
|
-
|
326
|
-
uri
|
327
422
|
end
|
328
423
|
|
329
|
-
#
|
424
|
+
# Sets the path prefix and ensures that it always has a leading
|
330
425
|
# slash.
|
331
426
|
#
|
332
|
-
# value
|
427
|
+
# @param value [String]
|
333
428
|
#
|
334
|
-
#
|
429
|
+
# @return [String] the new path prefix
|
335
430
|
def path_prefix=(value)
|
336
431
|
url_prefix.path = if value
|
337
|
-
|
338
|
-
|
339
|
-
|
432
|
+
value = '/' + value unless value[0, 1] == '/'
|
433
|
+
value
|
434
|
+
end
|
340
435
|
end
|
341
436
|
|
342
|
-
#
|
437
|
+
# Takes a relative url for a request and combines it with the defaults
|
343
438
|
# set on the connection instance.
|
344
439
|
#
|
440
|
+
# @param url [String]
|
441
|
+
# @param extra_params [Hash]
|
442
|
+
#
|
443
|
+
# @example
|
345
444
|
# conn = Faraday::Connection.new { ... }
|
346
445
|
# conn.url_prefix = "https://sushi.com/api?token=abc"
|
347
446
|
# conn.scheme # => https
|
348
447
|
# conn.path_prefix # => "/api"
|
349
448
|
#
|
350
|
-
# conn.build_url("nigiri?page=2")
|
351
|
-
#
|
449
|
+
# conn.build_url("nigiri?page=2")
|
450
|
+
# # => https://sushi.com/api/nigiri?token=abc&page=2
|
451
|
+
#
|
452
|
+
# conn.build_url("nigiri", page: 2)
|
453
|
+
# # => https://sushi.com/api/nigiri?token=abc&page=2
|
352
454
|
#
|
353
455
|
def build_url(url = nil, extra_params = nil)
|
354
456
|
uri = build_exclusive_url(url)
|
355
457
|
|
356
458
|
query_values = params.dup.merge_query(uri.query, options.params_encoder)
|
357
|
-
query_values.update
|
358
|
-
uri.query =
|
459
|
+
query_values.update(extra_params) if extra_params
|
460
|
+
uri.query =
|
461
|
+
if query_values.empty?
|
462
|
+
nil
|
463
|
+
else
|
464
|
+
query_values.to_query(options.params_encoder)
|
465
|
+
end
|
359
466
|
|
360
467
|
uri
|
361
468
|
end
|
362
469
|
|
363
470
|
# Builds and runs the Faraday::Request.
|
364
471
|
#
|
365
|
-
# method
|
366
|
-
# url
|
367
|
-
# body
|
368
|
-
#
|
472
|
+
# @param method [Symbol] HTTP method.
|
473
|
+
# @param url [String, URI] String or URI to access.
|
474
|
+
# @param body [Object] The request body that will eventually be converted to
|
475
|
+
# a string.
|
476
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
369
477
|
#
|
370
|
-
#
|
478
|
+
# @return [Faraday::Response]
|
371
479
|
def run_request(method, url, body, headers)
|
372
|
-
|
480
|
+
unless METHODS.include?(method)
|
373
481
|
raise ArgumentError, "unknown http method: #{method}"
|
374
482
|
end
|
375
483
|
|
376
|
-
# Resets temp_proxy
|
377
|
-
@temp_proxy = proxy_for_request(url)
|
378
|
-
|
379
484
|
request = build_request(method) do |req|
|
380
|
-
req.options =
|
485
|
+
req.options.proxy = proxy_for_request(url)
|
381
486
|
req.url(url) if url
|
382
487
|
req.headers.update(headers) if headers
|
383
488
|
req.body = body if body
|
@@ -389,73 +494,93 @@ module Faraday
|
|
389
494
|
|
390
495
|
# Creates and configures the request object.
|
391
496
|
#
|
392
|
-
#
|
497
|
+
# @param method [Symbol]
|
498
|
+
#
|
499
|
+
# @yield [Faraday::Request] if block given
|
500
|
+
# @return [Faraday::Request]
|
393
501
|
def build_request(method)
|
394
502
|
Request.create(method) do |req|
|
395
|
-
req.params =
|
396
|
-
req.headers =
|
397
|
-
req.options =
|
503
|
+
req.params = params.dup
|
504
|
+
req.headers = headers.dup
|
505
|
+
req.options = options.dup
|
398
506
|
yield(req) if block_given?
|
399
507
|
end
|
400
508
|
end
|
401
509
|
|
402
|
-
#
|
510
|
+
# Build an absolute URL based on url_prefix.
|
403
511
|
#
|
404
|
-
# url
|
405
|
-
# params
|
512
|
+
# @param url [String, URI]
|
513
|
+
# @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to
|
514
|
+
# replace the query values
|
406
515
|
# of the resulting url (default: nil).
|
407
516
|
#
|
408
|
-
#
|
517
|
+
# @return [URI]
|
409
518
|
def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
|
410
|
-
url = nil if url.respond_to?(:empty?)
|
519
|
+
url = nil if url.respond_to?(:empty?) && url.empty?
|
411
520
|
base = url_prefix
|
412
|
-
if url
|
521
|
+
if url && base.path && base.path !~ %r{/$}
|
413
522
|
base = base.dup
|
414
|
-
base.path = base.path + '/'
|
523
|
+
base.path = base.path + '/' # ensure trailing slash
|
415
524
|
end
|
416
525
|
uri = url ? base + url : base
|
417
|
-
|
418
|
-
|
526
|
+
if params
|
527
|
+
uri.query = params.to_query(params_encoder || options.params_encoder)
|
528
|
+
end
|
529
|
+
# rubocop:disable Style/SafeNavigation
|
530
|
+
uri.query = nil if uri.query && uri.query.empty?
|
531
|
+
# rubocop:enable Style/SafeNavigation
|
419
532
|
uri
|
420
533
|
end
|
421
534
|
|
422
|
-
#
|
535
|
+
# Creates a duplicate of this Faraday::Connection.
|
423
536
|
#
|
424
|
-
#
|
537
|
+
# @api private
|
538
|
+
#
|
539
|
+
# @return [Faraday::Connection]
|
425
540
|
def dup
|
426
541
|
self.class.new(build_exclusive_url,
|
427
|
-
:
|
428
|
-
:
|
429
|
-
:
|
430
|
-
:
|
431
|
-
:
|
542
|
+
headers: headers.dup,
|
543
|
+
params: params.dup,
|
544
|
+
builder: builder.dup,
|
545
|
+
ssl: ssl.dup,
|
546
|
+
request: options.dup)
|
432
547
|
end
|
433
548
|
|
434
|
-
#
|
549
|
+
# Yields username and password extracted from a URI if they both exist.
|
550
|
+
#
|
551
|
+
# @param uri [URI]
|
552
|
+
# @yield [username, password] any username and password
|
553
|
+
# @yieldparam username [String] any username from URI
|
554
|
+
# @yieldparam password [String] any password from URI
|
555
|
+
# @return [void]
|
556
|
+
# @api private
|
435
557
|
def with_uri_credentials(uri)
|
436
|
-
|
437
|
-
|
438
|
-
|
558
|
+
return unless uri.user && uri.password
|
559
|
+
|
560
|
+
yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
|
439
561
|
end
|
440
562
|
|
441
563
|
def set_authorization_header(header_type, *args)
|
442
|
-
header = Faraday::Request
|
443
|
-
|
564
|
+
header = Faraday::Request
|
565
|
+
.lookup_middleware(header_type)
|
566
|
+
.header(*args)
|
567
|
+
|
444
568
|
headers[Faraday::Request::Authorization::KEY] = header
|
445
569
|
end
|
446
570
|
|
447
571
|
def proxy_from_env(url)
|
448
572
|
return if Faraday.ignore_env_proxy
|
573
|
+
|
449
574
|
uri = nil
|
450
575
|
if URI.parse('').respond_to?(:find_proxy)
|
451
576
|
case url
|
452
577
|
when String
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
578
|
+
uri = Utils.URI(url)
|
579
|
+
uri = URI.parse("#{uri.scheme}://#{uri.hostname}").find_proxy
|
580
|
+
when URI
|
581
|
+
uri = url.find_proxy
|
582
|
+
when nil
|
583
|
+
uri = find_default_proxy
|
459
584
|
end
|
460
585
|
else
|
461
586
|
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
@@ -466,19 +591,24 @@ module Faraday
|
|
466
591
|
|
467
592
|
def find_default_proxy
|
468
593
|
uri = ENV['http_proxy']
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
594
|
+
return unless uri && !uri.empty?
|
595
|
+
|
596
|
+
uri = 'http://' + uri if uri !~ /^http/i
|
597
|
+
uri
|
473
598
|
end
|
474
599
|
|
475
600
|
def proxy_for_request(url)
|
476
|
-
return
|
601
|
+
return proxy if @manual_proxy
|
602
|
+
|
477
603
|
if url && Utils.URI(url).absolute?
|
478
604
|
proxy_from_env(url)
|
479
605
|
else
|
480
|
-
|
606
|
+
proxy
|
481
607
|
end
|
482
608
|
end
|
609
|
+
|
610
|
+
def support_parallel?(adapter)
|
611
|
+
adapter&.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
|
612
|
+
end
|
483
613
|
end
|
484
614
|
end
|