multipart-post 2.0.0 → 2.1.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e64b8bb7510028e6d5c5ca9626ff5448a12ee4e393938a69edd9eddfedf04e70
4
+ data.tar.gz: dddcaa65fa823b59d0d3a025c8ad1e88eae0e2fe976469c9b69931a0bc66af6a
5
+ SHA512:
6
+ metadata.gz: a046600778502bf34933ca1f4b2abd7ce0c7e8b4911ab9abc2bc74316cd42ce2f9167c6a40254ffb290ede586de81500a03500c09bfcb15ed96c0495bed19964
7
+ data.tar.gz: 422aa7086f923b29e545cba81cd1caca270ed4e86f0d29a50a8c61bc111ad30d546b353ef3db5eb52f63f697d03a5671e759f3119c8c200807184c9cfe3c1f58
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --color
2
+ --format documentation
3
+ --backtrace
4
+ --require spec_helper
5
+ --warnings
@@ -1,7 +1,20 @@
1
+ language: ruby
2
+ cache: bundler
3
+
1
4
  rvm:
2
- - 1.9.3
3
- - 2.0.0
4
- - jruby
5
- branches:
6
- only:
7
- - master
5
+ - 2.0
6
+ - 2.1
7
+ - 2.2
8
+ - 2.3
9
+ - 2.4
10
+ - 2.5
11
+ - 2.6
12
+ - ruby-head
13
+ - jruby-head
14
+ - truffleruby
15
+
16
+ matrix:
17
+ allow_failures:
18
+ - rvm: ruby-head
19
+ - rvm: jruby-head
20
+ - rvm: truffleruby
@@ -0,0 +1,6 @@
1
+ --no-private
2
+ lib/**/*.rb
3
+ -
4
+ History.txt
5
+ LICENSE
6
+ README.md
data/Gemfile CHANGED
@@ -1,14 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
- platforms :mri_19 do
5
- gem 'ruby-debug19'
6
- end
7
-
8
- platforms :mri_18 do
9
- gem 'ruby-debug'
10
- end
11
-
12
4
  group :development, :test do
13
5
  gem 'rake'
14
6
  end
@@ -1,3 +1,8 @@
1
+ <!--
2
+ # @markup rdoc
3
+ # @title CHANGELOG
4
+ -->
5
+
1
6
  === 2.0.0 / 2013-12-21
2
7
 
3
8
  - Drop Ruby 1.8 compatibility
@@ -57,4 +62,3 @@
57
62
  * 1 major enhancement
58
63
 
59
64
  * Birthday!
60
-
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2007-2013 Nick Sieger nick@nicksieger.com
2
+ Copyright, 2017, by Samuel G. D. Williams.
3
+
4
+ MIT license.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ this software and associated documentation files (the "Software"), to deal in
8
+ the Software without restriction, including without limitation the rights to
9
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10
+ the Software, and to permit persons to whom the Software is furnished to do so,
11
+ subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,77 +1,127 @@
1
- ## multipart-post
1
+ # Multipart::Post
2
2
 
3
- * http://github.com/nicksieger/multipart-post
3
+ Adds a streamy multipart form post capability to `Net::HTTP`. Also supports other
4
+ methods besides `POST`.
4
5
 
