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
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# DependencyLoader helps Faraday adapters and middleware load dependencies.
|
5
|
+
module DependencyLoader
|
6
|
+
attr_reader :load_error
|
7
|
+
|
8
|
+
# Executes a block which should try to require and reference dependent
|
9
|
+
# libraries
|
10
|
+
def dependency(lib = nil)
|
11
|
+
lib ? require(lib) : yield
|
12
|
+
rescue LoadError, NameError => e
|
13
|
+
self.load_error = e
|
14
|
+
end
|
15
|
+
|
16
|
+
def new(*)
|
17
|
+
unless loaded?
|
18
|
+
raise "missing dependency for #{self}: #{load_error.message}"
|
19
|
+
end
|
20
|
+
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def loaded?
|
25
|
+
load_error.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def inherited(subclass)
|
29
|
+
super
|
30
|
+
subclass.send(:load_error=, load_error)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_writer :load_error
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# FlatParamsEncoder manages URI params as a flat hash. Any Array values repeat
|
5
|
+
# the parameter multiple times.
|
6
|
+
module FlatParamsEncoder
|
7
|
+
class << self
|
8
|
+
extend Forwardable
|
9
|
+
def_delegators :'Faraday::Utils', :escape, :unescape
|
10
|
+
end
|
11
|
+
|
12
|
+
# Encode converts the given param into a URI querystring. Keys and values
|
13
|
+
# will converted to strings and appropriately escaped for the URI.
|
14
|
+
#
|
15
|
+
# @param params [Hash] query arguments to convert.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# encode({a: %w[one two three], b: true, c: "C"})
|
20
|
+
# # => 'a=one&a=two&a=three&b=true&c=C'
|
21
|
+
#
|
22
|
+
# @return [String] the URI querystring (without the leading '?')
|
23
|
+
def self.encode(params)
|
24
|
+
return nil if params.nil?
|
25
|
+
|
26
|
+
unless params.is_a?(Array)
|
27
|
+
unless params.respond_to?(:to_hash)
|
28
|
+
raise TypeError,
|
29
|
+
"Can't convert #{params.class} into Hash."
|
30
|
+
end
|
31
|
+
params = params.to_hash
|
32
|
+
params = params.map do |key, value|
|
33
|
+
key = key.to_s if key.is_a?(Symbol)
|
34
|
+
[key, value]
|
35
|
+
end
|
36
|
+
# Useful default for OAuth and caching.
|
37
|
+
# Only to be used for non-Array inputs. Arrays should preserve order.
|
38
|
+
params.sort!
|
39
|
+
end
|
40
|
+
|
41
|
+
# The params have form [['key1', 'value1'], ['key2', 'value2']].
|
42
|
+
buffer = +''
|
43
|
+
params.each do |key, value|
|
44
|
+
encoded_key = escape(key)
|
45
|
+
if value.nil?
|
46
|
+
buffer << "#{encoded_key}&"
|
47
|
+
elsif value.is_a?(Array)
|
48
|
+
if value.empty?
|
49
|
+
buffer << "#{encoded_key}=&"
|
50
|
+
else
|
51
|
+
value.each do |sub_value|
|
52
|
+
encoded_value = escape(sub_value)
|
53
|
+
buffer << "#{encoded_key}=#{encoded_value}&"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
else
|
57
|
+
encoded_value = escape(value)
|
58
|
+
buffer << "#{encoded_key}=#{encoded_value}&"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
buffer.chop
|
62
|
+
end
|
63
|
+
|
64
|
+
# Decode converts the given URI querystring into a hash.
|
65
|
+
#
|
66
|
+
# @param query [String] query arguments to parse.
|
67
|
+
#
|
68
|
+
# @example
|
69
|
+
#
|
70
|
+
# decode('a=one&a=two&a=three&b=true&c=C')
|
71
|
+
# # => {"a"=>["one", "two", "three"], "b"=>"true", "c"=>"C"}
|
72
|
+
#
|
73
|
+
# @return [Hash] parsed keys and value strings from the querystring.
|
74
|
+
def self.decode(query)
|
75
|
+
return nil if query.nil?
|
76
|
+
|
77
|
+
empty_accumulator = {}
|
78
|
+
|
79
|
+
split_query = (query.split('&').map do |pair|
|
80
|
+
pair.split('=', 2) if pair && !pair.empty?
|
81
|
+
end).compact
|
82
|
+
split_query.each_with_object(empty_accumulator.dup) do |pair, accu|
|
83
|
+
pair[0] = unescape(pair[0])
|
84
|
+
pair[1] = true if pair[1].nil?
|
85
|
+
if pair[1].respond_to?(:to_str)
|
86
|
+
pair[1] = unescape(pair[1].to_str.tr('+', ' '))
|
87
|
+
end
|
88
|
+
if accu[pair[0]].is_a?(Array)
|
89
|
+
accu[pair[0]] << pair[1]
|
90
|
+
elsif accu[pair[0]]
|
91
|
+
accu[pair[0]] = [accu[pair[0]], pair[1]]
|
92
|
+
else
|
93
|
+
accu[pair[0]] = pair[1]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# Sub-module for encoding parameters into query-string.
|
5
|
+
module EncodeMethods
|
6
|
+
# @param params [nil, Array, #to_hash] parameters to be encoded
|
7
|
+
#
|
8
|
+
# @return [String] the encoded params
|
9
|
+
#
|
10
|
+
# @raise [TypeError] if params can not be converted to a Hash
|
11
|
+
def encode(params)
|
12
|
+
return nil if params.nil?
|
13
|
+
|
14
|
+
unless params.is_a?(Array)
|
15
|
+
unless params.respond_to?(:to_hash)
|
16
|
+
raise TypeError, "Can't convert #{params.class} into Hash."
|
17
|
+
end
|
18
|
+
|
19
|
+
params = params.to_hash
|
20
|
+
params = params.map do |key, value|
|
21
|
+
key = key.to_s if key.is_a?(Symbol)
|
22
|
+
[key, value]
|
23
|
+
end
|
24
|
+
# Useful default for OAuth and caching.
|
25
|
+
# Only to be used for non-Array inputs. Arrays should preserve order.
|
26
|
+
params.sort!
|
27
|
+
end
|
28
|
+
|
29
|
+
# The params have form [['key1', 'value1'], ['key2', 'value2']].
|
30
|
+
buffer = +''
|
31
|
+
params.each do |parent, value|
|
32
|
+
encoded_parent = escape(parent)
|
33
|
+
buffer << "#{encode_pair(encoded_parent, value)}&"
|
34
|
+
end
|
35
|
+
buffer.chop
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def encode_pair(parent, value)
|
41
|
+
if value.is_a?(Hash)
|
42
|
+
encode_hash(parent, value)
|
43
|
+
elsif value.is_a?(Array)
|
44
|
+
encode_array(parent, value)
|
45
|
+
elsif value.nil?
|
46
|
+
parent
|
47
|
+
else
|
48
|
+
encoded_value = escape(value)
|
49
|
+
"#{parent}=#{encoded_value}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def encode_hash(parent, value)
|
54
|
+
value = value.map { |key, val| [escape(key), val] }.sort
|
55
|
+
|
56
|
+
buffer = +''
|
57
|
+
value.each do |key, val|
|
58
|
+
new_parent = "#{parent}%5B#{key}%5D"
|
59
|
+
buffer << "#{encode_pair(new_parent, val)}&"
|
60
|
+
end
|
61
|
+
buffer.chop
|
62
|
+
end
|
63
|
+
|
64
|
+
def encode_array(parent, value)
|
65
|
+
new_parent = "#{parent}%5B%5D"
|
66
|
+
return new_parent if value.empty?
|
67
|
+
|
68
|
+
buffer = +''
|
69
|
+
value.each { |val| buffer << "#{encode_pair(new_parent, val)}&" }
|
70
|
+
buffer.chop
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Sub-module for decoding query-string into parameters.
|
75
|
+
module DecodeMethods
|
76
|
+
# @param query [nil, String]
|
77
|
+
#
|
78
|
+
# @return [Array<Array, String>] the decoded params
|
79
|
+
#
|
80
|
+
# @raise [TypeError] if the nesting is incorrect
|
81
|
+
def decode(query)
|
82
|
+
return nil if query.nil?
|
83
|
+
|
84
|
+
params = {}
|
85
|
+
query.split('&').each do |pair|
|
86
|
+
next if pair.empty?
|
87
|
+
|
88
|
+
key, value = pair.split('=', 2)
|
89
|
+
key = unescape(key)
|
90
|
+
value = unescape(value.tr('+', ' ')) if value
|
91
|
+
decode_pair(key, value, params)
|
92
|
+
end
|
93
|
+
|
94
|
+
dehash(params, 0)
|
95
|
+
end
|
96
|
+
|
97
|
+
protected
|
98
|
+
|
99
|
+
SUBKEYS_REGEX = /[^\[\]]+(?:\]?\[\])?/.freeze
|
100
|
+
|
101
|
+
def decode_pair(key, value, context)
|
102
|
+
subkeys = key.scan(SUBKEYS_REGEX)
|
103
|
+
subkeys.each_with_index do |subkey, i|
|
104
|
+
is_array = subkey =~ /[\[\]]+\Z/
|
105
|
+
subkey = $` if is_array
|
106
|
+
last_subkey = i == subkeys.length - 1
|
107
|
+
|
108
|
+
context = prepare_context(context, subkey, is_array, last_subkey)
|
109
|
+
add_to_context(is_array, context, value, subkey) if last_subkey
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def prepare_context(context, subkey, is_array, last_subkey)
|
114
|
+
if !last_subkey || is_array
|
115
|
+
context = new_context(subkey, is_array, context)
|
116
|
+
end
|
117
|
+
if context.is_a?(Array) && !is_array
|
118
|
+
context = match_context(context, subkey)
|
119
|
+
end
|
120
|
+
context
|
121
|
+
end
|
122
|
+
|
123
|
+
def new_context(subkey, is_array, context)
|
124
|
+
value_type = is_array ? Array : Hash
|
125
|
+
if context[subkey] && !context[subkey].is_a?(value_type)
|
126
|
+
raise TypeError, "expected #{value_type.name} " \
|
127
|
+
"(got #{context[subkey].class.name}) for param `#{subkey}'"
|
128
|
+
end
|
129
|
+
|
130
|
+
context[subkey] ||= value_type.new
|
131
|
+
end
|
132
|
+
|
133
|
+
def match_context(context, subkey)
|
134
|
+
context << {} if !context.last.is_a?(Hash) || context.last.key?(subkey)
|
135
|
+
context.last
|
136
|
+
end
|
137
|
+
|
138
|
+
def add_to_context(is_array, context, value, subkey)
|
139
|
+
is_array ? context << value : context[subkey] = value
|
140
|
+
end
|
141
|
+
|
142
|
+
# Internal: convert a nested hash with purely numeric keys into an array.
|
143
|
+
# FIXME: this is not compatible with Rack::Utils.parse_nested_query
|
144
|
+
# @!visibility private
|
145
|
+
def dehash(hash, depth)
|
146
|
+
hash.each do |key, value|
|
147
|
+
hash[key] = dehash(value, depth + 1) if value.is_a?(Hash)
|
148
|
+
end
|
149
|
+
|
150
|
+
if depth.positive? && !hash.empty? && hash.keys.all? { |k| k =~ /^\d+$/ }
|
151
|
+
hash.sort.map(&:last)
|
152
|
+
else
|
153
|
+
hash
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# This is the default encoder for Faraday requests.
|
159
|
+
# Using this encoder, parameters will be encoded respecting their structure,
|
160
|
+
# so you can send objects such as Arrays or Hashes as parameters
|
161
|
+
# for your requests.
|
162
|
+
module NestedParamsEncoder
|
163
|
+
class << self
|
164
|
+
extend Forwardable
|
165
|
+
def_delegators :'Faraday::Utils', :escape, :unescape
|
166
|
+
end
|
167
|
+
|
168
|
+
extend EncodeMethods
|
169
|
+
extend DecodeMethods
|
170
|
+
end
|
171
|
+
end
|
data/lib/faraday/error.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'faraday/deprecate'
|
4
|
-
|
5
3
|
# Faraday namespace.
|
6
4
|
module Faraday
|
7
5
|
# Faraday error base class.
|
@@ -23,10 +21,10 @@ module Faraday
|
|
23
21
|
end
|
24
22
|
|
25
23
|
def inspect
|
26
|
-
inner = ''
|
27
|
-
inner
|
28
|
-
inner
|
29
|
-
inner
|
24
|
+
inner = +''
|
25
|
+
inner << " wrapped=#{@wrapped_exception.inspect}" if @wrapped_exception
|
26
|
+
inner << " response=#{@response.inspect}" if @response
|
27
|
+
inner << " #{super}" if inner.empty?
|
30
28
|
%(#<#{self.class}#{inner}>)
|
31
29
|
end
|
32
30
|
|
@@ -100,7 +98,7 @@ module Faraday
|
|
100
98
|
end
|
101
99
|
|
102
100
|
# A unified client error for timeouts.
|
103
|
-
class TimeoutError <
|
101
|
+
class TimeoutError < ServerError
|
104
102
|
def initialize(exc = 'timeout', response = nil)
|
105
103
|
super(exc, response)
|
106
104
|
end
|
@@ -110,49 +108,25 @@ module Faraday
|
|
110
108
|
class NilStatusError < ServerError
|
111
109
|
def initialize(exc, response = nil)
|
112
110
|
exc_msg_and_response!(exc, response)
|
113
|
-
@response = unwrap_resp!(@response)
|
114
111
|
super('http status could not be derived from the server response')
|
115
112
|
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
extend Faraday::Deprecate
|
120
|
-
|
121
|
-
def unwrap_resp(resp)
|
122
|
-
if inner = (resp.keys.size == 1 && resp[:response])
|
123
|
-
return unwrap_resp(inner)
|
124
|
-
end
|
125
|
-
|
126
|
-
resp
|
127
|
-
end
|
128
|
-
|
129
|
-
alias_method :unwrap_resp!, :unwrap_resp
|
130
|
-
deprecate('unwrap_resp', nil, '1.0')
|
131
113
|
end
|
132
114
|
|
133
115
|
# A unified error for failed connections.
|
134
|
-
class ConnectionFailed <
|
116
|
+
class ConnectionFailed < Error
|
135
117
|
end
|
136
118
|
|
137
119
|
# A unified client error for SSL errors.
|
138
|
-
class SSLError <
|
120
|
+
class SSLError < Error
|
139
121
|
end
|
140
122
|
|
141
123
|
# Raised by FaradayMiddleware::ResponseMiddleware
|
142
|
-
class ParsingError <
|
124
|
+
class ParsingError < Error
|
143
125
|
end
|
144
126
|
|
145
127
|
# Exception used to control the Retry middleware.
|
146
128
|
#
|
147
129
|
# @see Faraday::Request::Retry
|
148
|
-
class RetriableResponse <
|
149
|
-
end
|
150
|
-
|
151
|
-
[:ClientError, :ConnectionFailed, :ResourceNotFound,
|
152
|
-
:ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
|
153
|
-
Error.const_set(
|
154
|
-
const,
|
155
|
-
DeprecatedClass.proxy_class(Faraday.const_get(const))
|
156
|
-
)
|
130
|
+
class RetriableResponse < Error
|
157
131
|
end
|
158
132
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
# multipart-post gem
|
6
|
+
require 'composite_io'
|
7
|
+
require 'parts'
|
8
|
+
|
9
|
+
module Faraday
|
10
|
+
# Multipart value used to POST a binary data from a file or
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# payload = { file: Faraday::FilePart.new("file_name.ext", "content/type") }
|
14
|
+
# http.post("/upload", payload)
|
15
|
+
#
|
16
|
+
|
17
|
+
# @!method initialize(filename_or_io, content_type, filename = nil, opts = {})
|
18
|
+
#
|
19
|
+
# @param filename_or_io [String, IO] Either a String filename to a local
|
20
|
+
# file or an open IO object.
|
21
|
+
# @param content_type [String] String content type of the file data.
|
22
|
+
# @param filename [String] Optional String filename, usually to add context
|
23
|
+
# to a given IO object.
|
24
|
+
# @param opts [Hash] Optional Hash of String key/value pairs to describethis
|
25
|
+
# this uploaded file. Expected Header keys include:
|
26
|
+
# * Content-Transfer-Encoding - Defaults to "binary"
|
27
|
+
# * Content-Disposition - Defaults to "form-data"
|
28
|
+
# * Content-Type - Defaults to the content_type argument.
|
29
|
+
# * Content-ID - Optional.
|
30
|
+
#
|
31
|
+
# @return [Faraday::FilePart]
|
32
|
+
#
|
33
|
+
# @!attribute [r] content_type
|
34
|
+
# The uploaded binary data's content type.
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
#
|
38
|
+
# @!attribute [r] original_filename
|
39
|
+
# The base filename, taken either from the filename_or_io or filename
|
40
|
+
# arguments in #initialize.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
#
|
44
|
+
# @!attribute [r] opts
|
45
|
+
# Extra String key/value pairs to make up the header for this uploaded file.
|
46
|
+
#
|
47
|
+
# @return [Hash]
|
48
|
+
#
|
49
|
+
# @!attribute [r] io
|
50
|
+
# The open IO object for the uploaded file.
|
51
|
+
#
|
52
|
+
# @return [IO]
|
53
|
+
FilePart = ::UploadIO
|
54
|
+
|
55
|
+
# Multipart value used to POST a file.
|
56
|
+
#
|
57
|
+
# @deprecated Use FilePart instead of this class. It behaves identically, with
|
58
|
+
# a matching name to ParamPart.
|
59
|
+
UploadIO = ::UploadIO
|
60
|
+
|
61
|
+
Parts = ::Parts
|
62
|
+
|
63
|
+
# Similar to, but not compatible with CompositeReadIO provided by the
|
64
|
+
# multipart-post gem.
|
65
|
+
# https://github.com/nicksieger/multipart-post/blob/master/lib/composite_io.rb
|
66
|
+
class CompositeReadIO
|
67
|
+
def initialize(*parts)
|
68
|
+
@parts = parts.flatten
|
69
|
+
@ios = @parts.map(&:to_io)
|
70
|
+
@index = 0
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [Integer] sum of the lengths of all the parts
|
74
|
+
def length
|
75
|
+
@parts.inject(0) { |sum, part| sum + part.length }
|
76
|
+
end
|
77
|
+
|
78
|
+
# Rewind each of the IOs and reset the index to 0.
|
79
|
+
#
|
80
|
+
# @return [void]
|
81
|
+
def rewind
|
82
|
+
@ios.each(&:rewind)
|
83
|
+
@index = 0
|
84
|
+
end
|
85
|
+
|
86
|
+
# Read from IOs in order until `length` bytes have been received.
|
87
|
+
#
|
88
|
+
# @param length [Integer, nil]
|
89
|
+
# @param outbuf [String, nil]
|
90
|
+
def read(length = nil, outbuf = nil)
|
91
|
+
got_result = false
|
92
|
+
outbuf = outbuf ? (+outbuf).replace('') : +''
|
93
|
+
|
94
|
+
while (io = current_io)
|
95
|
+
if (result = io.read(length))
|
96
|
+
got_result ||= !result.nil?
|
97
|
+
result.force_encoding('BINARY') if result.respond_to?(:force_encoding)
|
98
|
+
outbuf << result
|
99
|
+
length -= result.length if length
|
100
|
+
break if length&.zero?
|
101
|
+
end
|
102
|
+
advance_io
|
103
|
+
end
|
104
|
+
!got_result && length ? nil : outbuf
|
105
|
+
end
|
106
|
+
|
107
|
+
# Close each of the IOs.
|
108
|
+
#
|
109
|
+
# @return [void]
|
110
|
+
def close
|
111
|
+
@ios.each(&:close)
|
112
|
+
end
|
113
|
+
|
114
|
+
def ensure_open_and_readable
|
115
|
+
# Rubinius compatibility
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def current_io
|
121
|
+
@ios[@index]
|
122
|
+
end
|
123
|
+
|
124
|
+
def advance_io
|
125
|
+
@index += 1
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|