faraday 1.0.1 → 1.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +3 -5
  5. data/examples/client_spec.rb +35 -3
  6. data/examples/client_test.rb +41 -2
  7. data/lib/faraday/adapter/test.rb +59 -43
  8. data/lib/faraday/adapter.rb +2 -12
  9. data/lib/faraday/autoload.rb +2 -10
  10. data/lib/faraday/connection.rb +37 -9
  11. data/lib/faraday/dependency_loader.rb +3 -1
  12. data/lib/faraday/deprecate.rb +110 -0
  13. data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
  14. data/lib/faraday/encoders/nested_params_encoder.rb +7 -2
  15. data/lib/faraday/error.rb +20 -6
  16. data/lib/faraday/methods.rb +6 -0
  17. data/lib/faraday/middleware.rb +14 -4
  18. data/lib/faraday/options/proxy_options.rb +4 -0
  19. data/lib/faraday/options.rb +4 -8
  20. data/lib/faraday/rack_builder.rb +13 -12
  21. data/lib/faraday/request/authorization.rb +14 -7
  22. data/lib/faraday/request/json.rb +55 -0
  23. data/lib/faraday/request.rb +19 -11
  24. data/lib/faraday/response/json.rb +54 -0
  25. data/lib/faraday/response/logger.rb +2 -4
  26. data/lib/faraday/response/raise_error.rb +12 -1
  27. data/lib/faraday/response.rb +3 -7
  28. data/lib/faraday/utils/headers.rb +2 -2
  29. data/lib/faraday/utils.rb +2 -2
  30. data/lib/faraday/version.rb +5 -0
  31. data/lib/faraday.rb +67 -40
  32. data/spec/faraday/adapter/em_http_spec.rb +39 -37
  33. data/spec/faraday/adapter/em_synchrony_spec.rb +11 -9
  34. data/spec/faraday/adapter/test_spec.rb +377 -0
  35. data/spec/faraday/connection_spec.rb +45 -0
  36. data/spec/faraday/deprecate_spec.rb +147 -0
  37. data/spec/faraday/error_spec.rb +15 -0
  38. data/spec/faraday/middleware_spec.rb +32 -6
  39. data/spec/faraday/options/proxy_options_spec.rb +7 -0
  40. data/spec/faraday/params_encoders/flat_spec.rb +8 -0
  41. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  42. data/spec/faraday/rack_builder_spec.rb +149 -0
  43. data/spec/faraday/request/authorization_spec.rb +10 -2
  44. data/spec/faraday/request/json_spec.rb +111 -0
  45. data/spec/faraday/request_spec.rb +16 -5
  46. data/spec/faraday/response/json_spec.rb +119 -0
  47. data/spec/faraday/response/raise_error_spec.rb +63 -0
  48. data/spec/spec_helper.rb +2 -0
  49. data/spec/support/shared_examples/adapter.rb +2 -1
  50. data/spec/support/shared_examples/request_method.rb +39 -11
  51. metadata +156 -30
  52. data/lib/faraday/adapter/em_http.rb +0 -286
  53. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
  54. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
  55. data/lib/faraday/adapter/em_synchrony.rb +0 -150
  56. data/lib/faraday/adapter/excon.rb +0 -124
  57. data/lib/faraday/adapter/httpclient.rb +0 -152
  58. data/lib/faraday/adapter/net_http.rb +0 -219
  59. data/lib/faraday/adapter/net_http_persistent.rb +0 -91
  60. data/lib/faraday/adapter/patron.rb +0 -132
  61. data/lib/faraday/adapter/rack.rb +0 -75
  62. data/lib/faraday/file_part.rb +0 -128
  63. data/lib/faraday/param_part.rb +0 -53
  64. data/lib/faraday/request/multipart.rb +0 -99
  65. data/lib/faraday/request/retry.rb +0 -239
  66. data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
  67. data/spec/faraday/request/multipart_spec.rb +0 -274
  68. data/spec/faraday/request/retry_spec.rb +0 -242
