faraday 2.0.0.alpha.pre.4 → 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 +4 -4
- data/examples/client_spec.rb +1 -1
- data/examples/client_test.rb +1 -1
- data/lib/faraday/connection.rb +1 -1
- data/lib/faraday/error.rb +2 -8
- data/lib/faraday/rack_builder.rb +21 -18
- data/lib/faraday/request.rb +0 -2
- data/lib/faraday/version.rb +1 -1
- data/lib/faraday.rb +0 -3
- data/spec/faraday/connection_spec.rb +3 -0
- data/spec/faraday/rack_builder_spec.rb +2 -7
- data/spec/faraday/request/url_encoded_spec.rb +0 -1
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +0 -1
- data/spec/support/shared_examples/request_method.rb +0 -13
- metadata +5 -32
- data/lib/faraday/file_part.rb +0 -122
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/multipart.rb +0 -108
- data/lib/faraday/request/retry.rb +0 -241
- data/spec/faraday/composite_read_io_spec.rb +0 -80
- data/spec/faraday/request/multipart_spec.rb +0 -302
- data/spec/faraday/request/retry_spec.rb +0 -254
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 367d509be94da297eac6ece76f5561772218a5982696eba047ef8599d0ff05e1
|
4
|
+
data.tar.gz: 779c66227b778b17661428c17ab65567e23f13ea2824b92251eba67cd32c6280
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73d405ce87ac4a0917806b16ab11693b68966334656689a95bc06764501c44965832b08fa7bf36beeb71c2144a6661775df4f22b18e8281f664a0605fc2ece49
|
7
|
+
data.tar.gz: 22701db3eb1bb1668aaf6429e711acad05099577b39ccc792d32c42a82043f628483973a993c5ce91acd4207a9f0a01f47a51d6bffc4212047e4150fbb63e1e1
|
data/examples/client_spec.rb
CHANGED
data/examples/client_test.rb
CHANGED
data/lib/faraday/connection.rb
CHANGED
@@ -117,7 +117,7 @@ module Faraday
|
|
117
117
|
|
118
118
|
extend Forwardable
|
119
119
|
|
120
|
-
def_delegators :builder, :
|
120
|
+
def_delegators :builder, :use, :request, :response, :adapter, :app
|
121
121
|
|
122
122
|
# Closes the underlying resources and/or connections. In the case of
|
123
123
|
# persistent connections, this closes all currently open connections
|
data/lib/faraday/error.rb
CHANGED
@@ -6,7 +6,7 @@ module Faraday
|
|
6
6
|
class Error < StandardError
|
7
7
|
attr_reader :response, :wrapped_exception
|
8
8
|
|
9
|
-
def initialize(exc, response = nil)
|
9
|
+
def initialize(exc = nil, response = nil)
|
10
10
|
@wrapped_exception = nil unless defined?(@wrapped_exception)
|
11
11
|
@response = nil unless defined?(@response)
|
12
12
|
super(exc_msg_and_response!(exc, response))
|
@@ -141,13 +141,7 @@ module Faraday
|
|
141
141
|
class SSLError < Error
|
142
142
|
end
|
143
143
|
|
144
|
-
# Raised by
|
144
|
+
# Raised by middlewares that parse the response, like the JSON response middleware.
|
145
145
|
class ParsingError < Error
|
146
146
|
end
|
147
|
-
|
148
|
-
# Exception used to control the Retry middleware.
|
149
|
-
#
|
150
|
-
# @see Faraday::Request::Retry
|
151
|
-
class RetriableResponse < Error
|
152
|
-
end
|
153
147
|
end
|
data/lib/faraday/rack_builder.rb
CHANGED
@@ -58,22 +58,21 @@ module Faraday
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
def initialize(
|
62
|
-
@adapter =
|
63
|
-
@handlers =
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
61
|
+
def initialize(&block)
|
62
|
+
@adapter = nil
|
63
|
+
@handlers = []
|
64
|
+
build(&block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def initialize_dup(original)
|
68
|
+
super
|
69
|
+
@adapter = original.adapter
|
70
|
+
@handlers = original.handlers.dup
|
71
71
|
end
|
72
72
|
|
73
|
-
def build
|
73
|
+
def build
|
74
74
|
raise_if_locked
|
75
|
-
|
76
|
-
yield(self) if block_given?
|
75
|
+
block_given? ? yield(self) : request(:url_encoded)
|
77
76
|
adapter(Faraday.default_adapter) unless @adapter
|
78
77
|
end
|
79
78
|
|
@@ -109,7 +108,7 @@ module Faraday
|
|
109
108
|
end
|
110
109
|
|
111
110
|
ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block)
|
112
|
-
return @adapter if klass == NO_ARGUMENT
|
111
|
+
return @adapter if klass == NO_ARGUMENT || klass.nil?
|
113
112
|
|
114
113
|
klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol)
|
115
114
|
@adapter = self.class::Handler.new(klass, *args, &block)
|
@@ -164,6 +163,7 @@ module Faraday
|
|
164
163
|
def app
|
165
164
|
@app ||= begin
|
166
165
|
lock!
|
166
|
+
ensure_adapter!
|
167
167
|
to_app
|
168
168
|
end
|
169
169
|
end
|
@@ -182,10 +182,6 @@ module Faraday
|
|
182
182
|
@adapter == other.adapter
|
183
183
|
end
|
184
184
|
|
185
|
-
def dup
|
186
|
-
self.class.new(@handlers.dup, @adapter.dup)
|
187
|
-
end
|
188
|
-
|
189
185
|
# ENV Keys
|
190
186
|
# :http_method - a symbolized request HTTP method (:get, :post)
|
191
187
|
# :body - the request body that will eventually be converted to a string.
|
@@ -216,6 +212,9 @@ module Faraday
|
|
216
212
|
private
|
217
213
|
|
218
214
|
LOCK_ERR = "can't modify middleware stack after making a request"
|
215
|
+
MISSING_ADAPTER_ERROR = "An attempt to run a request with a Faraday::Connection without adapter has been made.\n" \
|
216
|
+
"Please set Faraday.default_adapter or provide one when initializing the connection.\n" \
|
217
|
+
'For more info, check https://lostisland.github.io/faraday/usage/.'
|
219
218
|
|
220
219
|
def raise_if_locked
|
221
220
|
raise StackLocked, LOCK_ERR if locked?
|
@@ -227,6 +226,10 @@ module Faraday
|
|
227
226
|
raise 'Adapter should be set using the `adapter` method, not `use`'
|
228
227
|
end
|
229
228
|
|
229
|
+
def ensure_adapter!
|
230
|
+
raise MISSING_ADAPTER_ERROR unless @adapter
|
231
|
+
end
|
232
|
+
|
230
233
|
def adapter_set?
|
231
234
|
!@adapter.nil?
|
232
235
|
end
|
data/lib/faraday/request.rb
CHANGED
data/lib/faraday/version.rb
CHANGED
data/lib/faraday.rb
CHANGED
@@ -17,8 +17,6 @@ require 'faraday/middleware'
|
|
17
17
|
require 'faraday/adapter'
|
18
18
|
require 'faraday/request'
|
19
19
|
require 'faraday/response'
|
20
|
-
require 'faraday/file_part'
|
21
|
-
require 'faraday/param_part'
|
22
20
|
|
23
21
|
# This is the main namespace for Faraday.
|
24
22
|
#
|
@@ -150,5 +148,4 @@ module Faraday
|
|
150
148
|
self.ignore_env_proxy = false
|
151
149
|
self.root_path = File.expand_path __dir__
|
152
150
|
self.lib_path = File.expand_path 'faraday', __dir__
|
153
|
-
self.default_adapter = :test
|
154
151
|
end
|
@@ -151,6 +151,9 @@ RSpec.describe Faraday::Connection do
|
|
151
151
|
end
|
152
152
|
|
153
153
|
describe '#close' do
|
154
|
+
before { Faraday.default_adapter = :test }
|
155
|
+
after { Faraday.default_adapter = nil }
|
156
|
+
|
154
157
|
it 'can close underlying app' do
|
155
158
|
expect(conn.app).to receive(:close)
|
156
159
|
conn.close
|
@@ -20,6 +20,8 @@ RSpec.describe Faraday::RackBuilder do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
subject { conn.builder }
|
23
|
+
before { Faraday.default_adapter = :test }
|
24
|
+
after { Faraday.default_adapter = nil }
|
23
25
|
|
24
26
|
context 'with default stack' do
|
25
27
|
let(:conn) { Faraday::Connection.new }
|
@@ -86,13 +88,6 @@ RSpec.describe Faraday::RackBuilder do
|
|
86
88
|
|
87
89
|
it { expect(subject.handlers).to eq([Apple]) }
|
88
90
|
|
89
|
-
it 'allows rebuilding' do
|
90
|
-
subject.build do |builder|
|
91
|
-
builder.use(Orange)
|
92
|
-
end
|
93
|
-
expect(subject.handlers).to eq([Orange])
|
94
|
-
end
|
95
|
-
|
96
91
|
it 'allows use' do
|
97
92
|
subject.use(Orange)
|
98
93
|
expect(subject.handlers).to eq([Apple, Orange])
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'multipart_parser/reader'
|
4
|
-
|
5
3
|
module Faraday
|
6
4
|
module HelperMethods
|
7
5
|
def self.included(base)
|
@@ -86,41 +84,6 @@ module Faraday
|
|
86
84
|
end
|
87
85
|
end
|
88
86
|
|
89
|
-
def multipart_file
|
90
|
-
Faraday::FilePart.new(__FILE__, 'text/x-ruby')
|
91
|
-
end
|
92
|
-
|
93
|
-
# parse boundary out of a Content-Type header like:
|
94
|
-
# Content-Type: multipart/form-data; boundary=gc0p4Jq0M2Yt08jU534c0p
|
95
|
-
def parse_multipart_boundary(ctype)
|
96
|
-
MultipartParser::Reader.extract_boundary_value(ctype)
|
97
|
-
end
|
98
|
-
|
99
|
-
# parse a multipart MIME message, returning a hash of any multipart errors
|
100
|
-
def parse_multipart(boundary, body)
|
101
|
-
reader = MultipartParser::Reader.new(boundary)
|
102
|
-
result = { errors: [], parts: [] }
|
103
|
-
def result.part(name)
|
104
|
-
hash = self[:parts].detect { |h| h[:part].name == name }
|
105
|
-
[hash[:part], hash[:body].join]
|
106
|
-
end
|
107
|
-
|
108
|
-
reader.on_part do |part|
|
109
|
-
result[:parts] << thispart = {
|
110
|
-
part: part,
|
111
|
-
body: []
|
112
|
-
}
|
113
|
-
part.on_data do |chunk|
|
114
|
-
thispart[:body] << chunk
|
115
|
-
end
|
116
|
-
end
|
117
|
-
reader.on_error do |msg|
|
118
|
-
result[:errors] << msg
|
119
|
-
end
|
120
|
-
reader.write(body)
|
121
|
-
result
|
122
|
-
end
|
123
|
-
|
124
87
|
def method_with_body?(method)
|
125
88
|
self.class.method_with_body?(method)
|
126
89
|
end
|
@@ -40,7 +40,6 @@ shared_examples 'adapter examples' do |**options|
|
|
40
40
|
conn_options[:ssl][:ca_file] ||= ENV['SSL_FILE']
|
41
41
|
|
42
42
|
Faraday.new(remote, conn_options) do |conn|
|
43
|
-
conn.request :multipart
|
44
43
|
conn.request :url_encoded
|
45
44
|
conn.response :raise_error
|
46
45
|
conn.adapter described_class, *adapter_options
|
@@ -126,19 +126,6 @@ shared_examples 'a request method' do |http_method|
|
|
126
126
|
expect { conn.public_send(http_method, '/') }.to raise_error(exc)
|
127
127
|
end
|
128
128
|
|
129
|
-
# Can't send files on get, head and delete methods
|
130
|
-
if method_with_body?(http_method)
|
131
|
-
it 'sends files' do
|
132
|
-
payload = { uploaded_file: multipart_file }
|
133
|
-
request_stub.with(headers: { 'Content-Type' => %r{\Amultipart/form-data} }) do |request|
|
134
|
-
# WebMock does not support matching body for multipart/form-data requests yet :(
|
135
|
-
# https://github.com/bblimke/webmock/issues/623
|
136
|
-
request.body.include?('RubyMultipartPost')
|
137
|
-
end
|
138
|
-
conn.public_send(http_method, '/', payload)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
129
|
on_feature :reason_phrase_parse do
|
143
130
|
it 'parses the reason phrase' do
|
144
131
|
request_stub.to_return(status: [200, 'OK'])
|
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: 2.0.0
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "@technoweenie"
|
@@ -10,28 +10,8 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2022-01-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: multipart-post
|
17
|
-
requirement: !ruby/object:Gem::Requirement
|
18
|
-
requirements:
|
19
|
-
- - ">="
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '1.2'
|
22
|
-
- - "<"
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: '3'
|
25
|
-
type: :runtime
|
26
|
-
prerelease: false
|
27
|
-
version_requirements: !ruby/object:Gem::Requirement
|
28
|
-
requirements:
|
29
|
-
- - ">="
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version: '1.2'
|
32
|
-
- - "<"
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version: '3'
|
35
15
|
- !ruby/object:Gem::Dependency
|
36
16
|
name: ruby2_keywords
|
37
17
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +46,6 @@ files:
|
|
66
46
|
- lib/faraday/encoders/flat_params_encoder.rb
|
67
47
|
- lib/faraday/encoders/nested_params_encoder.rb
|
68
48
|
- lib/faraday/error.rb
|
69
|
-
- lib/faraday/file_part.rb
|
70
49
|
- lib/faraday/logging/formatter.rb
|
71
50
|
- lib/faraday/methods.rb
|
72
51
|
- lib/faraday/middleware.rb
|
@@ -77,15 +56,12 @@ files:
|
|
77
56
|
- lib/faraday/options/proxy_options.rb
|
78
57
|
- lib/faraday/options/request_options.rb
|
79
58
|
- lib/faraday/options/ssl_options.rb
|
80
|
-
- lib/faraday/param_part.rb
|
81
59
|
- lib/faraday/parameters.rb
|
82
60
|
- lib/faraday/rack_builder.rb
|
83
61
|
- lib/faraday/request.rb
|
84
62
|
- lib/faraday/request/authorization.rb
|
85
63
|
- lib/faraday/request/instrumentation.rb
|
86
64
|
- lib/faraday/request/json.rb
|
87
|
-
- lib/faraday/request/multipart.rb
|
88
|
-
- lib/faraday/request/retry.rb
|
89
65
|
- lib/faraday/request/url_encoded.rb
|
90
66
|
- lib/faraday/response.rb
|
91
67
|
- lib/faraday/response/json.rb
|
@@ -99,7 +75,6 @@ files:
|
|
99
75
|
- spec/faraday/adapter/test_spec.rb
|
100
76
|
- spec/faraday/adapter_registry_spec.rb
|
101
77
|
- spec/faraday/adapter_spec.rb
|
102
|
-
- spec/faraday/composite_read_io_spec.rb
|
103
78
|
- spec/faraday/connection_spec.rb
|
104
79
|
- spec/faraday/error_spec.rb
|
105
80
|
- spec/faraday/middleware_spec.rb
|
@@ -113,8 +88,6 @@ files:
|
|
113
88
|
- spec/faraday/request/authorization_spec.rb
|
114
89
|
- spec/faraday/request/instrumentation_spec.rb
|
115
90
|
- spec/faraday/request/json_spec.rb
|
116
|
-
- spec/faraday/request/multipart_spec.rb
|
117
|
-
- spec/faraday/request/retry_spec.rb
|
118
91
|
- spec/faraday/request/url_encoded_spec.rb
|
119
92
|
- spec/faraday/request_spec.rb
|
120
93
|
- spec/faraday/response/json_spec.rb
|
@@ -137,7 +110,7 @@ licenses:
|
|
137
110
|
- MIT
|
138
111
|
metadata:
|
139
112
|
homepage_uri: https://lostisland.github.io/faraday
|
140
|
-
changelog_uri: https://github.com/lostisland/faraday/releases/tag/v2.0.0
|
113
|
+
changelog_uri: https://github.com/lostisland/faraday/releases/tag/v2.0.0
|
141
114
|
source_code_uri: https://github.com/lostisland/faraday
|
142
115
|
bug_tracker_uri: https://github.com/lostisland/faraday/issues
|
143
116
|
post_install_message:
|
@@ -152,9 +125,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
125
|
version: '2.6'
|
153
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
127
|
requirements:
|
155
|
-
- - "
|
128
|
+
- - ">="
|
156
129
|
- !ruby/object:Gem::Version
|
157
|
-
version:
|
130
|
+
version: '0'
|
158
131
|
requirements: []
|
159
132
|
rubygems_version: 3.1.6
|
160
133
|
signing_key:
|
data/lib/faraday/file_part.rb
DELETED
@@ -1,122 +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
|
-
Parts = ::Parts
|
56
|
-
|
57
|
-
# Similar to, but not compatible with CompositeReadIO provided by the
|
58
|
-
# multipart-post gem.
|
59
|
-
# https://github.com/nicksieger/multipart-post/blob/master/lib/composite_io.rb
|
60
|
-
class CompositeReadIO
|
61
|
-
def initialize(*parts)
|
62
|
-
@parts = parts.flatten
|
63
|
-
@ios = @parts.map(&:to_io)
|
64
|
-
@index = 0
|
65
|
-
end
|
66
|
-
|
67
|
-
# @return [Integer] sum of the lengths of all the parts
|
68
|
-
def length
|
69
|
-
@parts.inject(0) { |sum, part| sum + part.length }
|
70
|
-
end
|
71
|
-
|
72
|
-
# Rewind each of the IOs and reset the index to 0.
|
73
|
-
#
|
74
|
-
# @return [void]
|
75
|
-
def rewind
|
76
|
-
@ios.each(&:rewind)
|
77
|
-
@index = 0
|
78
|
-
end
|
79
|
-
|
80
|
-
# Read from IOs in order until `length` bytes have been received.
|
81
|
-
#
|
82
|
-
# @param length [Integer, nil]
|
83
|
-
# @param outbuf [String, nil]
|
84
|
-
def read(length = nil, outbuf = nil)
|
85
|
-
got_result = false
|
86
|
-
outbuf = outbuf ? (+outbuf).replace('') : +''
|
87
|
-
|
88
|
-
while (io = current_io)
|
89
|
-
if (result = io.read(length))
|
90
|
-
got_result ||= !result.nil?
|
91
|
-
result.force_encoding('BINARY') if result.respond_to?(:force_encoding)
|
92
|
-
outbuf << result
|
93
|
-
length -= result.length if length
|
94
|
-
break if length&.zero?
|
95
|
-
end
|
96
|
-
advance_io
|
97
|
-
end
|
98
|
-
!got_result && length ? nil : outbuf
|
99
|
-
end
|
100
|
-
|
101
|
-
# Close each of the IOs.
|
102
|
-
#
|
103
|
-
# @return [void]
|
104
|
-
def close
|
105
|
-
@ios.each(&:close)
|
106
|
-
end
|
107
|
-
|
108
|
-
def ensure_open_and_readable
|
109
|
-
# Rubinius compatibility
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
|
114
|
-
def current_io
|
115
|
-
@ios[@index]
|
116
|
-
end
|
117
|
-
|
118
|
-
def advance_io
|
119
|
-
@index += 1
|
120
|
-
end
|
121
|
-
end
|
122
|
-
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,108 +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
|
107
|
-
|
108
|
-
Faraday::Request.register_middleware(multipart: Faraday::Request::Multipart)
|