multipart-post 2.1.1 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e64b8bb7510028e6d5c5ca9626ff5448a12ee4e393938a69edd9eddfedf04e70
4
- data.tar.gz: dddcaa65fa823b59d0d3a025c8ad1e88eae0e2fe976469c9b69931a0bc66af6a
3
+ metadata.gz: 57b52690943221aed433f2b02d12e12a9fe30bff041eb36d01cfcf09acf11192
4
+ data.tar.gz: e5d437b405dee85af158f745bf5752f9ea74844bb4d25a091d4d8aaefc908078
5
5
  SHA512:
6
- metadata.gz: a046600778502bf34933ca1f4b2abd7ce0c7e8b4911ab9abc2bc74316cd42ce2f9167c6a40254ffb290ede586de81500a03500c09bfcb15ed96c0495bed19964
7
- data.tar.gz: 422aa7086f923b29e545cba81cd1caca270ed4e86f0d29a50a8c61bc111ad30d546b353ef3db5eb52f63f697d03a5671e759f3119c8c200807184c9cfe3c1f58
6
+ metadata.gz: e84ee4db9339b8f243971eecad41763e1fe953465ffde9f922d8c2e8c3245893a966cdaf34c18c95e709c851551fca001f19755ddf31fde36338a6f2ef2f33ce
7
+ data.tar.gz: b597a3c6c94bfe59974bc16ac5183f009ce5a10bb95a32baf1853338dd015603085a421e605fa39ef34de61e1ed58c9f21fadfe20e5debd057117f4a164eb2b5
checksums.yaml.gz.sig ADDED
Binary file
data/lib/composite_io.rb CHANGED
@@ -1,108 +1,2 @@
1
- #--
2
- # Copyright (c) 2007-2012 Nick Sieger.
3
- # See the file README.txt included with the distribution for
4
- # software license details.
5
- #++
6
-
7
- # Concatenate together multiple IO objects into a single, composite IO object
8
- # for purposes of reading as a single stream.
9
- #
10
- # @example
11
- # crio = CompositeReadIO.new(StringIO.new('one'),
12
- # StringIO.new('two'),
13
- # StringIO.new('three'))
14
- # puts crio.read # => "onetwothree"
15
- class CompositeReadIO
16
- # Create a new composite-read IO from the arguments, all of which should
17
- # respond to #read in a manner consistent with IO.
18
- def initialize(*ios)
19
- @ios = ios.flatten
20
- @index = 0
21
- end
22
-
23
- # Read from IOs in order until `length` bytes have been received.
24
- def read(length = nil, outbuf = nil)
25
- got_result = false
26
- outbuf = outbuf ? outbuf.replace("") : ""
27
-
28
- while io = current_io
29
- if result = io.read(length)
30
- got_result ||= !result.nil?
31
- result.force_encoding("BINARY") if result.respond_to?(:force_encoding)
32
- outbuf << result
33
- length -= result.length if length
34
- break if length == 0
35
- end
36
- advance_io
37
- end
38
- (!got_result && length) ? nil : outbuf
39
- end
40
-
41
- def rewind
42
- @ios.each { |io| io.rewind }
43
- @index = 0
44
- end
45
-
46
- private
47
-
48
- def current_io
49
- @ios[@index]
50
- end
51
-
52
- def advance_io
53
- @index += 1
54
- end
55
- end
56
-
57
- # Convenience methods for dealing with files and IO that are to be uploaded.
58
- class UploadIO
59
- attr_reader :content_type, :original_filename, :local_path, :io, :opts
60
-
61
- # Create an upload IO suitable for including in the params hash of a
62
- # Net::HTTP::Post::Multipart.
63
- #
64
- # Can take two forms. The first accepts a filename and content type, and
65
- # opens the file for reading (to be closed by finalizer).
66
- #
67
- # The second accepts an already-open IO, but also requires a third argument,
68
- # the filename from which it was opened (particularly useful/recommended if
69
- # uploading directly from a form in a framework, which often save the file to
70
- # an arbitrarily named RackMultipart file in /tmp).
71
- #
72
- # @example
73
- # UploadIO.new("file.txt", "text/plain")
74
- # UploadIO.new(file_io, "text/plain", "file.txt")
75
- def initialize(filename_or_io, content_type, filename = nil, opts = {})
76
- io = filename_or_io
77
- local_path = ""
78
- if io.respond_to? :read
79
- # in Ruby 1.9.2, StringIOs no longer respond to path
80
- # (since they respond to :length, so we don't need their local path, see parts.rb:41)
81
- local_path = filename_or_io.respond_to?(:path) ? filename_or_io.path : "local.path"
82
- else
83
- io = File.open(filename_or_io)
84
- local_path = filename_or_io
85
- end
86
- filename ||= local_path
87
-
88
- @content_type = content_type
89
- @original_filename = File.basename(filename)
90
- @local_path = local_path
91
- @io = io
92
- @opts = opts
93
- end
94
-
95
- def self.convert!(io, content_type, original_filename, local_path)
96
- raise ArgumentError, "convert! has been removed. You must now wrap IOs " \
97
- "using:\nUploadIO.new(filename_or_io, content_type, " \
98
- "filename=nil)\nPlease update your code."
99
- end
100
-
101
- def method_missing(*args)
102
- @io.send(*args)
103
- end
104
-
105
- def respond_to?(meth, include_all = false)
106
- @io.respond_to?(meth, include_all) || super(meth, include_all)
107
- end
108
- end
1
+ warn "Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!"
2
+ require_relative 'multipart/post'
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2007-2013, by Nick Sieger.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Multipart
24
+ module Post
25
+ # Concatenate together multiple IO objects into a single, composite IO object
26
+ # for purposes of reading as a single stream.
27
+ #
28
+ # @example
29
+ # crio = CompositeReadIO.new(StringIO.new('one'),
30
+ # StringIO.new('two'),
31
+ # StringIO.new('three'))
32
+ # puts crio.read # => "onetwothree"
33
+ class CompositeReadIO
34
+ # Create a new composite-read IO from the arguments, all of which should
35
+ # respond to #read in a manner consistent with IO.
36
+ def initialize(*ios)
37
+ @ios = ios.flatten
38
+ @index = 0
39
+ end
40
+
41
+ # Read from IOs in order until `length` bytes have been received.
42
+ def read(length = nil, outbuf = nil)
43
+ got_result = false
44
+ outbuf = outbuf ? outbuf.replace("") : String.new
45
+
46
+ while io = current_io
47
+ if result = io.read(length)
48
+ got_result ||= !result.nil?
49
+ result.force_encoding("BINARY") if result.respond_to?(:force_encoding)
50
+ outbuf << result
51
+ length -= result.length if length
52
+ break if length == 0
53
+ end
54
+ advance_io
55
+ end
56
+ (!got_result && length) ? nil : outbuf
57
+ end
58
+
59
+ def rewind
60
+ @ios.each { |io| io.rewind }
61
+ @index = 0
62
+ end
63
+
64
+ private
65
+
66
+ def current_io
67
+ @ios[@index]
68
+ end
69
+
70
+ def advance_io
71
+ @index += 1
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ CompositeIO = Multipart::Post::CompositeReadIO
78
+ Object.deprecate_constant :CompositeIO
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2007-2013, by Nick Sieger.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'parts'
24
+ require_relative 'composite_read_io'
25
+
26
+ require 'securerandom'
27
+
28
+ module Multipart
29
+ module Post
30
+ module Multipartable
31
+ def self.secure_boundary
32
+ # https://tools.ietf.org/html/rfc7230
33
+ # tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
34
+ # / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
35
+ # / DIGIT / ALPHA
36
+
37
+ # https://tools.ietf.org/html/rfc2046
38
+ # bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
39
+ # "+" / "_" / "," / "-" / "." /
40
+ # "/" / ":" / "=" / "?"
41
+
42
+ "--#{SecureRandom.uuid}"
43
+ end
44
+
45
+ def initialize(path, params, headers={}, boundary = Multipartable.secure_boundary)
46
+ headers = headers.clone # don't want to modify the original variable
47
+ parts_headers = headers.delete(:parts) || {}
48
+ parts_headers.transform_keys!(&:to_sym)
49
+
50
+ super(path, headers)
51
+ parts = params.transform_keys(&:to_sym).map do |k,v|
52
+ case v
53
+ when Array
54
+ v.map {|item| Parts::Part.new(boundary, k, item, parts_headers[k]) }
55
+ else
56
+ Parts::Part.new(boundary, k, v, parts_headers[k])
57
+ end
58
+ end.flatten
59
+ parts << Parts::EpiloguePart.new(boundary)
60
+ ios = parts.map {|p| p.to_io }
61
+ self.set_content_type(headers["Content-Type"] || "multipart/form-data",
62
+ { "boundary" => boundary })
63
+ self.content_length = parts.inject(0) {|sum,i| sum + i.length }
64
+ self.body_stream = CompositeReadIO.new(*ios)
65
+
66
+ @boundary = boundary
67
+ end
68
+
69
+ attr :boundary
70
+ end
71
+ end
72
+ end
73
+
74
+ Multipartable = Multipart::Post::Multipartable
75
+ Object.deprecate_constant :Multipartable
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2007-2013, by Nick Sieger.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'stringio'
24
+
25
+ module Multipart
26
+ module Post
27
+ module Parts
28
+ module Part
29
+ def self.new(boundary, name, value, headers = {})
30
+ headers ||= {} # avoid nil values
31
+ if file?(value)
32
+ FilePart.new(boundary, name, value, headers)
33
+ else
34
+ ParamPart.new(boundary, name, value, headers)
35
+ end
36
+ end
37
+
38
+ def self.file?(value)
39
+ value.respond_to?(:content_type) && value.respond_to?(:original_filename)
40
+ end
41
+
42
+ def length
43
+ @part.length
44
+ end
45
+
46
+ def to_io
47
+ @io
48
+ end
49
+ end
50
+
51
+ # Represents a parametric part to be filled with given value.
52
+ class ParamPart
53
+ include Part
54
+
55
+ # @param boundary [String]
56
+ # @param name [#to_s]
57
+ # @param value [String]
58
+ # @param headers [Hash] Content-Type and Content-ID are used, if present.
59
+ def initialize(boundary, name, value, headers = {})
60
+ @part = build_part(boundary, name, value, headers)
61
+ @io = StringIO.new(@part)
62
+ end
63
+
64
+ def length
65
+ @part.bytesize
66
+ end
67
+
68
+ # @param boundary [String]
69
+ # @param name [#to_s]
70
+ # @param value [String]
71
+ # @param headers [Hash] Content-Type is used, if present.
72
+ def build_part(boundary, name, value, headers = {})
73
+ part = String.new
74
+ part << "--#{boundary}\r\n"
75
+ part << "Content-ID: #{headers["Content-ID"]}\r\n" if headers["Content-ID"]
76
+ part << "Content-Disposition: form-data; name=\"#{name.to_s}\"\r\n"
77
+ part << "Content-Type: #{headers["Content-Type"]}\r\n" if headers["Content-Type"]
78
+ part << "\r\n"
79
+ part << "#{value}\r\n"
80
+ end
81
+ end
82
+
83
+ # Represents a part to be filled from file IO.
84
+ class FilePart
85
+ include Part
86
+
87
+ attr_reader :length
88
+
89
+ # @param boundary [String]
90
+ # @param name [#to_s]
91
+ # @param io [IO]
92
+ # @param headers [Hash]
93
+ def initialize(boundary, name, io, headers = {})
94
+ file_length = io.respond_to?(:length) ? io.length : File.size(io.local_path)
95
+ @head = build_head(boundary, name, io.original_filename, io.content_type, file_length,
96
+ io.respond_to?(:opts) ? io.opts.merge(headers) : headers)
97
+ @foot = "\r\n"
98
+ @length = @head.bytesize + file_length + @foot.length
99
+ @io = CompositeReadIO.new(StringIO.new(@head), io, StringIO.new(@foot))
100
+ end
101
+
102
+ # @param boundary [String]
103
+ # @param name [#to_s]
104
+ # @param filename [String]
105
+ # @param type [String]
106
+ # @param content_len [Integer]
107
+ # @param opts [Hash]
108
+ def build_head(boundary, name, filename, type, content_len, opts = {})
109
+ opts = opts.clone
110
+
111
+ trans_encoding = opts.delete("Content-Transfer-Encoding") || "binary"
112
+ content_disposition = opts.delete("Content-Disposition") || "form-data"
113
+
114
+ part = String.new
115
+ part << "--#{boundary}\r\n"
116
+ part << "Content-Disposition: #{content_disposition}; name=\"#{name.to_s}\"; filename=\"#{filename}\"\r\n"
117
+ part << "Content-Length: #{content_len}\r\n"
118
+ if content_id = opts.delete("Content-ID")
119
+ part << "Content-ID: #{content_id}\r\n"
120
+ end
121
+
122
+ if opts["Content-Type"] != nil
123
+ part << "Content-Type: " + opts["Content-Type"] + "\r\n"
124
+ else
125
+ part << "Content-Type: #{type}\r\n"
126
+ end
127
+
128
+ part << "Content-Transfer-Encoding: #{trans_encoding}\r\n"
129
+
130
+ opts.each do |k, v|
131
+ part << "#{k}: #{v}\r\n"
132
+ end
133
+
134
+ part << "\r\n"
135
+ end
136
+ end
137
+
138
+ # Represents the epilogue or closing boundary.
139
+ class EpiloguePart
140
+ include Part
141
+
142
+ def initialize(boundary)
143
+ @part = String.new("--#{boundary}--\r\n")
144
+ @io = StringIO.new(@part)
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+ Parts = Multipart::Post::Parts
152
+ Object.deprecate_constant :Parts
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2007-2013, by Nick Sieger.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Multipart
24
+ module Post
25
+ # Convenience methods for dealing with files and IO that are to be uploaded.
26
+ class UploadIO
27
+ attr_reader :content_type, :original_filename, :local_path, :io, :opts
28
+
29
+ # Create an upload IO suitable for including in the params hash of a
30
+ # Net::HTTP::Post::Multipart.
31
+ #
32
+ # Can take two forms. The first accepts a filename and content type, and
33
+ # opens the file for reading (to be closed by finalizer).
34
+ #
35
+ # The second accepts an already-open IO, but also requires a third argument,
36
+ # the filename from which it was opened (particularly useful/recommended if
37
+ # uploading directly from a form in a framework, which often save the file to
38
+ # an arbitrarily named RackMultipart file in /tmp).
39
+ #
40
+ # @example
41
+ # UploadIO.new("file.txt", "text/plain")
42
+ # UploadIO.new(file_io, "text/plain", "file.txt")
43
+ def initialize(filename_or_io, content_type, filename = nil, opts = {})
44
+ io = filename_or_io
45
+ local_path = ""
46
+ if io.respond_to? :read
47
+ # in Ruby 1.9.2, StringIOs no longer respond to path
48
+ # (since they respond to :length, so we don't need their local path, see parts.rb:41)
49
+ local_path = filename_or_io.respond_to?(:path) ? filename_or_io.path : "local.path"
50
+ else
51
+ io = File.open(filename_or_io)
52
+ local_path = filename_or_io
53
+ end
54
+ filename ||= local_path
55
+
56
+ @content_type = content_type
57
+ @original_filename = File.basename(filename)
58
+ @local_path = local_path
59
+ @io = io
60
+ @opts = opts
61
+ end
62
+
63
+ def self.convert!(io, content_type, original_filename, local_path)
64
+ raise ArgumentError, "convert! has been removed. You must now wrap IOs " \
65
+ "using:\nUploadIO.new(filename_or_io, content_type, " \
66
+ "filename=nil)\nPlease update your code."
67
+ end
68
+
69
+ def method_missing(*args)
70
+ @io.send(*args)
71
+ end
72
+
73
+ def respond_to?(meth, include_all = false)
74
+ @io.respond_to?(meth, include_all) || super(meth, include_all)
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ UploadIO = Multipart::Post::UploadIO
81
+ Object.deprecate_constant :UploadIO
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2007-2013, by Nick Sieger.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Multipart
24
+ module Post
25
+ VERSION = "2.2.0"
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2007-2013, by Nick Sieger.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'post/multipartable'
24
+ require_relative 'post/upload_io'
@@ -1,9 +1,3 @@
1
- #--
2
- # Copyright (c) 2007-2013 Nick Sieger.
3
- # See the file README.txt included with the distribution for
4
- # software license details.
5
- #++
6
-
7
- module MultipartPost
8
- VERSION = "2.1.1"
9
- end
1
+ warn "Top level ::MultipartPost is deprecated, require 'multipart/post' and use `Multipart::Post` instead!"
2
+ require_relative 'multipart/post'
3
+ MultipartPost = Multipart::Post
data/lib/multipartable.rb CHANGED
@@ -1,48 +1,2 @@
1
- #--
2
- # Copyright (c) 2007-2013 Nick Sieger.
3
- # See the file README.txt included with the distribution for
4
- # software license details.
5
- #++
6
-
7
- require 'parts'
8
- require 'securerandom'
9
-
10
- module Multipartable
11
- def self.secure_boundary
12
- # https://tools.ietf.org/html/rfc7230
13
- # tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
14
- # / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
15
- # / DIGIT / ALPHA
16
-
17
- # https://tools.ietf.org/html/rfc2046
18
- # bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
19
- # "+" / "_" / "," / "-" / "." /
20
- # "/" / ":" / "=" / "?"
21
-
22
- "--#{SecureRandom.uuid}"
23
- end
24
-
25
- def initialize(path, params, headers={}, boundary = Multipartable.secure_boundary)
26
- headers = headers.clone # don't want to modify the original variable
27
- parts_headers = headers.delete(:parts) || {}
28
- super(path, headers)
29
- parts = params.map do |k,v|
30
- case v
31
- when Array
32
- v.map {|item| Parts::Part.new(boundary, k, item, parts_headers[k]) }
33
- else
34
- Parts::Part.new(boundary, k, v, parts_headers[k])
35
- end
36
- end.flatten
37
- parts << Parts::EpiloguePart.new(boundary)
38
- ios = parts.map {|p| p.to_io }
39
- self.set_content_type(headers["Content-Type"] || "multipart/form-data",
40
- { "boundary" => boundary })
41
- self.content_length = parts.inject(0) {|sum,i| sum + i.length }
42
- self.body_stream = CompositeReadIO.new(*ios)
43
-
44
- @boundary = boundary
45
- end
46
-
47
- attr :boundary
48
- end
1
+ warn "Top level ::Multipartable is deprecated, require 'multipart/post' and use `Multipart::Post::Multipartable` instead!"
2
+ require_relative 'multipart/post'
@@ -1,27 +1,40 @@
1
- #--
2
- # Copyright (c) 2007-2012 Nick Sieger.
3
- # See the file README.txt included with the distribution for
4
- # software license details.
5
- #++
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2007-2013, by Nick Sieger.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
6
22
 
7
23
  require 'net/http'
8
- require 'stringio'
9
- require 'cgi'
10
- require 'composite_io'
11
- require 'multipartable'
12
- require 'parts'
24
+
25
+ require_relative '../../../multipart/post'
13
26
 
14
27
  module Net
15
28
  class HTTP
16
29
  class Put
17
30
  class Multipart < Put
18
- include Multipartable
31
+ include ::Multipart::Post::Multipartable
19
32
  end
20
33
  end
21
34
 
22
35
  class Post
23
36
  class Multipart < Post
24
- include Multipartable
37
+ include ::Multipart::Post::Multipartable
25
38
  end
26
39
  end
27
40
  end