multipart-post 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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