Hello community,
here is the log from the commit of package rubygem-multipart-post for
openSUSE:Factory checked in at 2019-08-06 15:10:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-multipart-post (Old)
and /work/SRC/openSUSE:Factory/.rubygem-multipart-post.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-multipart-post"
Tue Aug 6 15:10:06 2019 rev:9 rq:717311 version:2.1.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/rubygem-multipart-post/rubygem-multipart-post.changes
2014-10-24 10:48:33.000000000 +0200
+++
/work/SRC/openSUSE:Factory/.rubygem-multipart-post.new.4126/rubygem-multipart-post.changes
2019-08-06 15:10:08.535781731 +0200
@@ -1,0 +2,11 @@
+Fri Jul 19 09:24:08 UTC 2019 - Stephan Kulow <[email protected]>
+
+- updated to version 2.1.1
+ see installed History.txt
+
+ <!--
+ # @markup rdoc
+ # @title CHANGELOG
+ -->
+
+-------------------------------------------------------------------
Old:
----
multipart-post-2.0.0.gem
New:
----
gem2rpm.yml
multipart-post-2.1.1.gem
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ rubygem-multipart-post.spec ++++++
--- /var/tmp/diff_new_pack.iF6fUX/_old 2019-08-06 15:10:08.979781480 +0200
+++ /var/tmp/diff_new_pack.iF6fUX/_new 2019-08-06 15:10:08.979781480 +0200
@@ -1,7 +1,7 @@
#
# spec file for package rubygem-multipart-post
#
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -12,28 +12,35 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
+#
+# This file was generated with a gem2rpm.yml and not just plain gem2rpm.
+# All sections marked as MANUAL, license headers, summaries and descriptions
+# can be maintained in that file. Please consult this file before editing any
+# of those fields
+#
+
Name: rubygem-multipart-post
-Version: 2.0.0
+Version: 2.1.1
Release: 0
%define mod_name multipart-post
%define mod_full_name %{mod_name}-%{version}
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: %{rubygem gem2rpm}
-BuildRequires: %{rubygem rdoc > 3.10}
BuildRequires: %{ruby}
BuildRequires: ruby-macros >= 5
Url: https://github.com/nicksieger/multipart-post
-Source: http://rubygems.org/gems/%{mod_full_name}.gem
+Source: https://rubygems.org/gems/%{mod_full_name}.gem
+Source1: gem2rpm.yml
Summary: A multipart form post accessory for Net::HTTP
License: MIT
Group: Development/Languages/Ruby
%description
-Use with Net::HTTP to do multipart form posts. IO values that have
+Use with Net::HTTP to do multipart form postspec. IO values that have
#content_type, #original_filename, and #local_path will be posted as a binary
file.
@@ -43,7 +50,7 @@
%install
%gem_install \
- --doc-files="History.txt README.md" \
+ --doc-files="History.txt LICENSE README.md" \
-f
%gem_packages
++++++ gem2rpm.yml ++++++
# ---
# ## used by gem2rpm
# :summary: this is a custom summary
# ## used by gem2rpm
# :description: |-
# this is a custom description
#
# it can be multiline
# ## used by gem2rpm
# :license: MIT or Ruby
# ## used by gem2rpm and gem_packages
# :version_suffix: -x_y
# ## used by gem2rpm and gem_packages
# :disable_docs: true
# ## used by gem2rpm
# :disable_automatic_rdoc_dep: true
# ## used by gem2rpm
# :preamble: |-
# BuildRequires: foobar
# Requires: foobar
# ## used by gem2rpm
# :patches:
# foo.patch: -p1
# bar.patch:
# :post_patch:
# if you need to fiddle with the source dir before rebuilding the gem
# ## used by gem2rpm
:sources:
# - foo.desktop
# - bar.desktop
# :gem_install_args: '....'
# ## used by gem2rpm
# :pre_install: |-
# %if 0%{?use_system_libev}
# export USE_VENDORED_LIBEV="no"
# %endif
# ## used by gem2rpm
# :post_install: |-
# # delete custom files here or do other fancy stuff
# install -D -m 0644 %{S:1} %{buildroot}%{_bindir}/gem2rpm-opensuse
# ## used by gem2rpm
# :testsuite_command: |-
# (pushd %{buildroot}%{gem_base}/gems/%{mod_full_name} && rake test)
# ## used by gem2rpm
# :filelist: |-
# /usr/bin/gem2rpm-opensuse
# ## used by gem2rpm
# :scripts:
# :post: |-
# /bin/echo foo
# ## used by gem_packages
# :main:
# :preamble: |-
# Requires: util-linux
# Recommends: pwgen
# :filelist: |-
# /usr/bin/gem2rpm-opensuse
# ## used by gem_packages
# :custom_pkgs:
# apache:
# :preamble: |-
# Requires: .....
# :filelist: |-
# /etc/apache2/conf.d/passenger.conf
# :summary: Custom summary is optional
# :description: |-
# Custom description is optional
#
# bar
# :post: |-
# /bin/echo foo
# :preamble: |-
# %if 0%{?suse_version} && 0%{?suse_version} < 1330
# %define rb_build_versions ruby24 ruby25
# %define rb_default_ruby_abi ruby:2.4.0 ruby:2.5.0
# %endif
++++++ multipart-post-2.0.0.gem -> multipart-post-2.1.1.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/.rspec new/.rspec
--- old/.rspec 1970-01-01 01:00:00.000000000 +0100
+++ new/.rspec 2019-05-13 13:34:34.000000000 +0200
@@ -0,0 +1,5 @@
+--color
+--format documentation
+--backtrace
+--require spec_helper
+--warnings
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/.travis.yml new/.travis.yml
--- old/.travis.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/.travis.yml 2019-05-13 13:34:34.000000000 +0200
@@ -1,7 +1,20 @@
+language: ruby
+cache: bundler
+
rvm:
- - 1.9.3
- - 2.0.0
- - jruby
-branches:
- only:
- - master
+ - 2.0
+ - 2.1
+ - 2.2
+ - 2.3
+ - 2.4
+ - 2.5
+ - 2.6
+ - ruby-head
+ - jruby-head
+ - truffleruby
+
+matrix:
+ allow_failures:
+ - rvm: ruby-head
+ - rvm: jruby-head
+ - rvm: truffleruby
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/.yardopts new/.yardopts
--- old/.yardopts 1970-01-01 01:00:00.000000000 +0100
+++ new/.yardopts 2019-05-13 13:34:34.000000000 +0200
@@ -0,0 +1,6 @@
+--no-private
+lib/**/*.rb
+-
+History.txt
+LICENSE
+README.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Gemfile new/Gemfile
--- old/Gemfile 1970-01-01 01:00:00.000000000 +0100
+++ new/Gemfile 2019-05-13 13:34:34.000000000 +0200
@@ -1,14 +1,6 @@
source 'https://rubygems.org'
gemspec
-platforms :mri_19 do
- gem 'ruby-debug19'
-end
-
-platforms :mri_18 do
- gem 'ruby-debug'
-end
-
group :development, :test do
gem 'rake'
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/History.txt new/History.txt
--- old/History.txt 1970-01-01 01:00:00.000000000 +0100
+++ new/History.txt 2019-05-13 13:34:34.000000000 +0200
@@ -1,3 +1,8 @@
+<!--
+# @markup rdoc
+# @title CHANGELOG
+-->
+
=== 2.0.0 / 2013-12-21
- Drop Ruby 1.8 compatibility
@@ -57,4 +62,3 @@
* 1 major enhancement
* Birthday!
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/LICENSE new/LICENSE
--- old/LICENSE 1970-01-01 01:00:00.000000000 +0100
+++ new/LICENSE 2019-05-13 13:34:34.000000000 +0200
@@ -0,0 +1,21 @@
+Copyright (c) 2007-2013 Nick Sieger [email protected]
+Copyright, 2017, by Samuel G. D. Williams.
+
+MIT license.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md 1970-01-01 01:00:00.000000000 +0100
+++ new/README.md 2019-05-13 13:34:34.000000000 +0200
@@ -1,77 +1,127 @@
-## multipart-post
+# Multipart::Post
-* http://github.com/nicksieger/multipart-post
+Adds a streamy multipart form post capability to `Net::HTTP`. Also supports
other
+methods besides `POST`.
-
+[](http://travis-ci.org/socketry/multipart-post)
-#### DESCRIPTION:
-
-Adds a streamy multipart form post capability to Net::HTTP. Also
-supports other methods besides POST.
-
-#### FEATURES/PROBLEMS:
+## Features/Problems
* Appears to actually work. A good feature to have.
-* Encapsulates posting of file/binary parts and name/value parameter parts,
similar to
+* Encapsulates posting of file/binary parts and name/value parameter parts,
similar to
most browsers' file upload forms.
-* Provides an UploadIO helper class to prepare IO objects for inclusion in the
params
+* Provides an `UploadIO` helper class to prepare IO objects for inclusion in
the params
hash of the multipart post object.
-#### SYNOPSIS:
-
- require 'net/http/post/multipart'
-
- url = URI.parse('http://www.example.com/upload')
- File.open("./image.jpg") do |jpg|
- req = Net::HTTP::Post::Multipart.new url.path,
- "file" => UploadIO.new(jpg, "image/jpeg", "image.jpg")
- res = Net::HTTP.start(url.host, url.port) do |http|
- http.request(req)
- end
- end
-
-To post multiple files or attachments, simply include multiple parameters with
-UploadIO values:
+## Installation
- require 'net/http/post/multipart'
+ gem install multipart-post
- url = URI.parse('http://www.example.com/upload')
- req = Net::HTTP::Post::Multipart.new url.path,
- "file1" => UploadIO.new(File.new("./image.jpg"), "image/jpeg",
"image.jpg"),
- "file2" => UploadIO.new(File.new("./image2.jpg"), "image/jpeg",
"image2.jpg")
- res = Net::HTTP.start(url.host, url.port) do |http|
- http.request(req)
- end
+or in your Gemfile
-#### REQUIREMENTS:
+ gem 'multipart-post'
-None
+## Usage
-#### INSTALL:
+```ruby
+require 'net/http/post/multipart'
- gem install multipart-post
+url = URI.parse('http://www.example.com/upload')
+File.open("./image.jpg") do |jpg|
+ req = Net::HTTP::Post::Multipart.new url.path,
+ "file" => UploadIO.new(jpg, "image/jpeg", "image.jpg")
+ res = Net::HTTP.start(url.host, url.port) do |http|
+ http.request(req)
+ end
+end
+```
-#### LICENSE:
-
-(The MIT License)
+To post multiple files or attachments, simply include multiple parameters with
+`UploadIO` values:
-Copyright (c) 2007-2013 Nick Sieger <[email protected]>
+```ruby
+require 'net/http/post/multipart'
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+url = URI.parse('http://www.example.com/upload')
+req = Net::HTTP::Post::Multipart.new url.path,
+ "file1" => UploadIO.new(File.new("./image.jpg"), "image/jpeg", "image.jpg"),
+ "file2" => UploadIO.new(File.new("./image2.jpg"), "image/jpeg", "image2.jpg")
+res = Net::HTTP.start(url.host, url.port) do |http|
+ http.request(req)
+end
+```
+
+To post files with other normal, non-file params such as input values, you
need to pass hashes to the `Multipart.new` method.
+
+In Rails 4 for example:
+
+```ruby
+def model_params
+ require_params = params.require(:model).permit(:param_one, :param_two,
:param_three, :avatar)
+ require_params[:avatar] = model_params[:avatar].present? ?
UploadIO.new(model_params[:avatar].tempfile,
model_params[:avatar].content_type, model_params[:avatar].original_filename) :
nil
+ require_params
+end
+
+require 'net/http/post/multipart'
+
+url = URI.parse('http://www.example.com/upload')
+Net::HTTP.start(url.host, url.port) do |http|
+ req = Net::HTTP::Post::Multipart.new(url, model_params)
+ key = "authorization_key"
+ req.add_field("Authorization", key) #add to Headers
+ http.use_ssl = (url.scheme == "https")
+ http.request(req)
+end
+```
+
+Or in plain ruby:
+
+```ruby
+def params(file)
+ params = { "description" => "A nice picture!" }
+ params[:datei] = UploadIO.new(file, "image/jpeg", "image.jpg")
+ params
+end
+
+url = URI.parse('http://www.example.com/upload')
+File.open("./image.jpg") do |file|
+ req = Net::HTTP::Post::Multipart.new(url.path, params(file))
+ res = Net::HTTP.start(url.host, url.port) do |http|
+ return http.request(req).body
+ end
+end
+```
+
+### Debugging
+
+You can debug requests and responses (e.g. status codes) for all requests by
adding the following code:
+
+```ruby
+http = Net::HTTP.new(uri.host, uri.port)
+http.set_debug_output($stdout)
+```
+
+## License
+
+Released under the MIT license.
+
+Copyright (c) 2007-2013 Nick Sieger <[email protected]>
+Copyright, 2017, by [Samuel G. D.
Williams](http://www.codeotaku.com/samuel-williams).
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Rakefile new/Rakefile
--- old/Rakefile 1970-01-01 01:00:00.000000000 +0100
+++ new/Rakefile 2019-05-13 13:34:34.000000000 +0200
@@ -1,9 +1,6 @@
require "bundler/gem_tasks"
+require "rspec/core/rake_task"
-task :default => :test
+RSpec::Core::RakeTask.new(:test)
-require 'rake/testtask'
-Rake::TestTask.new do |t|
- t.libs << "test"
- t.test_files = FileList['test/**/test*.rb']
-end
+task :default => :test
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/composite_io.rb new/lib/composite_io.rb
--- old/lib/composite_io.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/composite_io.rb 2019-05-13 13:34:34.000000000 +0200
@@ -7,11 +7,11 @@
# Concatenate together multiple IO objects into a single, composite IO object
# for purposes of reading as a single stream.
#
-# Usage:
-#
-# crio = CompositeReadIO.new(StringIO.new('one'), StringIO.new('two'),
StringIO.new('three'))
+# @example
+# crio = CompositeReadIO.new(StringIO.new('one'),
+# StringIO.new('two'),
+# StringIO.new('three'))
# puts crio.read # => "onetwothree"
-#
class CompositeReadIO
# Create a new composite-read IO from the arguments, all of which should
# respond to #read in a manner consistent with IO.
@@ -56,6 +56,8 @@
# Convenience methods for dealing with files and IO that are to be uploaded.
class UploadIO
+ attr_reader :content_type, :original_filename, :local_path, :io, :opts
+
# Create an upload IO suitable for including in the params hash of a
# Net::HTTP::Post::Multipart.
#
@@ -67,13 +69,9 @@
# uploading directly from a form in a framework, which often save the file to
# an arbitrarily named RackMultipart file in /tmp).
#
- # Usage:
- #
+ # @example
# UploadIO.new("file.txt", "text/plain")
# UploadIO.new(file_io, "text/plain", "file.txt")
- #
- attr_reader :content_type, :original_filename, :local_path, :io, :opts
-
def initialize(filename_or_io, content_type, filename = nil, opts = {})
io = filename_or_io
local_path = ""
@@ -95,7 +93,9 @@
end
def self.convert!(io, content_type, original_filename, local_path)
- 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."
+ 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."
end
def method_missing(*args)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/multipart_post.rb new/lib/multipart_post.rb
--- old/lib/multipart_post.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/multipart_post.rb 2019-05-13 13:34:34.000000000 +0200
@@ -5,5 +5,5 @@
#++
module MultipartPost
- VERSION = "2.0.0"
+ VERSION = "2.1.1"
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/multipartable.rb new/lib/multipartable.rb
--- old/lib/multipartable.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/multipartable.rb 2019-05-13 13:34:34.000000000 +0200
@@ -5,25 +5,44 @@
#++
require 'parts'
- module Multipartable
- DEFAULT_BOUNDARY = "-----------RubyMultipartPost"
- def initialize(path, params, headers={}, boundary = DEFAULT_BOUNDARY)
- headers = headers.clone # don't want to modify the original variable
- parts_headers = headers.delete(:parts) || {}
- super(path, headers)
- parts = params.map do |k,v|
- case v
- when Array
- v.map {|item| Parts::Part.new(boundary, k, item, parts_headers[k]) }
- else
- Parts::Part.new(boundary, k, v, parts_headers[k])
- end
- end.flatten
- parts << Parts::EpiloguePart.new(boundary)
- ios = parts.map {|p| p.to_io }
- self.set_content_type(headers["Content-Type"] || "multipart/form-data",
- { "boundary" => boundary })
- self.content_length = parts.inject(0) {|sum,i| sum + i.length }
- self.body_stream = CompositeReadIO.new(*ios)
- end
+require 'securerandom'
+
+module Multipartable
+ def self.secure_boundary
+ # https://tools.ietf.org/html/rfc7230
+ # tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
+ # / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
+ # / DIGIT / ALPHA
+
+ # https://tools.ietf.org/html/rfc2046
+ # bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
+ # "+" / "_" / "," / "-" / "." /
+ # "/" / ":" / "=" / "?"
+
+ "--#{SecureRandom.uuid}"
+ end
+
+ def initialize(path, params, headers={}, boundary =
Multipartable.secure_boundary)
+ headers = headers.clone # don't want to modify the original variable
+ parts_headers = headers.delete(:parts) || {}
+ super(path, headers)
+ parts = params.map do |k,v|
+ case v
+ when Array
+ v.map {|item| Parts::Part.new(boundary, k, item, parts_headers[k]) }
+ else
+ Parts::Part.new(boundary, k, v, parts_headers[k])
+ end
+ end.flatten
+ parts << Parts::EpiloguePart.new(boundary)
+ ios = parts.map {|p| p.to_io }
+ self.set_content_type(headers["Content-Type"] || "multipart/form-data",
+ { "boundary" => boundary })
+ self.content_length = parts.inject(0) {|sum,i| sum + i.length }
+ self.body_stream = CompositeReadIO.new(*ios)
+
+ @boundary = boundary
end
+
+ attr :boundary
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/net/http/post/multipart.rb
new/lib/net/http/post/multipart.rb
--- old/lib/net/http/post/multipart.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/net/http/post/multipart.rb 2019-05-13 13:34:34.000000000 +0200
@@ -11,14 +11,15 @@
require 'multipartable'
require 'parts'
-module Net #:nodoc:
- class HTTP #:nodoc:
+module Net
+ class HTTP
class Put
class Multipart < Put
include Multipartable
end
end
- class Post #:nodoc:
+
+ class Post
class Multipart < Post
include Multipartable
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/parts.rb new/lib/parts.rb
--- old/lib/parts.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/parts.rb 2019-05-13 13:34:34.000000000 +0200
@@ -5,7 +5,7 @@
#++
module Parts
- module Part #:nodoc:
+ module Part
def self.new(boundary, name, value, headers = {})
headers ||= {} # avoid nil values
if file?(value)
@@ -28,8 +28,14 @@
end
end
+ # Represents a parametric part to be filled with given value.
class ParamPart
include Part
+
+ # @param boundary [String]
+ # @param name [#to_s]
+ # @param value [String]
+ # @param headers [Hash] Content-Type is used, if present.
def initialize(boundary, name, value, headers = {})
@part = build_part(boundary, name, value, headers)
@io = StringIO.new(@part)
@@ -39,6 +45,10 @@
@part.bytesize
end
+ # @param boundary [String]
+ # @param name [#to_s]
+ # @param value [String]
+ # @param headers [Hash] Content-Type is used, if present.
def build_part(boundary, name, value, headers = {})
part = ''
part << "--#{boundary}\r\n"
@@ -52,7 +62,13 @@
# Represents a part to be filled from file IO.
class FilePart
include Part
+
attr_reader :length
+
+ # @param boundary [String]
+ # @param name [#to_s]
+ # @param io [IO]
+ # @param headers [Hash]
def initialize(boundary, name, io, headers = {})
file_length = io.respond_to?(:length) ? io.length :
File.size(io.local_path)
@head = build_head(boundary, name, io.original_filename,
io.content_type, file_length,
@@ -62,25 +78,38 @@
@io = CompositeReadIO.new(StringIO.new(@head), io, StringIO.new(@foot))
end
- def build_head(boundary, name, filename, type, content_len, opts = {},
headers = {})
- trans_encoding = opts["Content-Transfer-Encoding"] || "binary"
- content_disposition = opts["Content-Disposition"] || "form-data"
+ # @param boundary [String]
+ # @param name [#to_s]
+ # @param filename [String]
+ # @param type [String]
+ # @param content_len [Integer]
+ # @param opts [Hash]
+ def build_head(boundary, name, filename, type, content_len, opts = {})
+ opts = opts.clone
+
+ trans_encoding = opts.delete("Content-Transfer-Encoding") || "binary"
+ content_disposition = opts.delete("Content-Disposition") || "form-data"
part = ''
part << "--#{boundary}\r\n"
part << "Content-Disposition: #{content_disposition};
name=\"#{name.to_s}\"; filename=\"#{filename}\"\r\n"
part << "Content-Length: #{content_len}\r\n"
- if content_id = opts["Content-ID"]
+ if content_id = opts.delete("Content-ID")
part << "Content-ID: #{content_id}\r\n"
end
- if headers["Content-Type"] != nil
- part << "Content-Type: " + headers["Content-Type"] + "\r\n"
+ if opts["Content-Type"] != nil
+ part << "Content-Type: " + opts["Content-Type"] + "\r\n"
else
part << "Content-Type: #{type}\r\n"
end
part << "Content-Transfer-Encoding: #{trans_encoding}\r\n"
+
+ opts.each do |k, v|
+ part << "#{k}: #{v}\r\n"
+ end
+
part << "\r\n"
end
end
@@ -88,8 +117,9 @@
# Represents the epilogue or closing boundary.
class EpiloguePart
include Part
+
def initialize(boundary)
- @part = "--#{boundary}--\r\n\r\n"
+ @part = "--#{boundary}--\r\n"
@io = StringIO.new(@part)
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata 1970-01-01 01:00:00.000000000 +0100
+++ new/metadata 2019-05-13 13:34:34.000000000 +0200
@@ -1,28 +1,80 @@
--- !ruby/object:Gem::Specification
name: multipart-post
version: !ruby/object:Gem::Version
- version: 2.0.0
- prerelease:
+ version: 2.1.1
platform: ruby
authors:
- Nick Sieger
+- Samuel Williams
autorequire:
bindir: bin
cert_chain: []
-date: 2013-12-21 00:00:00.000000000 Z
-dependencies: []
-description: ! 'Use with Net::HTTP to do multipart form posts. IO values that
have
+date: 2019-05-13 00:00:00.000000000 Z
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: bundler
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: '1.3'
+ - - "<"
+ - !ruby/object:Gem::Version
+ version: '3'
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: '1.3'
+ - - "<"
+ - !ruby/object:Gem::Version
+ version: '3'
+- !ruby/object:Gem::Dependency
+ name: rspec
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - "~>"
+ - !ruby/object:Gem::Version
+ version: '3.4'
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - "~>"
+ - !ruby/object:Gem::Version
+ version: '3.4'
+- !ruby/object:Gem::Dependency
+ name: rake
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: '0'
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: '0'
+description: 'Use with Net::HTTP to do multipart form postspec. IO values that
have
#content_type, #original_filename, and #local_path will be posted as a
binary file.'
email:
- [email protected]
+- [email protected]
executables: []
extensions: []
extra_rdoc_files: []
files:
-- .gitignore
-- .travis.yml
+- ".gitignore"
+- ".rspec"
+- ".travis.yml"
+- ".yardopts"
- Gemfile
- History.txt
+- LICENSE
- Manifest.txt
- README.md
- Rakefile
@@ -32,48 +84,37 @@
- lib/net/http/post/multipart.rb
- lib/parts.rb
- multipart-post.gemspec
-- test/multibyte.txt
-- test/net/http/post/test_multipart.rb
-- test/test_composite_io.rb
-- test/test_parts.rb
+- spec/composite_io_spec.rb
+- spec/multibyte.txt
+- spec/net/http/post/multipart_spec.rb
+- spec/parts_spec.rb
+- spec/spec_helper.rb
homepage: https://github.com/nicksieger/multipart-post
licenses:
- MIT
+metadata: {}
post_install_message:
-rdoc_options:
-- --main
-- README.md
-- -SHN
-- -f
-- darkfish
+rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - ">="
- !ruby/object:Gem::Version
version: '0'
- segments:
- - 0
- hash: 3851181222699685043
required_rubygems_version: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - ">="
- !ruby/object:Gem::Version
version: '0'
- segments:
- - 0
- hash: 3851181222699685043
requirements: []
-rubyforge_project: caldersphere
-rubygems_version: 1.8.23
+rubygems_version: 3.0.3
signing_key:
-specification_version: 3
+specification_version: 4
summary: A multipart form post accessory for Net::HTTP.
test_files:
-- test/multibyte.txt
-- test/net/http/post/test_multipart.rb
-- test/test_composite_io.rb
-- test/test_parts.rb
+- spec/composite_io_spec.rb
+- spec/multibyte.txt
+- spec/net/http/post/multipart_spec.rb
+- spec/parts_spec.rb
+- spec/spec_helper.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/multipart-post.gemspec new/multipart-post.gemspec
--- old/multipart-post.gemspec 1970-01-01 01:00:00.000000000 +0100
+++ new/multipart-post.gemspec 2019-05-13 13:34:34.000000000 +0200
@@ -2,21 +2,22 @@
$:.push File.expand_path("../lib", __FILE__)
require "multipart_post"
-Gem::Specification.new do |s|
- s.name = "multipart-post"
- s.version = MultipartPost::VERSION
- s.authors = ["Nick Sieger"]
- s.email = ["[email protected]"]
- s.homepage = "https://github.com/nicksieger/multipart-post"
- s.summary = %q{A multipart form post accessory for Net::HTTP.}
- s.license = "MIT"
- s.description = %q{Use with Net::HTTP to do multipart form posts. IO values
that have #content_type, #original_filename, and #local_path will be posted as
a binary file.}
-
- s.rubyforge_project = "caldersphere"
-
- s.files = `git ls-files`.split("\n")
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f|
File.basename(f) }
- s.rdoc_options = ["--main", "README.md", "-SHN", "-f", "darkfish"]
- s.require_paths = ["lib"]
+Gem::Specification.new do |spec|
+ spec.name = "multipart-post"
+ spec.version = MultipartPost::VERSION
+ spec.authors = ["Nick Sieger", "Samuel Williams"]
+ spec.email = ["[email protected]",
"[email protected]"]
+ spec.homepage = "https://github.com/nicksieger/multipart-post"
+ spec.summary = %q{A multipart form post accessory for Net::HTTP.}
+ spec.license = "MIT"
+ spec.description = %q{Use with Net::HTTP to do multipart form postspec. IO
values that have #content_type, #original_filename, and #local_path will be
posted as a binary file.}
+
+ spec.files = `git ls-files`.split("\n")
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f|
File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_development_dependency 'bundler', ['>= 1.3', '< 3']
+ spec.add_development_dependency 'rspec', '~> 3.4'
+ spec.add_development_dependency 'rake'
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/spec/composite_io_spec.rb
new/spec/composite_io_spec.rb
--- old/spec/composite_io_spec.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/spec/composite_io_spec.rb 2019-05-13 13:34:34.000000000 +0200
@@ -0,0 +1,138 @@
+# Copyright, 2012, by Nick Sieger.
+# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+require 'composite_io'
+require 'stringio'
+require 'timeout'
+
+RSpec.shared_context "composite io" do
+ it "test_full_read_from_several_ios" do
+ expect(subject.read).to be == 'the quick brown fox'
+ end
+
+ it "test_partial_read" do
+ expect(subject.read(9)).to be == 'the quick'
+ end
+
+ it "test_partial_read_to_boundary" do
+ expect(subject.read(10)).to be == 'the quick '
+ end
+
+ it "test_read_with_size_larger_than_available" do
+ expect(subject.read(32)).to be == 'the quick brown fox'
+ end
+
+ it "test_read_into_buffer" do
+ buf = ''
+ subject.read(nil, buf)
+ expect(buf).to be == 'the quick brown fox'
+ end
+
+ it "test_multiple_reads" do
+ expect(subject.read(4)).to be == 'the '
+ expect(subject.read(4)).to be == 'quic'
+ expect(subject.read(4)).to be == 'k br'
+ expect(subject.read(4)).to be == 'own '
+ expect(subject.read(4)).to be == 'fox'
+ end
+
+ it "test_read_after_end" do
+ subject.read
+ expect(subject.read).to be == ""
+ end
+
+ it "test_read_after_end_with_amount" do
+ subject.read(32)
+ expect(subject.read(32)).to be_nil
+ end
+
+ it "test_second_full_read_after_rewinding" do
+ subject.read
+ subject.rewind
+ expect(subject.read).to be == 'the quick brown fox'
+ end
+
+ # Was apparently broken on JRuby due to
http://jira.codehaus.org/browse/JRUBY-7109
+ it "test_compatible_with_copy_stream" do
+ target_io = StringIO.new
+ Timeout.timeout(1) do # Not sure why we need this in the spec?
+ IO.copy_stream(subject, target_io)
+ end
+ expect(target_io.string).to be == "the quick brown fox"
+ end
+end
+
+RSpec.describe CompositeReadIO do
+ describe "generic io" do
+ subject {StringIO.new('the quick brown fox')}
+
+ include_context "composite io"
+ end
+
+ describe "composite io" do
+ subject {CompositeReadIO.new(StringIO.new('the '), StringIO.new('quick '),
StringIO.new('brown '), StringIO.new('fox'))}
+
+ include_context "composite io"
+ end
+
+ describe "nested composite io" do
+ subject {CompositeReadIO.new(CompositeReadIO.new(StringIO.new('the '),
StringIO.new('quick ')), StringIO.new('brown '), StringIO.new('fox'))}
+
+ include_context "composite io"
+ end
+
+ describe "unicode composite io" do
+ let(:utf8_io) {File.open(File.dirname(__FILE__)+'/multibyte.txt')}
+ let(:binary_io) {StringIO.new("\x86")}
+
+ subject {CompositeReadIO.new(binary_io, utf8_io)}
+
+ it "test_read_from_multibyte" do
+ expect(subject.read).to be ==
"\x86\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\n".b
+ end
+ end
+
+ it "test_convert_error" do
+ expect do
+ UploadIO.convert!('tmp.txt', 'text/plain', 'tmp.txt', 'tmp.txt')
+ end.to raise_error(ArgumentError, /convert! has been removed/)
+ end
+
+ it "test_empty" do
+ expect(subject.read).to be == ""
+ end
+
+ it "test_empty_limited" do
+ expect(subject.read(1)).to be_nil
+ end
+
+ it "test_empty_parts" do
+ io = CompositeReadIO.new(StringIO.new, StringIO.new('the '), StringIO.new,
StringIO.new('quick'))
+ expect(io.read(3)).to be == "the"
+ expect(io.read(3)).to be == " qu"
+ expect(io.read(3)).to be == "ick"
+ end
+
+ it "test_all_empty_parts" do
+ io = CompositeReadIO.new(StringIO.new, StringIO.new)
+ expect(io.read(1)).to be_nil
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/spec/multibyte.txt new/spec/multibyte.txt
--- old/spec/multibyte.txt 1970-01-01 01:00:00.000000000 +0100
+++ new/spec/multibyte.txt 2019-05-13 13:34:34.000000000 +0200
@@ -0,0 +1 @@
+ファイル
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/spec/net/http/post/multipart_spec.rb
new/spec/net/http/post/multipart_spec.rb
--- old/spec/net/http/post/multipart_spec.rb 1970-01-01 01:00:00.000000000
+0100
+++ new/spec/net/http/post/multipart_spec.rb 2019-05-13 13:34:34.000000000
+0200
@@ -0,0 +1,123 @@
+#--
+# Copyright (c) 2007-2013 Nick Sieger.
+# See the file README.txt included with the distribution for
+# software license details.
+#++
+
+require 'net/http/post/multipart'
+
+RSpec.shared_context "net http multipart" do
+ let(:temp_file) {"temp.txt"}
+ let(:http_post) do
+ Struct.new("HTTPPost", :content_length, :body_stream, :content_type) do
+ def set_content_type(type, params = {})
+ self.content_type = type + params.map{|k,v|"; #{k}=#{v}"}.join('')
+ end
+ end
+ end
+
+ after(:each) do
+ File.delete(temp_file) rescue nil
+ end
+
+ def assert_results(post)
+ expect(post.content_length).to be > 0
+ expect(post.body_stream).to_not be_nil
+
+ expect(post['content-type']).to be == "multipart/form-data;
boundary=#{post.boundary}"
+
+ body = post.body_stream.read
+ boundary_regex = Regexp.quote(post.boundary)
+
+ expect(body).to be =~ /1234567890/
+
+ # ensure there is at least one boundary
+ expect(body).to be =~ /^--#{boundary_regex}\r\n/
+
+ # ensure there is an epilogue
+ expect(body).to be =~ /^--#{boundary_regex}--\r\n/
+ expect(body).to be =~ /text\/plain/
+
+ if (body =~ /multivalueParam/)
+ expect(body.scan(/^.*multivalueParam.*$/).size).to be == 2
+ end
+ end
+
+ def assert_additional_headers_added(post, parts_headers)
+ post.body_stream.rewind
+ body = post.body_stream.read
+ parts_headers.each do |part, headers|
+ headers.each do |k,v|
+ expect(body).to be =~ /#{k}: #{v}/
+ end
+ end
+ end
+end
+
+RSpec.describe Net::HTTP::Post::Multipart do
+ include_context "net http multipart"
+
+ it "test_form_multipart_body" do
+ File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
+ @io = File.open(TEMP_FILE)
+ @io = UploadIO.new @io, "text/plain", TEMP_FILE
+ assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :foo => 'bar',
:file => @io)
+ end
+
+ it "test_form_multipart_body_with_stringio" do
+ @io = StringIO.new("1234567890")
+ @io = UploadIO.new @io, "text/plain", TEMP_FILE
+ assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :foo => 'bar',
:file => @io)
+ end
+
+ it "test_form_multiparty_body_with_parts_headers" do
+ @io = StringIO.new("1234567890")
+ @io = UploadIO.new @io, "text/plain", TEMP_FILE
+ parts = { :text => 'bar', :file => @io }
+ headers = {
+ :parts => {
+ :text => { "Content-Type" => "part/type" },
+ :file => { "Content-Transfer-Encoding" => "part-encoding" }
+ }
+ }
+
+ request = Net::HTTP::Post::Multipart.new("/foo/bar", parts, headers)
+ assert_results request
+ assert_additional_headers_added(request, headers[:parts])
+ end
+
+ it "test_form_multipart_body_with_array_value" do
+ File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
+ @io = File.open(TEMP_FILE)
+ @io = UploadIO.new @io, "text/plain", TEMP_FILE
+ params = {:foo => ['bar', 'quux'], :file => @io}
+ headers = { :parts => {
+ :foo => { "Content-Type" => "application/json; charset=UTF-8" } } }
+ post = Net::HTTP::Post::Multipart.new("/foo/bar", params, headers)
+
+ expect(post.content_length).to be > 0
+ expect(post.body_stream).to_not be_nil
+
+ body = post.body_stream.read
+ expect(body.lines.grep(/name="foo"/).length).to be == 2
+ expect(body).to be =~ /Content-Type: application\/json; charset=UTF-8/
+ end
+
+ it "test_form_multipart_body_with_arrayparam" do
+ File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
+ @io = File.open(TEMP_FILE)
+ @io = UploadIO.new @io, "text/plain", TEMP_FILE
+ assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :multivalueParam
=> ['bar','bah'], :file => @io)
+ end
+end
+
+RSpec.describe Net::HTTP::Put::Multipart do
+ include_context "net http multipart"
+
+ it "test_form_multipart_body_put" do
+ File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
+ @io = File.open(TEMP_FILE)
+ @io = UploadIO.new @io, "text/plain", TEMP_FILE
+ assert_results Net::HTTP::Put::Multipart.new("/foo/bar", :foo => 'bar',
:file => @io)
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/spec/parts_spec.rb new/spec/parts_spec.rb
--- old/spec/parts_spec.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/spec/parts_spec.rb 2019-05-13 13:34:34.000000000 +0200
@@ -0,0 +1,102 @@
+# Copyright, 2012, by Nick Sieger.
+# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+require 'parts'
+require 'stringio'
+require 'composite_io'
+require 'tempfile'
+
+MULTIBYTE = File.dirname(__FILE__)+'/multibyte.txt'
+TEMP_FILE = "temp.txt"
+
+module AssertPartLength
+ def assert_part_length(part)
+ bytes = part.to_io.read
+ bytesize = bytes.respond_to?(:bytesize) ? bytes.bytesize : bytes.length
+ expect(bytesize).to be == part.length
+ end
+end
+
+RSpec.describe Parts do
+ let(:string_with_content_type) do
+ Class.new(String) do
+ def content_type; 'application/data'; end
+ end
+ end
+
+ it "test_file_with_upload_io" do
+ expect(Parts::Part.file?(UploadIO.new(__FILE__, "text/plain"))).to be true
+ end
+
+ it "test_file_with_modified_string" do
+ expect(Parts::Part.file?(string_with_content_type.new("Hello"))).to be
false
+ end
+
+ it "test_new_with_modified_string" do
+ expect(Parts::Part.new("boundary", "multibyte",
string_with_content_type.new("Hello"))).to be_kind_of(Parts::ParamPart)
+ end
+end
+
+RSpec.describe Parts::FilePart do
+ include AssertPartLength
+
+ before(:each) do
+ File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
+ io = UploadIO.new(TEMP_FILE, "text/plain")
+ @part = Parts::FilePart.new("boundary", "afile", io)
+ end
+
+ after(:each) do
+ File.delete(TEMP_FILE) rescue nil
+ end
+
+ it "test_correct_length" do
+ assert_part_length @part
+ end
+
+ it "test_multibyte_file_length" do
+ assert_part_length Parts::FilePart.new("boundary", "multibyte",
UploadIO.new(MULTIBYTE, "text/plain"))
+ end
+
+ it "test_multibyte_filename" do
+ name = File.read(MULTIBYTE, 300)
+ file = Tempfile.new(name.respond_to?(:force_encoding) ?
name.force_encoding("UTF-8") : name)
+ assert_part_length Parts::FilePart.new("boundary", "multibyte",
UploadIO.new(file, "text/plain"))
+ file.close
+ end
+
+ it "test_force_content_type_header" do
+ part = Parts::FilePart.new("boundary", "afile", UploadIO.new(TEMP_FILE,
"text/plain"), { "Content-Type" => "application/pdf" })
+ expect(part.to_io.read).to match(/Content-Type: application\/pdf/)
+ end
+end
+
+RSpec.describe Parts::ParamPart do
+ include AssertPartLength
+
+ before(:each) do
+ @part = Parts::ParamPart.new("boundary", "multibyte", File.read(MULTIBYTE))
+ end
+
+ it "test_correct_length" do
+ assert_part_length @part
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/spec/spec_helper.rb new/spec/spec_helper.rb
--- old/spec/spec_helper.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/spec/spec_helper.rb 2019-05-13 13:34:34.000000000 +0200
@@ -0,0 +1,29 @@
+
+if ENV['COVERAGE']
+ begin
+ require 'simplecov'
+
+ SimpleCov.start do
+ add_filter "/spec/"
+ end
+
+ if ENV['TRAVIS']
+ require 'coveralls'
+ Coveralls.wear!
+ end
+ rescue LoadError
+ warn "Could not load simplecov: #{$!}"
+ end
+end
+
+require "bundler/setup"
+require "multipart_post"
+
+RSpec.configure do |config|
+ # Enable flags like --only-failures and --next-failure
+ config.example_status_persistence_file_path = ".rspec_status"
+
+ config.expect_with :rspec do |c|
+ c.syntax = :expect
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/test/multibyte.txt new/test/multibyte.txt
--- old/test/multibyte.txt 1970-01-01 01:00:00.000000000 +0100
+++ new/test/multibyte.txt 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-ファイル
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/test/net/http/post/test_multipart.rb
new/test/net/http/post/test_multipart.rb
--- old/test/net/http/post/test_multipart.rb 1970-01-01 01:00:00.000000000
+0100
+++ new/test/net/http/post/test_multipart.rb 1970-01-01 01:00:00.000000000
+0100
@@ -1,110 +0,0 @@
-#--
-# Copyright (c) 2007-2013 Nick Sieger.
-# See the file README.txt included with the distribution for
-# software license details.
-#++
-
-require 'net/http/post/multipart'
-require 'test/unit'
-
-class Net::HTTP::Post::MultiPartTest < Test::Unit::TestCase
- TEMP_FILE = "temp.txt"
-
- HTTPPost = Struct.new("HTTPPost", :content_length, :body_stream,
:content_type)
- HTTPPost.module_eval do
- def set_content_type(type, params = {})
- self.content_type = type + params.map{|k,v|"; #{k}=#{v}"}.join('')
- end
- end
-
- def teardown
- File.delete(TEMP_FILE) rescue nil
- end
-
- def test_form_multipart_body
- File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
- @io = File.open(TEMP_FILE)
- @io = UploadIO.new @io, "text/plain", TEMP_FILE
- assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :foo => 'bar',
:file => @io)
- end
- def test_form_multipart_body_put
- File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
- @io = File.open(TEMP_FILE)
- @io = UploadIO.new @io, "text/plain", TEMP_FILE
- assert_results Net::HTTP::Put::Multipart.new("/foo/bar", :foo => 'bar',
:file => @io)
- end
-
- def test_form_multipart_body_with_stringio
- @io = StringIO.new("1234567890")
- @io = UploadIO.new @io, "text/plain", TEMP_FILE
- assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :foo => 'bar',
:file => @io)
- end
-
- def test_form_multiparty_body_with_parts_headers
- @io = StringIO.new("1234567890")
- @io = UploadIO.new @io, "text/plain", TEMP_FILE
- parts = { :text => 'bar', :file => @io }
- headers = {
- :parts => {
- :text => { "Content-Type" => "part/type" },
- :file => { "Content-Transfer-Encoding" => "part-encoding" }
- }
- }
-
- request = Net::HTTP::Post::Multipart.new("/foo/bar", parts, headers)
- assert_results request
- assert_additional_headers_added(request, headers[:parts])
- end
-
- def test_form_multipart_body_with_array_value
- File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
- @io = File.open(TEMP_FILE)
- @io = UploadIO.new @io, "text/plain", TEMP_FILE
- params = {:foo => ['bar', 'quux'], :file => @io}
- headers = { :parts => {
- :foo => { "Content-Type" => "application/json; charset=UTF-8" } } }
- post = Net::HTTP::Post::Multipart.new("/foo/bar", params, headers,
-
Net::HTTP::Post::Multipart::DEFAULT_BOUNDARY)
-
- assert post.content_length && post.content_length > 0
- assert post.body_stream
-
- body = post.body_stream.read
- assert_equal 2, body.lines.grep(/name="foo"/).length
- assert body =~ /Content-Type: application\/json; charset=UTF-8/, body
- end
-
- def test_form_multipart_body_with_arrayparam
- File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
- @io = File.open(TEMP_FILE)
- @io = UploadIO.new @io, "text/plain", TEMP_FILE
- assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :multivalueParam
=> ['bar','bah'], :file => @io)
- end
-
- def assert_results(post)
- assert post.content_length && post.content_length > 0
- assert post.body_stream
- assert_equal "multipart/form-data;
boundary=#{Multipartable::DEFAULT_BOUNDARY}", post['content-type']
- body = post.body_stream.read
- boundary_regex = Regexp.quote Multipartable::DEFAULT_BOUNDARY
- assert body =~ /1234567890/
- # ensure there is at least one boundary
- assert body =~ /^--#{boundary_regex}\r\n/
- # ensure there is an epilogue
- assert body =~ /^--#{boundary_regex}--\r\n/
- assert body =~ /text\/plain/
- if (body =~ /multivalueParam/)
- assert_equal 2, body.scan(/^.*multivalueParam.*$/).size
- end
- end
-
- def assert_additional_headers_added(post, parts_headers)
- post.body_stream.rewind
- body = post.body_stream.read
- parts_headers.each do |part, headers|
- headers.each do |k,v|
- assert body =~ /#{k}: #{v}/
- end
- end
- end
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/test/test_composite_io.rb
new/test/test_composite_io.rb
--- old/test/test_composite_io.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/test/test_composite_io.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,115 +0,0 @@
-#--
-# Copyright (c) 2007-2013 Nick Sieger.
-# See the file README.txt included with the distribution for
-# software license details.
-#++
-
-require 'composite_io'
-require 'stringio'
-require 'test/unit'
-require 'timeout'
-
-class CompositeReadIOTest < Test::Unit::TestCase
- def setup
- @io = CompositeReadIO.new(CompositeReadIO.new(StringIO.new('the '),
StringIO.new('quick ')),
- StringIO.new('brown '), StringIO.new('fox'))
- end
-
- def test_full_read_from_several_ios
- assert_equal 'the quick brown fox', @io.read
- end
-
- unless RUBY_VERSION < '1.9'
- def test_read_from_multibyte
- utf8 = File.open(File.dirname(__FILE__)+'/multibyte.txt')
- binary = StringIO.new("\x86")
- @io = CompositeReadIO.new(binary,utf8)
-
- expect = "\x86\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\n"
- expect.force_encoding('BINARY') if expect.respond_to?(:force_encoding)
- assert_equal expect, @io.read
- end
- end
-
- def test_partial_read
- assert_equal 'the quick', @io.read(9)
- end
-
- def test_partial_read_to_boundary
- assert_equal 'the quick ', @io.read(10)
- end
-
- def test_read_with_size_larger_than_available
- assert_equal 'the quick brown fox', @io.read(32)
- end
-
- def test_read_into_buffer
- buf = ''
- @io.read(nil, buf)
- assert_equal 'the quick brown fox', buf
- end
-
- def test_multiple_reads
- assert_equal 'the ', @io.read(4)
- assert_equal 'quic', @io.read(4)
- assert_equal 'k br', @io.read(4)
- assert_equal 'own ', @io.read(4)
- assert_equal 'fox', @io.read(4)
- end
-
- def test_read_after_end
- @io.read
- assert_equal "", @io.read
- end
-
- def test_read_after_end_with_amount
- @io.read(32)
- assert_equal nil, @io.read(32)
- end
-
- def test_second_full_read_after_rewinding
- @io.read
- @io.rewind
- assert_equal 'the quick brown fox', @io.read
- end
-
- def test_convert_error
- assert_raises(ArgumentError) {
- UploadIO.convert!('tmp.txt', 'text/plain', 'tmp.txt', 'tmp.txt')
- }
- end
-
- ## FIXME excluding on JRuby due to
- ## http://jira.codehaus.org/browse/JRUBY-7109
- if IO.respond_to?(:copy_stream) && !defined?(JRUBY_VERSION)
- def test_compatible_with_copy_stream
- target_io = StringIO.new
- Timeout.timeout(1) do
- IO.copy_stream(@io, target_io)
- end
- assert_equal "the quick brown fox", target_io.string
- end
- end
-
- def test_empty
- io = CompositeReadIO.new
- assert_equal "", io.read
- end
-
- def test_empty_limited
- io = CompositeReadIO.new
- assert_nil io.read(1)
- end
-
- def test_empty_parts
- io = CompositeReadIO.new(StringIO.new, StringIO.new('the '), StringIO.new,
StringIO.new('quick'))
- assert_equal "the", io.read(3)
- assert_equal " qu", io.read(3)
- assert_equal "ick", io.read(4)
- end
-
- def test_all_empty_parts
- io = CompositeReadIO.new(StringIO.new, StringIO.new)
- assert_nil io.read(1)
- end
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/test/test_parts.rb new/test/test_parts.rb
--- old/test/test_parts.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/test/test_parts.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,86 +0,0 @@
-#--
-# Copyright (c) 2007-2012 Nick Sieger.
-# See the file README.txt included with the distribution for
-# software license details.
-#++
-
-require 'test/unit'
-
-require 'parts'
-require 'stringio'
-require 'composite_io'
-require 'tempfile'
-
-
-MULTIBYTE = File.dirname(__FILE__)+'/multibyte.txt'
-TEMP_FILE = "temp.txt"
-
-module AssertPartLength
- def assert_part_length(part)
- bytes = part.to_io.read
- bytesize = bytes.respond_to?(:bytesize) ? bytes.bytesize : bytes.length
- assert_equal bytesize, part.length
- end
-end
-
-class PartTest < Test::Unit::TestCase
- def setup
- @string_with_content_type = Class.new(String) do
- def content_type; 'application/data'; end
- end
- end
-
- def test_file_with_upload_io
- assert Parts::Part.file?(UploadIO.new(__FILE__, "text/plain"))
- end
-
- def test_file_with_modified_string
- assert !Parts::Part.file?(@string_with_content_type.new("Hello"))
- end
-
- def test_new_with_modified_string
- assert_kind_of Parts::ParamPart,
- Parts::Part.new("boundary", "multibyte",
@string_with_content_type.new("Hello"))
- end
-end
-
-class FilePartTest < Test::Unit::TestCase
- include AssertPartLength
-
- def setup
- File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
- io = UploadIO.new(TEMP_FILE, "text/plain")
- @part = Parts::FilePart.new("boundary", "afile", io)
- end
-
- def teardown
- File.delete(TEMP_FILE) rescue nil
- end
-
- def test_correct_length
- assert_part_length @part
- end
-
- def test_multibyte_file_length
- assert_part_length Parts::FilePart.new("boundary", "multibyte",
UploadIO.new(MULTIBYTE, "text/plain"))
- end
-
- def test_multibyte_filename
- name = File.read(MULTIBYTE, 300)
- file = Tempfile.new(name.respond_to?(:force_encoding) ?
name.force_encoding("UTF-8") : name)
- assert_part_length Parts::FilePart.new("boundary", "multibyte",
UploadIO.new(file, "text/plain"))
- file.close
- end
-end
-
-class ParamPartTest < Test::Unit::TestCase
- include AssertPartLength
-
- def setup
- @part = Parts::ParamPart.new("boundary", "multibyte", File.read(MULTIBYTE))
- end
-
- def test_correct_length
- assert_part_length @part
- end
-end