faraday 1.8.0 → 1.10.3
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/lib/faraday/connection.rb +15 -15
- data/lib/faraday/dependency_loader.rb +3 -1
- data/lib/faraday/deprecate.rb +110 -0
- data/lib/faraday/error.rb +0 -6
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request.rb +10 -12
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +2 -4
- data/lib/faraday/response.rb +3 -1
- data/lib/faraday/version.rb +1 -1
- data/lib/faraday.rb +10 -2
- data/spec/faraday/deprecate_spec.rb +147 -0
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request_spec.rb +1 -1
- data/spec/faraday/response/json_spec.rb +119 -0
- data/spec/spec_helper.rb +2 -0
- metadata +33 -25
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/multipart.rb +0 -106
- data/lib/faraday/request/retry.rb +0 -239
- data/spec/faraday/request/multipart_spec.rb +0 -302
- data/spec/faraday/request/retry_spec.rb +0 -242
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Request::Json do
|
4
|
+
let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }) }
|
5
|
+
|
6
|
+
def process(body, content_type = nil)
|
7
|
+
env = { body: body, request_headers: Faraday::Utils::Headers.new }
|
8
|
+
env[:request_headers]['content-type'] = content_type if content_type
|
9
|
+
middleware.call(Faraday::Env.from(env)).env
|
10
|
+
end
|
11
|
+
|
12
|
+
def result_body
|
13
|
+
result[:body]
|
14
|
+
end
|
15
|
+
|
16
|
+
def result_type
|
17
|
+
result[:request_headers]['content-type']
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'no body' do
|
21
|
+
let(:result) { process(nil) }
|
22
|
+
|
23
|
+
it "doesn't change body" do
|
24
|
+
expect(result_body).to be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "doesn't add content type" do
|
28
|
+
expect(result_type).to be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'empty body' do
|
33
|
+
let(:result) { process('') }
|
34
|
+
|
35
|
+
it "doesn't change body" do
|
36
|
+
expect(result_body).to be_empty
|
37
|
+
end
|
38
|
+
|
39
|
+
it "doesn't add content type" do
|
40
|
+
expect(result_type).to be_nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'string body' do
|
45
|
+
let(:result) { process('{"a":1}') }
|
46
|
+
|
47
|
+
it "doesn't change body" do
|
48
|
+
expect(result_body).to eq('{"a":1}')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'adds content type' do
|
52
|
+
expect(result_type).to eq('application/json')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'object body' do
|
57
|
+
let(:result) { process(a: 1) }
|
58
|
+
|
59
|
+
it 'encodes body' do
|
60
|
+
expect(result_body).to eq('{"a":1}')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'adds content type' do
|
64
|
+
expect(result_type).to eq('application/json')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'empty object body' do
|
69
|
+
let(:result) { process({}) }
|
70
|
+
|
71
|
+
it 'encodes body' do
|
72
|
+
expect(result_body).to eq('{}')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'object body with json type' do
|
77
|
+
let(:result) { process({ a: 1 }, 'application/json; charset=utf-8') }
|
78
|
+
|
79
|
+
it 'encodes body' do
|
80
|
+
expect(result_body).to eq('{"a":1}')
|
81
|
+
end
|
82
|
+
|
83
|
+
it "doesn't change content type" do
|
84
|
+
expect(result_type).to eq('application/json; charset=utf-8')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'object body with vendor json type' do
|
89
|
+
let(:result) { process({ a: 1 }, 'application/vnd.myapp.v1+json; charset=utf-8') }
|
90
|
+
|
91
|
+
it 'encodes body' do
|
92
|
+
expect(result_body).to eq('{"a":1}')
|
93
|
+
end
|
94
|
+
|
95
|
+
it "doesn't change content type" do
|
96
|
+
expect(result_type).to eq('application/vnd.myapp.v1+json; charset=utf-8')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'object body with incompatible type' do
|
101
|
+
let(:result) { process({ a: 1 }, 'application/xml; charset=utf-8') }
|
102
|
+
|
103
|
+
it "doesn't change body" do
|
104
|
+
expect(result_body).to eq(a: 1)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "doesn't change content type" do
|
108
|
+
expect(result_type).to eq('application/xml; charset=utf-8')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -25,7 +25,7 @@ RSpec.describe Faraday::Request do
|
|
25
25
|
describe 'deprecate method for HTTP method' do
|
26
26
|
let(:http_method) { :post }
|
27
27
|
let(:expected_warning) do
|
28
|
-
%r{
|
28
|
+
%r{NOTE: Faraday::Request#method is deprecated; use http_method instead\. It will be removed in or after version 2.0 \nFaraday::Request#method called from .+/spec/faraday/request_spec.rb:\d+.}
|
29
29
|
end
|
30
30
|
|
31
31
|
it { expect(subject.method).to eq(:post) }
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Response::Json, type: :response do
|
4
|
+
let(:options) { {} }
|
5
|
+
let(:headers) { {} }
|
6
|
+
let(:middleware) do
|
7
|
+
described_class.new(lambda { |env|
|
8
|
+
Faraday::Response.new(env)
|
9
|
+
}, **options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def process(body, content_type = 'application/json', options = {})
|
13
|
+
env = {
|
14
|
+
body: body, request: options,
|
15
|
+
request_headers: Faraday::Utils::Headers.new,
|
16
|
+
response_headers: Faraday::Utils::Headers.new(headers)
|
17
|
+
}
|
18
|
+
env[:response_headers]['content-type'] = content_type if content_type
|
19
|
+
yield(env) if block_given?
|
20
|
+
middleware.call(Faraday::Env.from(env))
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'no type matching' do
|
24
|
+
it "doesn't change nil body" do
|
25
|
+
expect(process(nil).body).to be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'nullifies empty body' do
|
29
|
+
expect(process('').body).to be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'parses json body' do
|
33
|
+
response = process('{"a":1}')
|
34
|
+
expect(response.body).to eq('a' => 1)
|
35
|
+
expect(response.env[:raw_body]).to be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with preserving raw' do
|
40
|
+
let(:options) { { preserve_raw: true } }
|
41
|
+
|
42
|
+
it 'parses json body' do
|
43
|
+
response = process('{"a":1}')
|
44
|
+
expect(response.body).to eq('a' => 1)
|
45
|
+
expect(response.env[:raw_body]).to eq('{"a":1}')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with default regexp type matching' do
|
50
|
+
it 'parses json body of correct type' do
|
51
|
+
response = process('{"a":1}', 'application/x-json')
|
52
|
+
expect(response.body).to eq('a' => 1)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'ignores json body of incorrect type' do
|
56
|
+
response = process('{"a":1}', 'text/json-xml')
|
57
|
+
expect(response.body).to eq('{"a":1}')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with array type matching' do
|
62
|
+
let(:options) { { content_type: %w[a/b c/d] } }
|
63
|
+
|
64
|
+
it 'parses json body of correct type' do
|
65
|
+
expect(process('{"a":1}', 'a/b').body).to be_a(Hash)
|
66
|
+
expect(process('{"a":1}', 'c/d').body).to be_a(Hash)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'ignores json body of incorrect type' do
|
70
|
+
expect(process('{"a":1}', 'a/d').body).not_to be_a(Hash)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'chokes on invalid json' do
|
75
|
+
expect { process('{!') }.to raise_error(Faraday::ParsingError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'includes the response on the ParsingError instance' do
|
79
|
+
begin
|
80
|
+
process('{') { |env| env[:response] = Faraday::Response.new }
|
81
|
+
raise 'Parsing should have failed.'
|
82
|
+
rescue Faraday::ParsingError => e
|
83
|
+
expect(e.response).to be_a(Faraday::Response)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'HEAD responses' do
|
88
|
+
it "nullifies the body if it's only one space" do
|
89
|
+
response = process(' ')
|
90
|
+
expect(response.body).to be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "nullifies the body if it's two spaces" do
|
94
|
+
response = process(' ')
|
95
|
+
expect(response.body).to be_nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'JSON options' do
|
100
|
+
let(:body) { '{"a": 1}' }
|
101
|
+
let(:result) { { a: 1 } }
|
102
|
+
let(:options) do
|
103
|
+
{
|
104
|
+
parser_options: {
|
105
|
+
symbolize_names: true
|
106
|
+
}
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'passes relevant options to JSON parse' do
|
111
|
+
expect(::JSON).to receive(:parse)
|
112
|
+
.with(body, options[:parser_options])
|
113
|
+
.and_return(result)
|
114
|
+
|
115
|
+
response = process(body)
|
116
|
+
expect(response.body).to eq(result)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -38,6 +38,8 @@ require 'pry'
|
|
38
38
|
|
39
39
|
Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
|
40
40
|
|
41
|
+
Faraday::Deprecate.skip = false
|
42
|
+
|
41
43
|
RSpec.configure do |config|
|
42
44
|
# rspec-expectations config goes here. You can use an alternate
|
43
45
|
# assertion/expectation library such as wrong or the stdlib/minitest
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faraday
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.10.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "@technoweenie"
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-01-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: faraday-em_http
|
@@ -60,14 +60,28 @@ dependencies:
|
|
60
60
|
requirements:
|
61
61
|
- - "~>"
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: 1.0
|
63
|
+
version: '1.0'
|
64
64
|
type: :runtime
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
68
|
- - "~>"
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: 1.0
|
70
|
+
version: '1.0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: faraday-multipart
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - "~>"
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '1.0'
|
78
|
+
type: :runtime
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - "~>"
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '1.0'
|
71
85
|
- !ruby/object:Gem::Dependency
|
72
86
|
name: faraday-net_http
|
73
87
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,14 +102,14 @@ dependencies:
|
|
88
102
|
requirements:
|
89
103
|
- - "~>"
|
90
104
|
- !ruby/object:Gem::Version
|
91
|
-
version: '1.
|
105
|
+
version: '1.0'
|
92
106
|
type: :runtime
|
93
107
|
prerelease: false
|
94
108
|
version_requirements: !ruby/object:Gem::Requirement
|
95
109
|
requirements:
|
96
110
|
- - "~>"
|
97
111
|
- !ruby/object:Gem::Version
|
98
|
-
version: '1.
|
112
|
+
version: '1.0'
|
99
113
|
- !ruby/object:Gem::Dependency
|
100
114
|
name: faraday-patron
|
101
115
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,25 +139,19 @@ dependencies:
|
|
125
139
|
- !ruby/object:Gem::Version
|
126
140
|
version: '1.0'
|
127
141
|
- !ruby/object:Gem::Dependency
|
128
|
-
name:
|
142
|
+
name: faraday-retry
|
129
143
|
requirement: !ruby/object:Gem::Requirement
|
130
144
|
requirements:
|
131
|
-
- - "
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
version: '1.2'
|
134
|
-
- - "<"
|
145
|
+
- - "~>"
|
135
146
|
- !ruby/object:Gem::Version
|
136
|
-
version: '
|
147
|
+
version: '1.0'
|
137
148
|
type: :runtime
|
138
149
|
prerelease: false
|
139
150
|
version_requirements: !ruby/object:Gem::Requirement
|
140
151
|
requirements:
|
141
|
-
- - "
|
142
|
-
- !ruby/object:Gem::Version
|
143
|
-
version: '1.2'
|
144
|
-
- - "<"
|
152
|
+
- - "~>"
|
145
153
|
- !ruby/object:Gem::Version
|
146
|
-
version: '
|
154
|
+
version: '1.0'
|
147
155
|
- !ruby/object:Gem::Dependency
|
148
156
|
name: ruby2_keywords
|
149
157
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,10 +186,10 @@ files:
|
|
178
186
|
- lib/faraday/autoload.rb
|
179
187
|
- lib/faraday/connection.rb
|
180
188
|
- lib/faraday/dependency_loader.rb
|
189
|
+
- lib/faraday/deprecate.rb
|
181
190
|
- lib/faraday/encoders/flat_params_encoder.rb
|
182
191
|
- lib/faraday/encoders/nested_params_encoder.rb
|
183
192
|
- lib/faraday/error.rb
|
184
|
-
- lib/faraday/file_part.rb
|
185
193
|
- lib/faraday/logging/formatter.rb
|
186
194
|
- lib/faraday/methods.rb
|
187
195
|
- lib/faraday/middleware.rb
|
@@ -192,18 +200,17 @@ files:
|
|
192
200
|
- lib/faraday/options/proxy_options.rb
|
193
201
|
- lib/faraday/options/request_options.rb
|
194
202
|
- lib/faraday/options/ssl_options.rb
|
195
|
-
- lib/faraday/param_part.rb
|
196
203
|
- lib/faraday/parameters.rb
|
197
204
|
- lib/faraday/rack_builder.rb
|
198
205
|
- lib/faraday/request.rb
|
199
206
|
- lib/faraday/request/authorization.rb
|
200
207
|
- lib/faraday/request/basic_authentication.rb
|
201
208
|
- lib/faraday/request/instrumentation.rb
|
202
|
-
- lib/faraday/request/
|
203
|
-
- lib/faraday/request/retry.rb
|
209
|
+
- lib/faraday/request/json.rb
|
204
210
|
- lib/faraday/request/token_authentication.rb
|
205
211
|
- lib/faraday/request/url_encoded.rb
|
206
212
|
- lib/faraday/response.rb
|
213
|
+
- lib/faraday/response/json.rb
|
207
214
|
- lib/faraday/response/logger.rb
|
208
215
|
- lib/faraday/response/raise_error.rb
|
209
216
|
- lib/faraday/utils.rb
|
@@ -224,6 +231,7 @@ files:
|
|
224
231
|
- spec/faraday/adapter_spec.rb
|
225
232
|
- spec/faraday/composite_read_io_spec.rb
|
226
233
|
- spec/faraday/connection_spec.rb
|
234
|
+
- spec/faraday/deprecate_spec.rb
|
227
235
|
- spec/faraday/error_spec.rb
|
228
236
|
- spec/faraday/middleware_spec.rb
|
229
237
|
- spec/faraday/options/env_spec.rb
|
@@ -235,10 +243,10 @@ files:
|
|
235
243
|
- spec/faraday/rack_builder_spec.rb
|
236
244
|
- spec/faraday/request/authorization_spec.rb
|
237
245
|
- spec/faraday/request/instrumentation_spec.rb
|
238
|
-
- spec/faraday/request/
|
239
|
-
- spec/faraday/request/retry_spec.rb
|
246
|
+
- spec/faraday/request/json_spec.rb
|
240
247
|
- spec/faraday/request/url_encoded_spec.rb
|
241
248
|
- spec/faraday/request_spec.rb
|
249
|
+
- spec/faraday/response/json_spec.rb
|
242
250
|
- spec/faraday/response/logger_spec.rb
|
243
251
|
- spec/faraday/response/middleware_spec.rb
|
244
252
|
- spec/faraday/response/raise_error_spec.rb
|
@@ -260,7 +268,7 @@ licenses:
|
|
260
268
|
- MIT
|
261
269
|
metadata:
|
262
270
|
homepage_uri: https://lostisland.github.io/faraday
|
263
|
-
changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.
|
271
|
+
changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.10.3
|
264
272
|
source_code_uri: https://github.com/lostisland/faraday
|
265
273
|
bug_tracker_uri: https://github.com/lostisland/faraday/issues
|
266
274
|
post_install_message:
|
@@ -279,7 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
279
287
|
- !ruby/object:Gem::Version
|
280
288
|
version: '0'
|
281
289
|
requirements: []
|
282
|
-
rubygems_version: 3.
|
290
|
+
rubygems_version: 3.1.6
|
283
291
|
signing_key:
|
284
292
|
specification_version: 4
|
285
293
|
summary: HTTP/REST API client library.
|
data/lib/faraday/file_part.rb
DELETED
@@ -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
|
data/lib/faraday/param_part.rb
DELETED
@@ -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
|
@@ -1,106 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path('url_encoded', __dir__)
|
4
|
-
require 'securerandom'
|
5
|
-
|
6
|
-
module Faraday
|
7
|
-
class Request
|
8
|
-
# Middleware for supporting multi-part requests.
|
9
|
-
class Multipart < UrlEncoded
|
10
|
-
self.mime_type = 'multipart/form-data'
|
11
|
-
unless defined?(::Faraday::Request::Multipart::DEFAULT_BOUNDARY_PREFIX)
|
12
|
-
DEFAULT_BOUNDARY_PREFIX = '-----------RubyMultipartPost'
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize(app = nil, options = {})
|
16
|
-
super(app)
|
17
|
-
@options = options
|
18
|
-
end
|
19
|
-
|
20
|
-
# Checks for files in the payload, otherwise leaves everything untouched.
|
21
|
-
#
|
22
|
-
# @param env [Faraday::Env]
|
23
|
-
def call(env)
|
24
|
-
match_content_type(env) do |params|
|
25
|
-
env.request.boundary ||= unique_boundary
|
26
|
-
env.request_headers[CONTENT_TYPE] +=
|
27
|
-
"; boundary=#{env.request.boundary}"
|
28
|
-
env.body = create_multipart(env, params)
|
29
|
-
end
|
30
|
-
@app.call env
|
31
|
-
end
|
32
|
-
|
33
|
-
# @param env [Faraday::Env]
|
34
|
-
def process_request?(env)
|
35
|
-
type = request_type(env)
|
36
|
-
env.body.respond_to?(:each_key) && !env.body.empty? && (
|
37
|
-
(type.empty? && has_multipart?(env.body)) ||
|
38
|
-
(type == self.class.mime_type)
|
39
|
-
)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Returns true if obj is an enumerable with values that are multipart.
|
43
|
-
#
|
44
|
-
# @param obj [Object]
|
45
|
-
# @return [Boolean]
|
46
|
-
def has_multipart?(obj) # rubocop:disable Naming/PredicateName
|
47
|
-
if obj.respond_to?(:each)
|
48
|
-
(obj.respond_to?(:values) ? obj.values : obj).each do |val|
|
49
|
-
return true if val.respond_to?(:content_type) || has_multipart?(val)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
false
|
53
|
-
end
|
54
|
-
|
55
|
-
# @param env [Faraday::Env]
|
56
|
-
# @param params [Hash]
|
57
|
-
def create_multipart(env, params)
|
58
|
-
boundary = env.request.boundary
|
59
|
-
parts = process_params(params) do |key, value|
|
60
|
-
part(boundary, key, value)
|
61
|
-
end
|
62
|
-
parts << Faraday::Parts::EpiloguePart.new(boundary)
|
63
|
-
|
64
|
-
body = Faraday::CompositeReadIO.new(parts)
|
65
|
-
env.request_headers[Faraday::Env::ContentLength] = body.length.to_s
|
66
|
-
body
|
67
|
-
end
|
68
|
-
|
69
|
-
def part(boundary, key, value)
|
70
|
-
if value.respond_to?(:to_part)
|
71
|
-
value.to_part(boundary, key)
|
72
|
-
else
|
73
|
-
Faraday::Parts::Part.new(boundary, key, value)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# @return [String]
|
78
|
-
def unique_boundary
|
79
|
-
"#{DEFAULT_BOUNDARY_PREFIX}-#{SecureRandom.hex}"
|
80
|
-
end
|
81
|
-
|
82
|
-
# @param params [Hash]
|
83
|
-
# @param prefix [String]
|
84
|
-
# @param pieces [Array]
|
85
|
-
def process_params(params, prefix = nil, pieces = nil, &block)
|
86
|
-
params.inject(pieces || []) do |all, (key, value)|
|
87
|
-
if prefix
|
88
|
-
key = @options[:flat_encode] ? prefix.to_s : "#{prefix}[#{key}]"
|
89
|
-
end
|
90
|
-
|
91
|
-
case value
|
92
|
-
when Array
|
93
|
-
values = value.inject([]) { |a, v| a << [nil, v] }
|
94
|
-
process_params(values, key, all, &block)
|
95
|
-
when Hash
|
96
|
-
process_params(value, key, all, &block)
|
97
|
-
else
|
98
|
-
# rubocop:disable Performance/RedundantBlockCall
|
99
|
-
all << block.call(key, value)
|
100
|
-
# rubocop:enable Performance/RedundantBlockCall
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|