5
- ![build status](https://travis-ci.org/nicksieger/multipart-post.png)
6
+ [![Build Status](https://secure.travis-ci.org/socketry/multipart-post.svg)](http://travis-ci.org/socketry/multipart-post)
6
7
 
7
- #### DESCRIPTION:
8
-
9
- Adds a streamy multipart form post capability to Net::HTTP. Also
10
- supports other methods besides POST.
11
-
12
- #### FEATURES/PROBLEMS:
8
+ ## Features/Problems
13
9
 
14
10
  * Appears to actually work. A good feature to have.
15
- * Encapsulates posting of file/binary parts and name/value parameter parts, similar to
11
+ * Encapsulates posting of file/binary parts and name/value parameter parts, similar to
16
12
  most browsers' file upload forms.
17
- * Provides an UploadIO helper class to prepare IO objects for inclusion in the params
13
+ * Provides an `UploadIO` helper class to prepare IO objects for inclusion in the params
18
14
  hash of the multipart post object.
19
15
 
20
- #### SYNOPSIS:
21
-
22
- require 'net/http/post/multipart'
23
-
24
- url = URI.parse('http://www.example.com/upload')
25
- File.open("./image.jpg") do |jpg|
26
- req = Net::HTTP::Post::Multipart.new url.path,
27
- "file" => UploadIO.new(jpg, "image/jpeg", "image.jpg")
28
- res = Net::HTTP.start(url.host, url.port) do |http|
29
- http.request(req)
30
- end
31
- end
32
-
33
- To post multiple files or attachments, simply include multiple parameters with
34
- UploadIO values:
35
-
36
- require 'net/http/post/multipart'
37
-
38
- url = URI.parse('http://www.example.com/upload')
39
- req = Net::HTTP::Post::Multipart.new url.path,
40
- "file1" => UploadIO.new(File.new("./image.jpg"), "image/jpeg", "image.jpg"),
41
- "file2" => UploadIO.new(File.new("./image2.jpg"), "image/jpeg", "image2.jpg")
42
- res = Net::HTTP.start(url.host, url.port) do |http|
43
- http.request(req)
44
- end
45
-
46
- #### REQUIREMENTS:
47
-
48
- None
49
-
50
- #### INSTALL:
16
+ ## Installation
51
17
 
52
18
  gem install multipart-post
53
19
 
54
- #### LICENSE:
20
+ or in your Gemfile
55
21
 
56
- (The MIT License)
22
+ gem 'multipart-post'
57
23
 
58
- Copyright (c) 2007-2013 Nick Sieger <nick@nicksieger.com>
24
+ ## Usage
59
25
 
60
- Permission is hereby granted, free of charge, to any person obtaining
61
- a copy of this software and associated documentation files (the
62
- 'Software'), to deal in the Software without restriction, including
63
- without limitation the rights to use, copy, modify, merge, publish,
64
- distribute, sublicense, and/or sell copies of the Software, and to
65
- permit persons to whom the Software is furnished to do so, subject to
66
- the following conditions:
26
+ ```ruby
27
+ require 'net/http/post/multipart'
67
28
 
68
- The above copyright notice and this permission notice shall be
69
- included in all copies or substantial portions of the Software.
29
+ url = URI.parse('http://www.example.com/upload')
30
+ File.open("./image.jpg") do |jpg|
31
+ req = Net::HTTP::Post::Multipart.new url.path,
32
+ "file" => UploadIO.new(jpg, "image/jpeg", "image.jpg")
33
+ res = Net::HTTP.start(url.host, url.port) do |http|
34
+ http.request(req)
35
+ end
36
+ end
37
+ ```
70
38
 
71
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
72
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
73
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
74
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
75
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
76
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
77
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39
+ To post multiple files or attachments, simply include multiple parameters with
40
+ `UploadIO` values:
41
+
42
+ ```ruby
43
+ require 'net/http/post/multipart'
44
+
45
+ url = URI.parse('http://www.example.com/upload')
46
+ req = Net::HTTP::Post::Multipart.new url.path,
47
+ "file1" => UploadIO.new(File.new("./image.jpg"), "image/jpeg", "image.jpg"),
48
+ "file2" => UploadIO.new(File.new("./image2.jpg"), "image/jpeg", "image2.jpg")
49
+ res = Net::HTTP.start(url.host, url.port) do |http|
50
+ http.request(req)
51
+ end
52
+ ```
53
+
54
+ To post files with other normal, non-file params such as input values, you need to pass hashes to the `Multipart.new` method.
55
+
56
+ In Rails 4 for example:
57
+
58
+ ```ruby
59
+ def model_params
60
+ require_params = params.require(:model).permit(:param_one, :param_two, :param_three, :avatar)
61
+ require_params[:avatar] = model_params[:avatar].present? ? UploadIO.new(model_params[:avatar].tempfile, model_params[:avatar].content_type, model_params[:avatar].original_filename) : nil
62
+ require_params
63
+ end
64
+
65
+ require 'net/http/post/multipart'
66
+
67
+ url = URI.parse('http://www.example.com/upload')
68
+ Net::HTTP.start(url.host, url.port) do |http|
69
+ req = Net::HTTP::Post::Multipart.new(url, model_params)
70
+ key = "authorization_key"
71
+ req.add_field("Authorization", key) #add to Headers
72
+ http.use_ssl = (url.scheme == "https")
73
+ http.request(req)
74
+ end
75
+ ```
76
+
77
+ Or in plain ruby:
78
+
79
+ ```ruby
80
+ def params(file)
81
+ params = { "description" => "A nice picture!" }
82
+ params[:datei] = UploadIO.new(file, "image/jpeg", "image.jpg")
83
+ params
84
+ end
85
+
86
+ url = URI.parse('http://www.example.com/upload')
87
+ File.open("./image.jpg") do |file|
88
+ req = Net::HTTP::Post::Multipart.new(url.path, params(file))
89
+ res = Net::HTTP.start(url.host, url.port) do |http|
90
+ return http.request(req).body
91
+ end
92
+ end
93
+ ```
94
+
95
+ ### Debugging
96
+
97
+ You can debug requests and responses (e.g. status codes) for all requests by adding the following code:
98
+
99
+ ```ruby
100
+ http = Net::HTTP.new(uri.host, uri.port)
101
+ http.set_debug_output($stdout)
102
+ ```
103
+
104
+ ## License
105
+
106
+ Released under the MIT license.
107
+
108
+ Copyright (c) 2007-2013 Nick Sieger <nick@nicksieger.com>
109
+ Copyright, 2017, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
110
+
111
+ Permission is hereby granted, free of charge, to any person obtaining a copy
112
+ of this software and associated documentation files (the "Software"), to deal
113
+ in the Software without restriction, including without limitation the rights
114
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
115
+ copies of the Software, and to permit persons to whom the Software is
116
+ furnished to do so, subject to the following conditions:
117
+
118
+ The above copyright notice and this permission notice shall be included in
119
+ all copies or substantial portions of the Software.
120
+
121
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
122
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
123
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
124
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
125
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
126
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
127
+ THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,9 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
2
3
 
3
- task :default => :test
4
+ RSpec::Core::RakeTask.new(:test)
4
5
 
5
- require 'rake/testtask'
6
- Rake::TestTask.new do |t|
7
- t.libs << "test"
8
- t.test_files = FileList['test/**/test*.rb']
9
- end
6
+ task :default => :test
@@ -7,11 +7,11 @@
7
7
  # Concatenate together multiple IO objects into a single, composite IO object
8
8
  # for purposes of reading as a single stream.
9
9
  #
10
- # Usage:
11
- #
12
- # crio = CompositeReadIO.new(StringIO.new('one'), StringIO.new('two'), StringIO.new('three'))
10
+ # @example
11
+ # crio = CompositeReadIO.new(StringIO.new('one'),
12
+ # StringIO.new('two'),
13
+ # StringIO.new('three'))
13
14
  # puts crio.read # => "onetwothree"
14
- #
15
15
  class CompositeReadIO
16
16
  # Create a new composite-read IO from the arguments, all of which should
17
17
  # respond to #read in a manner consistent with IO.
@@ -56,6 +56,8 @@ end
56
56
 
57
57
  # Convenience methods for dealing with files and IO that are to be uploaded.
58
58
  class UploadIO
59
+ attr_reader :content_type, :original_filename, :local_path, :io, :opts
60
+
59
61
  # Create an upload IO suitable for including in the params hash of a
60
62
  # Net::HTTP::Post::Multipart.
61
63
  #
@@ -67,13 +69,9 @@ class UploadIO
67
69
  # uploading directly from a form in a framework, which often save the file to
68
70
  # an arbitrarily named RackMultipart file in /tmp).
69
71
  #
70
- # Usage:
71
- #
72
+ # @example
72
73
  # UploadIO.new("file.txt", "text/plain")
73
74
  # UploadIO.new(file_io, "text/plain", "file.txt")
74
- #
75
- attr_reader :content_type, :original_filename, :local_path, :io, :opts
76
-
77
75
  def initialize(filename_or_io, content_type, filename = nil, opts = {})
78
76
  io = filename_or_io
79
77
  local_path = ""
@@ -95,7 +93,9 @@ class UploadIO
95
93
  end
96
94
 
97
95
  def self.convert!(io, content_type, original_filename, local_path)
98
- raise ArgumentError, "convert! has been removed. You must now wrap IOs using:\nUploadIO.new(filename_or_io, content_type, filename=nil)\nPlease update your code."
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
99
  end
100
100
 
101
101
  def method_missing(*args)
@@ -5,5 +5,5 @@
5
5
  #++
6
6
 
7
7
  module MultipartPost
8
- VERSION = "2.0.0"
8
+ VERSION = "2.1.1"
9
9
  end
@@ -5,25 +5,44 @@
5
5
  #++
6
6
 
7
7
  require 'parts'
8
- module Multipartable
9
- DEFAULT_BOUNDARY = "-----------RubyMultipartPost"
10
- def initialize(path, params, headers={}, boundary = DEFAULT_BOUNDARY)
11
- headers = headers.clone # don't want to modify the original variable
12
- parts_headers = headers.delete(:parts) || {}
13
- super(path, headers)
14
- parts = params.map do |k,v|
15
- case v
16
- when Array
17
- v.map {|item| Parts::Part.new(boundary, k, item, parts_headers[k]) }
18
- else
19
- Parts::Part.new(boundary, k, v, parts_headers[k])
20
- end
21
- end.flatten
22
- parts << Parts::EpiloguePart.new(boundary)
23
- ios = parts.map {|p| p.to_io }
24
- self.set_content_type(headers["Content-Type"] || "multipart/form-data",
25
- { "boundary" => boundary })
26
- self.content_length = parts.inject(0) {|sum,i| sum + i.length }
27
- self.body_stream = CompositeReadIO.new(*ios)
28
- end
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
29
45
  end
46
+
47
+ attr :boundary
48
+ end
@@ -11,14 +11,15 @@ require 'composite_io'
11
11
  require 'multipartable'
12
12
  require 'parts'
13
13
 
14
- module Net #:nodoc:
15
- class HTTP #:nodoc:
14
+ module Net
15
+ class HTTP
16
16
  class Put
17
17
  class Multipart < Put
18
18
  include Multipartable
19
19
  end
20
20
  end
21
- class Post #:nodoc:
21
+
22
+ class Post
22
23
  class Multipart < Post
23
24
  include Multipartable
24
25
  end