faraday 0.13.0 → 2.0.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 +5 -5
- data/CHANGELOG.md +496 -0
- data/LICENSE.md +1 -1
- data/README.md +28 -328
- data/Rakefile +7 -0
- data/examples/client_spec.rb +97 -0
- data/examples/client_test.rb +118 -0
- data/lib/faraday/adapter/test.rb +127 -68
- data/lib/faraday/adapter.rb +71 -22
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/connection.rb +314 -226
- data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
- data/lib/faraday/error.rb +121 -37
- data/lib/faraday/logging/formatter.rb +106 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +18 -25
- data/lib/faraday/middleware_registry.rb +65 -0
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +181 -0
- data/lib/faraday/options/proxy_options.rb +32 -0
- data/lib/faraday/options/request_options.rb +22 -0
- data/lib/faraday/options/ssl_options.rb +59 -0
- data/lib/faraday/options.rb +41 -195
- data/lib/faraday/parameters.rb +4 -196
- data/lib/faraday/rack_builder.rb +91 -74
- data/lib/faraday/request/authorization.rb +37 -29
- data/lib/faraday/request/instrumentation.rb +47 -27
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request/url_encoded.rb +45 -23
- data/lib/faraday/request.rb +74 -32
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +22 -69
- data/lib/faraday/response/raise_error.rb +57 -14
- data/lib/faraday/response.rb +26 -33
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/lib/faraday/utils.rb +47 -251
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +104 -197
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/test_spec.rb +377 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/connection_spec.rb +787 -0
- data/spec/faraday/error_spec.rb +60 -0
- data/spec/faraday/middleware_spec.rb +52 -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 +44 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +42 -0
- data/spec/faraday/params_encoders/nested_spec.rb +142 -0
- data/spec/faraday/rack_builder_spec.rb +302 -0
- data/spec/faraday/request/authorization_spec.rb +83 -0
- data/spec/faraday/request/instrumentation_spec.rb +74 -0
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request/url_encoded_spec.rb +82 -0
- data/spec/faraday/request_spec.rb +109 -0
- data/spec/faraday/response/json_spec.rb +117 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/raise_error_spec.rb +172 -0
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +117 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +132 -0
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +96 -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 +249 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- metadata +71 -34
- data/lib/faraday/adapter/em_http.rb +0 -243
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
- data/lib/faraday/adapter/em_synchrony.rb +0 -106
- data/lib/faraday/adapter/excon.rb +0 -80
- data/lib/faraday/adapter/httpclient.rb +0 -128
- data/lib/faraday/adapter/net_http.rb +0 -135
- data/lib/faraday/adapter/net_http_persistent.rb +0 -54
- data/lib/faraday/adapter/patron.rb +0 -83
- data/lib/faraday/adapter/rack.rb +0 -58
- data/lib/faraday/adapter/typhoeus.rb +0 -123
- data/lib/faraday/autoload.rb +0 -84
- data/lib/faraday/request/basic_authentication.rb +0 -13
- data/lib/faraday/request/multipart.rb +0 -68
- data/lib/faraday/request/retry.rb +0 -164
- data/lib/faraday/request/token_authentication.rb +0 -15
- data/lib/faraday/upload_io.rb +0 -67
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
module Utils
|
5
|
+
# A case-insensitive Hash that preserves the original case of a header
|
6
|
+
# when set.
|
7
|
+
#
|
8
|
+
# Adapted from Rack::Utils::HeaderHash
|
9
|
+
class Headers < ::Hash
|
10
|
+
def self.from(value)
|
11
|
+
new(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.allocate
|
15
|
+
new_self = super
|
16
|
+
new_self.initialize_names
|
17
|
+
new_self
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(hash = nil)
|
21
|
+
super()
|
22
|
+
@names = {}
|
23
|
+
update(hash || {})
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize_names
|
27
|
+
@names = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
# on dup/clone, we need to duplicate @names hash
|
31
|
+
def initialize_copy(other)
|
32
|
+
super
|
33
|
+
@names = other.names.dup
|
34
|
+
end
|
35
|
+
|
36
|
+
# need to synchronize concurrent writes to the shared KeyMap
|
37
|
+
keymap_mutex = Mutex.new
|
38
|
+
|
39
|
+
# symbol -> string mapper + cache
|
40
|
+
KeyMap = Hash.new do |map, key|
|
41
|
+
value = if key.respond_to?(:to_str)
|
42
|
+
key
|
43
|
+
else
|
44
|
+
key.to_s.split('_') # user_agent: %w(user agent)
|
45
|
+
.each(&:capitalize!) # => %w(User Agent)
|
46
|
+
.join('-') # => "User-Agent"
|
47
|
+
end
|
48
|
+
keymap_mutex.synchronize { map[key] = value }
|
49
|
+
end
|
50
|
+
KeyMap[:etag] = 'ETag'
|
51
|
+
|
52
|
+
def [](key)
|
53
|
+
key = KeyMap[key]
|
54
|
+
super(key) || super(@names[key.downcase])
|
55
|
+
end
|
56
|
+
|
57
|
+
def []=(key, val)
|
58
|
+
key = KeyMap[key]
|
59
|
+
key = (@names[key.downcase] ||= key)
|
60
|
+
# join multiple values with a comma
|
61
|
+
val = val.to_ary.join(', ') if val.respond_to?(:to_ary)
|
62
|
+
super(key, val)
|
63
|
+
end
|
64
|
+
|
65
|
+
def fetch(key, *args, &block)
|
66
|
+
key = KeyMap[key]
|
67
|
+
key = @names.fetch(key.downcase, key)
|
68
|
+
super(key, *args, &block)
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete(key)
|
72
|
+
key = KeyMap[key]
|
73
|
+
key = @names[key.downcase]
|
74
|
+
return unless key
|
75
|
+
|
76
|
+
@names.delete key.downcase
|
77
|
+
super(key)
|
78
|
+
end
|
79
|
+
|
80
|
+
def include?(key)
|
81
|
+
@names.include? key.downcase
|
82
|
+
end
|
83
|
+
|
84
|
+
alias has_key? include?
|
85
|
+
alias member? include?
|
86
|
+
alias key? include?
|
87
|
+
|
88
|
+
def merge!(other)
|
89
|
+
other.each { |k, v| self[k] = v }
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
alias update merge!
|
94
|
+
|
95
|
+
def merge(other)
|
96
|
+
hash = dup
|
97
|
+
hash.merge! other
|
98
|
+
end
|
99
|
+
|
100
|
+
def replace(other)
|
101
|
+
clear
|
102
|
+
@names.clear
|
103
|
+
update other
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
def to_hash
|
108
|
+
{}.update(self)
|
109
|
+
end
|
110
|
+
|
111
|
+
def parse(header_string)
|
112
|
+
return unless header_string && !header_string.empty?
|
113
|
+
|
114
|
+
headers = header_string.split("\r\n")
|
115
|
+
|
116
|
+
# Find the last set of response headers.
|
117
|
+
start_index = headers.rindex { |x| x.start_with?('HTTP/') } || 0
|
118
|
+
last_response = headers.slice(start_index, headers.size)
|
119
|
+
|
120
|
+
last_response
|
121
|
+
.tap { |a| a.shift if a.first.start_with?('HTTP/') }
|
122
|
+
.map { |h| h.split(/:\s*/, 2) } # split key and value
|
123
|
+
.reject { |p| p[0].nil? } # ignore blank lines
|
124
|
+
.each { |key, value| add_parsed(key, value) }
|
125
|
+
end
|
126
|
+
|
127
|
+
protected
|
128
|
+
|
129
|
+
attr_reader :names
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
# Join multiple values with a comma.
|
134
|
+
def add_parsed(key, value)
|
135
|
+
self[key] ? self[key] << ', ' << value : self[key] = value
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
module Utils
|
5
|
+
# A hash with stringified keys.
|
6
|
+
class ParamsHash < Hash
|
7
|
+
def [](key)
|
8
|
+
super(convert_key(key))
|
9
|
+
end
|
10
|
+
|
11
|
+
def []=(key, value)
|
12
|
+
super(convert_key(key), value)
|
13
|
+
end
|
14
|
+
|
15
|
+
def delete(key)
|
16
|
+
super(convert_key(key))
|
17
|
+
end
|
18
|
+
|
19
|
+
def include?(key)
|
20
|
+
super(convert_key(key))
|
21
|
+
end
|
22
|
+
|
23
|
+
alias has_key? include?
|
24
|
+
alias member? include?
|
25
|
+
alias key? include?
|
26
|
+
|
27
|
+
def update(params)
|
28
|
+
params.each do |key, value|
|
29
|
+
self[key] = value
|
30
|
+
end
|
31
|
+
self
|
32
|
+
end
|
33
|
+
alias merge! update
|
34
|
+
|
35
|
+
def merge(params)
|
36
|
+
dup.update(params)
|
37
|
+
end
|
38
|
+
|
39
|
+
def replace(other)
|
40
|
+
clear
|
41
|
+
update(other)
|
42
|
+
end
|
43
|
+
|
44
|
+
def merge_query(query, encoder = nil)
|
45
|
+
return self unless query && !query.empty?
|
46
|
+
|
47
|
+
update((encoder || Utils.default_params_encoder).decode(query))
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_query(encoder = nil)
|
51
|
+
(encoder || Utils.default_params_encoder).encode(self)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def convert_key(key)
|
57
|
+
key.to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/faraday/utils.rb
CHANGED
@@ -1,193 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
require 'uri'
|
5
|
+
require 'faraday/utils/headers'
|
6
|
+
require 'faraday/utils/params_hash'
|
2
7
|
|
3
8
|
module Faraday
|
9
|
+
# Utils contains various static helper methods.
|
4
10
|
module Utils
|
5
|
-
|
6
|
-
|
7
|
-
# Adapted from Rack::Utils::HeaderHash
|
8
|
-
class Headers < ::Hash
|
9
|
-
def self.from(value)
|
10
|
-
new(value)
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.allocate
|
14
|
-
new_self = super
|
15
|
-
new_self.initialize_names
|
16
|
-
new_self
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(hash = nil)
|
20
|
-
super()
|
21
|
-
@names = {}
|
22
|
-
self.update(hash || {})
|
23
|
-
end
|
24
|
-
|
25
|
-
def initialize_names
|
26
|
-
@names = {}
|
27
|
-
end
|
28
|
-
|
29
|
-
# on dup/clone, we need to duplicate @names hash
|
30
|
-
def initialize_copy(other)
|
31
|
-
super
|
32
|
-
@names = other.names.dup
|
33
|
-
end
|
34
|
-
|
35
|
-
# need to synchronize concurrent writes to the shared KeyMap
|
36
|
-
keymap_mutex = Mutex.new
|
37
|
-
|
38
|
-
# symbol -> string mapper + cache
|
39
|
-
KeyMap = Hash.new do |map, key|
|
40
|
-
value = if key.respond_to?(:to_str)
|
41
|
-
key
|
42
|
-
else
|
43
|
-
key.to_s.split('_'). # :user_agent => %w(user agent)
|
44
|
-
each { |w| w.capitalize! }. # => %w(User Agent)
|
45
|
-
join('-') # => "User-Agent"
|
46
|
-
end
|
47
|
-
keymap_mutex.synchronize { map[key] = value }
|
48
|
-
end
|
49
|
-
KeyMap[:etag] = "ETag"
|
50
|
-
|
51
|
-
def [](k)
|
52
|
-
k = KeyMap[k]
|
53
|
-
super(k) || super(@names[k.downcase])
|
54
|
-
end
|
55
|
-
|
56
|
-
def []=(k, v)
|
57
|
-
k = KeyMap[k]
|
58
|
-
k = (@names[k.downcase] ||= k)
|
59
|
-
# join multiple values with a comma
|
60
|
-
v = v.to_ary.join(', ') if v.respond_to? :to_ary
|
61
|
-
super(k, v)
|
62
|
-
end
|
63
|
-
|
64
|
-
def fetch(k, *args, &block)
|
65
|
-
k = KeyMap[k]
|
66
|
-
key = @names.fetch(k.downcase, k)
|
67
|
-
super(key, *args, &block)
|
68
|
-
end
|
69
|
-
|
70
|
-
def delete(k)
|
71
|
-
k = KeyMap[k]
|
72
|
-
if k = @names[k.downcase]
|
73
|
-
@names.delete k.downcase
|
74
|
-
super(k)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def include?(k)
|
79
|
-
@names.include? k.downcase
|
80
|
-
end
|
81
|
-
|
82
|
-
alias_method :has_key?, :include?
|
83
|
-
alias_method :member?, :include?
|
84
|
-
alias_method :key?, :include?
|
85
|
-
|
86
|
-
def merge!(other)
|
87
|
-
other.each { |k, v| self[k] = v }
|
88
|
-
self
|
89
|
-
end
|
90
|
-
alias_method :update, :merge!
|
91
|
-
|
92
|
-
def merge(other)
|
93
|
-
hash = dup
|
94
|
-
hash.merge! other
|
95
|
-
end
|
96
|
-
|
97
|
-
def replace(other)
|
98
|
-
clear
|
99
|
-
@names.clear
|
100
|
-
self.update other
|
101
|
-
self
|
102
|
-
end
|
103
|
-
|
104
|
-
def to_hash() ::Hash.new.update(self) end
|
105
|
-
|
106
|
-
def parse(header_string)
|
107
|
-
return unless header_string && !header_string.empty?
|
108
|
-
|
109
|
-
headers = header_string.split(/\r\n/)
|
110
|
-
|
111
|
-
# Find the last set of response headers.
|
112
|
-
start_index = headers.rindex { |x| x.match(/^HTTP\//) } || 0
|
113
|
-
last_response = headers.slice(start_index, headers.size)
|
114
|
-
|
115
|
-
last_response.
|
116
|
-
tap { |a| a.shift if a.first.index('HTTP/') == 0 }. # drop the HTTP status line
|
117
|
-
map { |h| h.split(/:\s*/, 2) }.reject { |p| p[0].nil? }. # split key and value, ignore blank lines
|
118
|
-
each { |key, value|
|
119
|
-
# join multiple values with a comma
|
120
|
-
if self[key]
|
121
|
-
self[key] << ', ' << value
|
122
|
-
else
|
123
|
-
self[key] = value
|
124
|
-
end
|
125
|
-
}
|
126
|
-
end
|
127
|
-
|
128
|
-
protected
|
129
|
-
|
130
|
-
def names
|
131
|
-
@names
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
# hash with stringified keys
|
136
|
-
class ParamsHash < Hash
|
137
|
-
def [](key)
|
138
|
-
super(convert_key(key))
|
139
|
-
end
|
140
|
-
|
141
|
-
def []=(key, value)
|
142
|
-
super(convert_key(key), value)
|
143
|
-
end
|
144
|
-
|
145
|
-
def delete(key)
|
146
|
-
super(convert_key(key))
|
147
|
-
end
|
148
|
-
|
149
|
-
def include?(key)
|
150
|
-
super(convert_key(key))
|
151
|
-
end
|
152
|
-
|
153
|
-
alias_method :has_key?, :include?
|
154
|
-
alias_method :member?, :include?
|
155
|
-
alias_method :key?, :include?
|
156
|
-
|
157
|
-
def update(params)
|
158
|
-
params.each do |key, value|
|
159
|
-
self[key] = value
|
160
|
-
end
|
161
|
-
self
|
162
|
-
end
|
163
|
-
alias_method :merge!, :update
|
164
|
-
|
165
|
-
def merge(params)
|
166
|
-
dup.update(params)
|
167
|
-
end
|
168
|
-
|
169
|
-
def replace(other)
|
170
|
-
clear
|
171
|
-
update(other)
|
172
|
-
end
|
173
|
-
|
174
|
-
def merge_query(query, encoder = nil)
|
175
|
-
if query && !query.empty?
|
176
|
-
update((encoder || Utils.default_params_encoder).decode(query))
|
177
|
-
end
|
178
|
-
self
|
179
|
-
end
|
180
|
-
|
181
|
-
def to_query(encoder = nil)
|
182
|
-
(encoder || Utils.default_params_encoder).encode(self)
|
183
|
-
end
|
184
|
-
|
185
|
-
private
|
186
|
-
|
187
|
-
def convert_key(key)
|
188
|
-
key.to_s
|
189
|
-
end
|
190
|
-
end
|
11
|
+
module_function
|
191
12
|
|
192
13
|
def build_query(params)
|
193
14
|
FlatParamsEncoder.encode(params)
|
@@ -197,17 +18,27 @@ module Faraday
|
|
197
18
|
NestedParamsEncoder.encode(params)
|
198
19
|
end
|
199
20
|
|
200
|
-
|
21
|
+
def default_space_encoding
|
22
|
+
@default_space_encoding ||= '+'
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
attr_writer :default_space_encoding
|
27
|
+
end
|
28
|
+
|
29
|
+
ESCAPE_RE = /[^a-zA-Z0-9 .~_-]/.freeze
|
201
30
|
|
202
|
-
def escape(
|
203
|
-
|
204
|
-
|
205
|
-
|
31
|
+
def escape(str)
|
32
|
+
str.to_s.gsub(ESCAPE_RE) do |match|
|
33
|
+
"%#{match.unpack('H2' * match.bytesize).join('%').upcase}"
|
34
|
+
end.gsub(' ', default_space_encoding)
|
206
35
|
end
|
207
36
|
|
208
|
-
def unescape(
|
37
|
+
def unescape(str)
|
38
|
+
CGI.unescape str.to_s
|
39
|
+
end
|
209
40
|
|
210
|
-
DEFAULT_SEP = /[&;] */n
|
41
|
+
DEFAULT_SEP = /[&;] */n.freeze
|
211
42
|
|
212
43
|
# Adapted from Rack
|
213
44
|
def parse_query(query)
|
@@ -222,45 +53,14 @@ module Faraday
|
|
222
53
|
@default_params_encoder ||= NestedParamsEncoder
|
223
54
|
end
|
224
55
|
|
225
|
-
|
226
|
-
|
56
|
+
def basic_header_from(login, pass)
|
57
|
+
value = Base64.encode64("#{login}:#{pass}")
|
58
|
+
value.delete!("\n")
|
59
|
+
"Basic #{value}"
|
227
60
|
end
|
228
61
|
|
229
|
-
|
230
|
-
|
231
|
-
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
|
232
|
-
k = $1 || ''
|
233
|
-
after = $' || ''
|
234
|
-
|
235
|
-
return if k.empty?
|
236
|
-
|
237
|
-
if after == ""
|
238
|
-
if params[k]
|
239
|
-
params[k] = Array[params[k]] unless params[k].kind_of?(Array)
|
240
|
-
params[k] << v
|
241
|
-
else
|
242
|
-
params[k] = v
|
243
|
-
end
|
244
|
-
elsif after == "[]"
|
245
|
-
params[k] ||= []
|
246
|
-
raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
247
|
-
params[k] << v
|
248
|
-
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
|
249
|
-
child_key = $1
|
250
|
-
params[k] ||= []
|
251
|
-
raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
252
|
-
if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key)
|
253
|
-
normalize_params(params[k].last, child_key, v)
|
254
|
-
else
|
255
|
-
params[k] << normalize_params({}, child_key, v)
|
256
|
-
end
|
257
|
-
else
|
258
|
-
params[k] ||= {}
|
259
|
-
raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Hash)
|
260
|
-
params[k] = normalize_params(params[k], after, v)
|
261
|
-
end
|
262
|
-
|
263
|
-
return params
|
62
|
+
class << self
|
63
|
+
attr_writer :default_params_encoder
|
264
64
|
end
|
265
65
|
|
266
66
|
# Normalize URI() behavior across Ruby versions
|
@@ -268,46 +68,44 @@ module Faraday
|
|
268
68
|
# url - A String or URI.
|
269
69
|
#
|
270
70
|
# Returns a parsed URI.
|
271
|
-
def URI(url)
|
71
|
+
def URI(url) # rubocop:disable Naming/MethodName
|
272
72
|
if url.respond_to?(:host)
|
273
73
|
url
|
274
74
|
elsif url.respond_to?(:to_str)
|
275
75
|
default_uri_parser.call(url)
|
276
76
|
else
|
277
|
-
raise ArgumentError,
|
77
|
+
raise ArgumentError, 'bad argument (expected URI object or URI string)'
|
278
78
|
end
|
279
79
|
end
|
280
80
|
|
281
81
|
def default_uri_parser
|
282
|
-
@default_uri_parser ||=
|
283
|
-
require 'uri'
|
284
|
-
Kernel.method(:URI)
|
285
|
-
end
|
82
|
+
@default_uri_parser ||= Kernel.method(:URI)
|
286
83
|
end
|
287
84
|
|
288
85
|
def default_uri_parser=(parser)
|
289
86
|
@default_uri_parser = if parser.respond_to?(:call) || parser.nil?
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
87
|
+
parser
|
88
|
+
else
|
89
|
+
parser.method(:parse)
|
90
|
+
end
|
294
91
|
end
|
295
92
|
|
296
|
-
# Receives a String or URI and returns just
|
93
|
+
# Receives a String or URI and returns just
|
94
|
+
# the path with the query string sorted.
|
297
95
|
def normalize_path(url)
|
298
96
|
url = URI(url)
|
299
|
-
(url.path.start_with?('/') ? url.path :
|
300
|
-
|
97
|
+
(url.path.start_with?('/') ? url.path : "/#{url.path}") +
|
98
|
+
(url.query ? "?#{sort_query_params(url.query)}" : '')
|
301
99
|
end
|
302
100
|
|
303
101
|
# Recursive hash update
|
304
102
|
def deep_merge!(target, hash)
|
305
103
|
hash.each do |key, value|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
104
|
+
target[key] = if value.is_a?(Hash) && (target[key].is_a?(Hash) || target[key].is_a?(Options))
|
105
|
+
deep_merge(target[key], value)
|
106
|
+
else
|
107
|
+
value
|
108
|
+
end
|
311
109
|
end
|
312
110
|
target
|
313
111
|
end
|
@@ -317,8 +115,6 @@ module Faraday
|
|
317
115
|
deep_merge!(source.dup, hash)
|
318
116
|
end
|
319
117
|
|
320
|
-
protected
|
321
|
-
|
322
118
|
def sort_query_params(query)
|
323
119
|
query.split('&').sort.join('&')
|
324
120
|
end
|