@@ -1,219 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- begin
4
- require 'net/https'
5
- rescue LoadError
6
- warn 'Warning: no such file to load -- net/https. ' \
7
- 'Make sure openssl is installed if you want ssl support'
8
- require 'net/http'
9
- end
10
- require 'zlib'
11
-
12
- module Faraday
13
- class Adapter
14
- # Net::HTTP adapter.
15
- class NetHttp < Faraday::Adapter
16
- exceptions = [
17
- IOError,
18
- Errno::EADDRNOTAVAIL,
19
- Errno::ECONNABORTED,
20
- Errno::ECONNREFUSED,
21
- Errno::ECONNRESET,
22
- Errno::EHOSTUNREACH,
23
- Errno::EINVAL,
24
- Errno::ENETUNREACH,
25
- Errno::EPIPE,
26
- Net::HTTPBadResponse,
27
- Net::HTTPHeaderSyntaxError,
28
- Net::ProtocolError,
29
- SocketError,
30
- Zlib::GzipFile::Error
31
- ]
32
-
33
- if defined?(::OpenSSL::SSL::SSLError)
34
- exceptions << ::OpenSSL::SSL::SSLError
35
- end
36
- exceptions << ::Net::OpenTimeout if defined?(::Net::OpenTimeout)
37
-
38
- NET_HTTP_EXCEPTIONS = exceptions.freeze
39
-
40
- def initialize(app = nil, opts = {}, &block)
41
- @ssl_cert_store = nil
42
- super(app, opts, &block)
43
- end
44
-
45
- def build_connection(env)
46
- net_http_connection(env).tap do |http|
47
- if http.respond_to?(:use_ssl=)
48
- http.use_ssl = env[:url].scheme == 'https'
49
- end
50
- configure_ssl(http, env[:ssl])
51
- configure_request(http, env[:request])
52
- end
53
- end
54
-
55
- def net_http_connection(env)
56
- klass = if (proxy = env[:request][:proxy])
57
- Net::HTTP::Proxy(proxy[:uri].hostname, proxy[:uri].port,
58
- proxy[:user], proxy[:password])
59
- else
60
- Net::HTTP
61
- end
62
- port = env[:url].port || (env[:url].scheme == 'https' ? 443 : 80)
63
- klass.new(env[:url].hostname, port)
64
- end
65
-
66
- def call(env)
67
- super
68
- http_response = connection(env) do |http|
69
- begin
70
- perform_request(http, env)
71
- rescue *NET_HTTP_EXCEPTIONS => e
72
- if defined?(OpenSSL) && e.is_a?(OpenSSL::SSL::SSLError)
73
- raise Faraday::SSLError, e
74
- end
75
-
76
- raise Faraday::ConnectionFailed, e
77
- end
78
- end
79
-
80
- save_response(env, http_response.code.to_i,
81
- http_response.body || +'', nil,
82
- http_response.message) do |response_headers|
83
- http_response.each_header do |key, value|
84
- response_headers[key] = value
85
- end
86
- end
87
-
88
- @app.call env
89
- rescue Timeout::Error, Errno::ETIMEDOUT => e
90
- raise Faraday::TimeoutError, e
91
- end
92
-
93
- private
94
-
95
- def create_request(env)
96
- request = Net::HTTPGenericRequest.new \
97
- env[:method].to_s.upcase, # request method
98
- !!env[:body], # is there request body
99
- env[:method] != :head, # is there response body
100
- env[:url].request_uri, # request uri path
101
- env[:request_headers] # request headers
102
-
103
- if env[:body].respond_to?(:read)
104
- request.body_stream = env[:body]
105
- else
106
- request.body = env[:body]
107
- end
108
- request
109
- end
110
-
111
- def perform_request(http, env)
112
- if env[:request].stream_response?
113
- size = 0
114
- yielded = false
115
- http_response = request_with_wrapped_block(http, env) do |chunk|
116
- if chunk.bytesize.positive? || size.positive?
117
- yielded = true
118
- size += chunk.bytesize
119
- env[:request].on_data.call(chunk, size)
120
- end
121
- end
122
- env[:request].on_data.call(+'', 0) unless yielded
123
- # Net::HTTP returns something,
124
- # but it's not meaningful according to the docs.
125
- http_response.body = nil
126
- http_response
127
- else
128
- request_with_wrapped_block(http, env)
129
- end
130
- end
131
-
132
- def request_with_wrapped_block(http, env, &block)
133
- if (env[:method] == :get) && !env[:body]
134
- # prefer `get` to `request` because the former handles gzip (ruby 1.9)
135
- request_via_get_method(http, env, &block)
136
- else
137
- request_via_request_method(http, env, &block)
138
- end
139
- end
140
-
141
- def request_via_get_method(http, env, &block)
142
- # Must use Net::HTTP#start and pass it a block otherwise the server's
143
- # TCP socket does not close correctly.
144
- http.start do |opened_http|
145
- opened_http.get env[:url].request_uri, env[:request_headers], &block
146
- end
147
- end
148
-
149
- def request_via_request_method(http, env, &block)
150
- # Must use Net::HTTP#start and pass it a block otherwise the server's
151
- # TCP socket does not close correctly.
152
- http.start do |opened_http|
153
- if block_given?
154
- opened_http.request create_request(env) do |response|
155
- response.read_body(&block)
156
- end
157
- else
158
- opened_http.request create_request(env)
159
- end
160
- end
161
- end
162
-
163
- def configure_ssl(http, ssl)
164
- return unless ssl
165
-
166
- http.verify_mode = ssl_verify_mode(ssl)
167
- http.cert_store = ssl_cert_store(ssl)
168
-
169
- http.cert = ssl[:client_cert] if ssl[:client_cert]
170
- http.key = ssl[:client_key] if ssl[:client_key]
171
- http.ca_file = ssl[:ca_file] if ssl[:ca_file]
172
- http.ca_path = ssl[:ca_path] if ssl[:ca_path]
173
- http.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
174
- http.ssl_version = ssl[:version] if ssl[:version]
175
- http.min_version = ssl[:min_version] if ssl[:min_version]
176
- http.max_version = ssl[:max_version] if ssl[:max_version]
177
- end
178
-
179
- def configure_request(http, req)
180
- if (sec = request_timeout(:read, req))
181
- http.read_timeout = sec
182
- end
183
-
184
- if (sec = http.respond_to?(:write_timeout=) &&
185
- request_timeout(:write, req))
186
- http.write_timeout = sec
187
- end
188
-
189
- if (sec = request_timeout(:open, req))
190
- http.open_timeout = sec
191
- end
192
-
193
- # Only set if Net::Http supports it, since Ruby 2.5.
194
- http.max_retries = 0 if http.respond_to?(:max_retries=)
195
-
196
- @config_block&.call(http)
197
- end
198
-
199
- def ssl_cert_store(ssl)
200
- return ssl[:cert_store] if ssl[:cert_store]
201
-
202
- @ssl_cert_store ||= begin
203
- # Use the default cert store by default, i.e. system ca certs
204
- OpenSSL::X509::Store.new.tap(&:set_default_paths)
205
- end
206
- end
207
-
208
- def ssl_verify_mode(ssl)
209
- ssl[:verify_mode] || begin
210
- if ssl.fetch(:verify, true)
211
- OpenSSL::SSL::VERIFY_PEER
212
- else
213
- OpenSSL::SSL::VERIFY_NONE
214
- end
215
- end
216
- end
217
- end
218
- end
219
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- # Net::HTTP::Persistent adapter.
6
- class NetHttpPersistent < NetHttp
7
- dependency 'net/http/persistent'
8
-
9
- private
10
-
11
- def net_http_connection(env)
12
- @cached_connection ||=
13
- if Net::HTTP::Persistent.instance_method(:initialize)
14
- .parameters.first == %i[key name]
15
- options = { name: 'Faraday' }
16
- if @connection_options.key?(:pool_size)
17
- options[:pool_size] = @connection_options[:pool_size]
18
- end
19
- Net::HTTP::Persistent.new(**options)
20
- else
21
- Net::HTTP::Persistent.new('Faraday')
22
- end
23
-
24
- proxy_uri = proxy_uri(env)
25
- if @cached_connection.proxy_uri != proxy_uri
26
- @cached_connection.proxy = proxy_uri
27
- end
28
- @cached_connection
29
- end
30
-
31
- def proxy_uri(env)
32
- proxy_uri = nil
33
- if (proxy = env[:request][:proxy])
34
- proxy_uri = if proxy[:uri].is_a?(::URI::HTTP)
35
- proxy[:uri].dup
36
- else
37
- ::URI.parse(proxy[:uri].to_s)
38
- end
39
- proxy_uri.user = proxy_uri.password = nil
40
- # awful patch for net-http-persistent 2.8
41
- # not unescaping user/password
42
- if proxy[:user]
43
- (class << proxy_uri; self; end).class_eval do
44
- define_method(:user) { proxy[:user] }
45
- define_method(:password) { proxy[:password] }
46
- end
47
- end
48
- end
49
- proxy_uri
50
- end
51
-
52
- def perform_request(http, env)
53
- http.request env[:url], create_request(env)
54
- rescue Errno::ETIMEDOUT => e
55
- raise Faraday::TimeoutError, e
56
- rescue Net::HTTP::Persistent::Error => e
57
- raise Faraday::TimeoutError, e if e.message.include? 'Timeout'
58
-
59
- if e.message.include? 'connection refused'
60
- raise Faraday::ConnectionFailed, e
61
- end
62
-
63
- raise
64
- end
65
-
66
- SSL_CONFIGURATIONS = {
67
- certificate: :client_cert,
68
- private_key: :client_key,
69
- ca_file: :ca_file,
70
- ssl_version: :version,
71
- min_version: :min_version,
72
- max_version: :max_version
73
- }.freeze
74
-
75
- def configure_ssl(http, ssl)
76
- return unless ssl
77
-
78
- http_set(http, :verify_mode, ssl_verify_mode(ssl))
79
- http_set(http, :cert_store, ssl_cert_store(ssl))
80
-
81
- SSL_CONFIGURATIONS
82
- .select { |_, key| ssl[key] }
83
- .each { |target, key| http_set(http, target, ssl[key]) }
84
- end
85
-
86
- def http_set(http, attr, value)
87
- http.send("#{attr}=", value) if http.send(attr) != value
88
- end
89
- end
90
- end
91
- end
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- # Patron adapter.
6
- class Patron < Faraday::Adapter
7
- dependency 'patron'
8
-
9
- def build_connection(env)
10
- session = ::Patron::Session.new
11
- @config_block&.call(session)
12
- if (env[:url].scheme == 'https') && env[:ssl]
13
- configure_ssl(session, env[:ssl])
14
- end
15
-
16
- if (req = env[:request])
17
- configure_timeouts(session, req)
18
- configure_proxy(session, req[:proxy])
19
- end
20
-
21
- session
22
- end
23
-
24
- def call(env)
25
- super
26
- # TODO: support streaming requests
27
- env[:body] = env[:body].read if env[:body].respond_to? :read
28
-
29
- response = connection(env) do |session|
30
- begin
31
- data = env[:body] ? env[:body].to_s : nil
32
- session.request(env[:method], env[:url].to_s,
33
- env[:request_headers], data: data)
34
- rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
35
- raise Faraday::ConnectionFailed, $ERROR_INFO
36
- end
37
- end
38
-
39
- if (req = env[:request]).stream_response?
40
- warn "Streaming downloads for #{self.class.name} " \
41
- 'are not yet implemented.'
42
- req.on_data.call(response.body, response.body.bytesize)
43
- end
44
- # Remove the "HTTP/1.1 200", leaving just the reason phrase
45
- reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
46
-
47
- save_response(env, response.status, response.body,
48
- response.headers, reason_phrase)
49
-
50
- @app.call env
51
- rescue ::Patron::TimeoutError => e
52
- if connection_timed_out_message?(e.message)
53
- raise Faraday::ConnectionFailed, e
54
- end
55
-
56
- raise Faraday::TimeoutError, e
57
- rescue ::Patron::Error => e
58
- if e.message.include?('code 407')
59
- raise Faraday::ConnectionFailed,
60
- %(407 "Proxy Authentication Required ")
61
- end
62
-
63
- raise Faraday::ConnectionFailed, e
64
- end
65
-
66
- if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
67
- # HAX: helps but doesn't work completely
68
- # https://github.com/toland/patron/issues/34
69
- ::Patron::Request::VALID_ACTIONS.tap do |actions|
70
- if actions[0].is_a?(Symbol)
71
- actions << :patch unless actions.include? :patch
72
- actions << :options unless actions.include? :options
73
- else
74
- # Patron 0.4.20 and up
75
- actions << 'PATCH' unless actions.include? 'PATCH'
76
- actions << 'OPTIONS' unless actions.include? 'OPTIONS'
77
- end
78
- end
79
- end
80
-
81
- def configure_ssl(session, ssl)
82
- if ssl.fetch(:verify, true)
83
- session.cacert = ssl[:ca_file]
84
- else
85
- session.insecure = true
86
- end
87
- end
88
-
89
- def configure_timeouts(session, req)
90
- return unless req
91
-
92
- if (sec = request_timeout(:read, req))
93
- session.timeout = sec
94
- end
95
-
96
- return unless (sec = request_timeout(:open, req))
97
-
98
- session.connect_timeout = sec
99
- end
100
-
101
- def configure_proxy(session, proxy)
102
- return unless proxy
103
-
104
- proxy_uri = proxy[:uri].dup
105
- proxy_uri.user = proxy[:user] &&
106
- Utils.escape(proxy[:user]).gsub('+', '%20')
107
- proxy_uri.password = proxy[:password] &&
108
- Utils.escape(proxy[:password]).gsub('+', '%20')
109
- session.proxy = proxy_uri.to_s
110
- end
111
-
112
- private
113
-
114
- CURL_TIMEOUT_MESSAGES = [
115
- 'Connection time-out',
116
- 'Connection timed out',
117
- 'Timed out before name resolve',
118
- 'server connect has timed out',
119
- 'Resolving timed out',
120
- 'name lookup timed out',
121
- 'timed out before SSL',
122
- 'connect() timed out'
123
- ].freeze
124
-
125
- def connection_timed_out_message?(message)
126
- CURL_TIMEOUT_MESSAGES.any? do |curl_message|
127
- message.include?(curl_message)
128
- end
129
- end
130
- end
131
- end
132
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- # Sends requests to a Rack app.
6
- #
7
- # @example
8
- #
9
- # class MyRackApp
10
- # def call(env)
11
- # [200, {'Content-Type' => 'text/html'}, ["hello world"]]
12
- # end
13
- # end
14
- #
15
- # Faraday.new do |conn|
16
- # conn.adapter :rack, MyRackApp.new
17
- # end
18
- class Rack < Faraday::Adapter
19
- dependency 'rack/test'
20
-
21
- # not prefixed with "HTTP_"
22
- SPECIAL_HEADERS = %w[CONTENT_LENGTH CONTENT_TYPE].freeze
23
-
24
- def initialize(faraday_app, rack_app)
25
- super(faraday_app)
26
- mock_session = ::Rack::MockSession.new(rack_app)
27
- @session = ::Rack::Test::Session.new(mock_session)
28
- end
29
-
30
- def call(env)
31
- super
32
- rack_env = build_rack_env(env)
33
-
34
- env[:request_headers]&.each do |name, value|
35
- name = name.upcase.tr('-', '_')
36
- name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
37
- rack_env[name] = value
38
- end
39
-
40
- timeout = request_timeout(:open, env[:request])
41
- timeout ||= request_timeout(:read, env[:request])
42
- response = if timeout
43
- Timer.timeout(timeout, Faraday::TimeoutError) do
44
- execute_request(env, rack_env)
45
- end
46
- else
47
- execute_request(env, rack_env)
48
- end
49
-
50
- if (req = env[:request]).stream_response?
51
- warn "Streaming downloads for #{self.class.name} " \
52
- 'are not yet implemented.'
53
- req.on_data.call(response.body, response.body.bytesize)
54
- end
55
-
56
- save_response(env, response.status, response.body, response.headers)
57
- @app.call env
58
- end
59
-
60
- private
61
-
62
- def execute_request(env, rack_env)
63
- @session.request(env[:url].to_s, rack_env)
64
- end
65
-
66
- def build_rack_env(env)
67
- {
68
- method: env[:method],
69
- input: env[:body].respond_to?(:read) ? env[:body].read : env[:body],
70
- 'rack.url_scheme' => env[:url].scheme
71
- }
72
- end
73
- end
74
- end
75
- end
@@ -1,128 +0,0 @@
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
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # Multipart value used to POST data with a content type.
5
- class ParamPart
6
- # @param value [String] Uploaded content as a String.
7
- # @param content_type [String] String content type of the value.
8
- # @param content_id [String] Optional String of this value's Content-ID.
9
- #
10
- # @return [Faraday::ParamPart]
11
- def initialize(value, content_type, content_id = nil)
12
- @value = value
13
- @content_type = content_type
14
- @content_id = content_id
15
- end
16
-
17
- # Converts this value to a form part.
18
- #
19
- # @param boundary [String] String multipart boundary that must not exist in
20
- # the content exactly.
21
- # @param key [String] String key name for this value.
22
- #
23
- # @return [Faraday::Parts::Part]
24
- def to_part(boundary, key)
25
- Faraday::Parts::Part.new(boundary, key, value, headers)
26
- end
27
-
28
- # Returns a Hash of String key/value pairs.
29
- #
30
- # @return [Hash]
31
- def headers
32
- {
33
- 'Content-Type' => content_type,
34
- 'Content-ID' => content_id
35
- }
36
- end
37
-
38
- # The content to upload.
39
- #
40
- # @return [String]
41
- attr_reader :value
42
-
43
- # The value's content type.
44
- #
45
- # @return [String]
46
- attr_reader :content_type
47
-
48
- # The value's content ID, if given.
49
- #
50
- # @return [String, nil]
51
- attr_reader :content_id
52
- end
53
- end