socketry / multipart-post Goto Github PK
View Code? Open in Web Editor NEWAdds multipart POST capability to net/http
License: MIT License
Adds multipart POST capability to net/http
License: MIT License
In Ruby 1.8.7, StringIO responds to path, but in 1.9.2, it no longer does, which causes UploadIO to break (composite_io.rb:69).
An easy solution would be to check for obj.respond_to? :path ? obj.path : "no local path" (in my tests, supplying a dummy local path seems to work), but I don't know if that causes problems down the line. If not, one of us could write a pull request.
Thanks for the great gem!
Alex
I ended up updating to the new constants, but I thought I'd let you know that the deprecations aren't working as likely intended as they do not appear to be required when loading multipart/post
.
Would there be any chance of releasing a new version of this package to RubyGems?
There've been a bunch of exciting changes - for example #70 - but they're only accessible by installing from GitHub rather than using a versioned, released package.
2.2.2 dropped support for Ruby <2.6.0. This is a backwards-incompatible change, so per semver it should be a major version bump. Older Rubies (with older rubygems) depending on multipart-post ~> 2.x
will now fail to install:
$ docker run --rm -it ruby:2.5-alpine gem install multipart-post -v '~> 2.2'
Fetching multipart-post-2.2.2.gem
ERROR: Error installing multipart-post:
The last version of multipart-post (~> 2.2) to support your Ruby & RubyGems was 2.2.0. Try installing it with `gem install multipart-post -v 2.2.0`
multipart-post requires Ruby version >= 2.6.0. The current ruby version is 2.5.9.229.
I'd suggest that the current gem should be rereleased as 3.0, and 2.2.2 be yanked.
I recognize that 2.5 (and 2.6) are old Rubies at this point, so I have no overall complaint about dropping support in a newer gem version here. It's just that the way this was implemented, those older Rubies can't even keep going with version constraints that were previously valid.
Thanks!
Hello,
I notice that in my project when I use Faraday 0.17.4 which depends on this gem I get warning:
"Top level ::MultipartPost is deprecated, require 'multipart/post' and use
Multipart::Post
instead!"
I checked the code and see that here does a force warn
no matter what. Why is it done in that way?
Hello,
I'm trying to use this gem to upload files through a secure connection using SSL, but it seems to be impossible.
Does anyone have a guide or something to help me sort this issue?
I've tried some combinations of the code using http://www.rubyinside.com/nethttp-cheat-sheet-2940.html
but no luck.
Thanks.
In v2.2.0 (RubyGems.org v2.2.0), dropped Ruby 2.2 support due to #91.
Specify the version in the gemspec. @ioquatix thoughts?
From 83cd51e3fe6e1e2be1375602274caa6ae0ac2a86 Mon Sep 17 00:00:00 2001
From: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Thu, 30 Jul 2015 04:20:00 +0000
Subject: [PATCH] variable.c: Module#deprecate_constant
* variable.c (rb_const_get_0): warn deprecated constant reference.
* variable.c (rb_mod_deprecate_constant): mark constants to be
warned as deprecated. [Feature #11398]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
when POST a.jpg to server with new name 'a'.
it will raise:
/home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/parts.rb:42:in `size': No such file or directory - 2 (Errno::ENOENT)
from /home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/parts.rb:42:in`initialize'
from /home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/parts.rb:5:in `new'
from /home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/parts.rb:5:in`new'
from /home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/multipartable.rb:6:in `initialize'
from /home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/composite_io.rb:76:in`map'
from /home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/multipartable.rb:6:in `each'
from /home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/multipartable.rb:6:in`map'
from /home/gavin_kou/local/lib/ruby/gems/1.8/gems/multipart-post-1.0.1/lib/multipartable.rb:6:in `initialize'
in parts.rb line 41. change from:
file_length = io.respond_to?(:length) ? io.length : File.size(io.local_path)
to
file_length = io.respond_to?(:length) ? io.length : File.size(io.path)
it works fine.
Hi Nick,
This really just a support request (don't think it is a bug) ... if you have time to answer or sample code to point me to.
I'm working on making a script to take my gh-pages branch and upload itto github
They use a two part POST technique described here: http://developer.github.com/v3/repos/downloads/
Here's some of my code -- the first POST using HTTParty works and I get back valid json.
class Github
include HTTParty
base_uri 'https://api.github.com/repos/concord-consortium/lab'
format :json
basic_auth CONFIG[:username], CONFIG[:password]
debug_output
end
tag = `git log -1 --date=short --format=%cd-%h gh-pages`.strip
name = "lab-dist-#{tag}.tar.gz"
if File.exist?("uploads/#{name}") || system("git archive gh-pages | gzip >uploads/#{name}")
options = {
"name" => name,
"size" => File.stat("uploads/#{name}").size,
"description" => "Latest release of Lab distribution",
"content_type" => "application/x-gzip"
}
response = Github.post('/downloads', :body => MultiJson.encode(options))
pp response
This is the part that doesn't work:
url = URI.parse(response['s3_url'])
File.open("#{PROJECT_ROOT}/uploads/#{name}") do |archive|
req = Net::HTTP::Post::Multipart.new url.path,
'key' => response['path'],
'acl' => response['acl'],
'success_action_status' => 201,
'Filename' => response['name'],
'AWSAccessKeyId' => response['accesskeyid'],
'Policy' => response['policy'],
'Signature' => response['signature'],
'Content-Type' => response['mime_type'],
"file" => UploadIO.new(archive, response['mime_type'])
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
end
I'm pretty sure thats NOT how to add the extra parameters for the multipart post -- but I didn't see an example combining the file and the other form' elements.
Thanks for any help!
I am experiencing an issue in multipart-post
2.0.0. I have a client piece of code that looks roughly like this:
require 'net/http'
require 'net/http/post/multipart'
http = Net::HTTP.new('localhost', 8080)
http.start do |http|
File.open('C:/data/asd.png') do |png|
req = Net::HTTP::Post::Multipart.new('http://localhost:8080/some-endpoint',
'uploadId' => "some-internal-data",
'files[]' => UploadIO.new(png, 'image/png', 'asd.png'),
'size' => 186670,
)
# Some headers for session ID and CSRF protection
req['Cookie'] = "JSESSIONID=1234567890abcdef"
req['X-Requested-By'] = 'UNUSED'
http.request(req)
end
end
The code runs on JRuby 9.1.6.0 on Windows 10. When I run it I get this stack trace:
Net::ReadTimeout: Net::ReadTimeout
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/protocol.rb:158:in `rbuf_fill'
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/protocol.rb:136:in `readuntil'
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/protocol.rb:146:in `readline'
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/http/response.rb:40:in `read_status_line'
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/http/response.rb:29:in `read_new'
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/http.rb:1448:in `block in transport_request'
from org/jruby/RubyKernel.java:1118:in `catch'
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/http.rb:1445:in `transport_request'
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/http.rb:1418:in `request'
from (irb):19:in `block in evaluate'
from org/jruby/RubyIO.java:1141:in `open'
from (irb):11:in `block in evaluate'
from C:/dev/jruby-9.1.6.0/lib/ruby/stdlib/net/http.rb:858:in `start'
from (irb):10:in `<eval>'
from org/jruby/RubyKernel.java:998:in `eval'
from org/jruby/RubyKernel.java:1299:in `loop'
from org/jruby/RubyKernel.java:1118:in `catch'
from org/jruby/RubyKernel.java:1118:in `catch'
from jirb:13:in `<main>'
On the server side there is a Java + Tomcat on Windows. The output from the server is java.net.SocketTimeoutException: null
. The stack trace on the server is most likely irrelevant.
I've tried identical code on a JRuby/Linux client with the exact same Java/Windows server and it worked. Furthermore - I tried MRI/Windows client and it worked too. I also tried some older builds of JRuby I have locally and they failed. So there appears to be some incompatibility in multipart-post
with JRuby on Windows.
I'm not even sure if I should be logging this here. Still it's probably good to have it here so that it's visible for users of the library. Is there something that can be done other than forwarding this to the JRuby guys?
I'm trying to figure out who is depending on multipart-post
so we can get everyone on board for a 3.0 release
If you're using multipart-post
version 2.1.0
with ruby
version 2.4.1p111
you'll receive the following exception:
NoMethodError: undefined method `alphanumeric' for SecureRandom:Module
This is because SecureRandom.alphanumeric
was added to ruby in version 2.5.0 (see ruby/ruby@b867882 and https://github.com/ruby/ruby/blob/v2_5_0/NEWS).
Ruby 2.4 is still supported by the ruby language team.
Currently you have to downgrade multipart-post
to version 2.0.0
, or upgrade the ruby to at least version 2.5.0
.
See a8bccb9 for the introducing commit.
I want to make a post request with faraday with a zip file and it fails with multipart-post.
I have this code :
conn = Faraday.new(:url => "mon_url") do |conn|
# POST/PUT params encoders:
conn.request :multipart
conn.request :url_encoded
conn.adapter :net_http
end
file = StringIO.new( { "parameters" => {
"neptune-import" => {
"no_save" => false,
"user_name" => "user",
"name" => "Mon test",
"organisation_name" => "organisation",
"referential_name" => "test",
}
}
}.to_s )
action_params_io = Faraday::UploadIO.new(file, "application/json", "parameters.json")
transport_data_io = Faraday::UploadIO.new(::Zip::File.open("demo.zip"), "application/zip", "demo.zip")
payload = {
:file1 => action_params_io,
:file2 => transport_data_io,
}
conn.post "http://", payload
And it returns an error on length method :
NoMethodError: undefined method `length' for #<Zip::File:0x007f0cb455eae8>
from /home/luc/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/multipart-post-2.0.0/lib/composite_io.rb:102:in `method_missing'
from (irb):47
Do you have any idea how I could do that with your gem?
Thanks for your time and your work
Luc Donnet
Sir,
Although this is not really an issue, at least not a major one, I would like to report that file upload is relatively slow , approximately only one third of my maximal connexion speed (which is attained when using for instance Firefox).
This is on a machine running WinXP(sp3) and Ruby 1.9. I used the code you provide as an example with two slight modifications: sslv3 and a custom header containing an Oauth2 "access token".
Note that I previously noted that "streamed" multi part uploads with Python were somewhat slower than when the file is loaded in memory, but not to the same extend.
Do you have any idea of how upload could be made faster while avoiding high memory usage?
Hi, you seem to have Hoe as a runtime dependancy.
As such I have ended up just copying your code into my gem, as opposed to having multipart-post as a dependancy. While it's ok for me to install hoe toi use your gem directly, I can't justify forcing my downstream users to install it.
If you could either git it set up as a development only dependancy, or just use gem-this or similar, that would be just great.
Thanks and sorry about the puns.
Can there be an option to silence deprecation warnings? This is the output when running grosser/parallel_tests
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::Parts is deprecated, require 'multipart/post' and use `Multipart::Post::Parts` instead!
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::Parts is deprecated, require 'multipart/post' and use `Multipart::Post::Parts` instead!
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::Parts is deprecated, require 'multipart/post' and use `Multipart::Post::Parts` instead!
Top level ::Parts is deprecated, require 'multipart/post' and use `Multipart::Post::Parts` instead!
I found out about multipart-post as a library dependency to r10k for puppet.
gem2rpm does not work with multipart-post because of a documentation issue that I would like to raise awareness on.
Normally people would bypass the errors below with --no-ri
but gem2rpm only supports --no-doc
, so the alternative is to ask "Why?" and push for a fix. Seems to be caused by an undefined/unsupported formatter called darkfish? Anyone know for sure?
+ umask 022
+ cd /tmp/mk-gem2rpm/rpmbuild/BUILD
+ cd multipart-post-2.0.0
+ LANG=C
+ export LANG
+ unset DISPLAY
+ gem build multipart-post.gemspec
Successfully built RubyGem
Name: multipart-post
Version: 2.0.0
File: multipart-post-2.0.0.gem
+ mkdir -p ./usr/lib/ruby/gems/1.8
+ CONFIGURE_ARGS='--with-cflags='\''-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'\'' '
+ gem install -V --local --install-dir ./usr/lib/ruby/gems/1.8 --bindir ./usr/bin --force multipart-post-2.0.0.gem
Installing gem multipart-post-2.0.0
Using local gem /tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/cache/multipart-post-2.0.0.gem
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/.gitignore
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/.travis.yml
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/Gemfile
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/History.txt
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/Manifest.txt
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/README.md
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/Rakefile
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/lib/composite_io.rb
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/lib/multipart_post.rb
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/lib/multipartable.rb
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/lib/net/http/post/multipart.rb
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/lib/parts.rb
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/multipart-post.gemspec
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/test/multibyte.txt
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/test/net/http/post/test_multipart.rb
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/test/test_composite_io.rb
/tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/gems/multipart-post-2.0.0/test/test_parts.rb
Successfully installed multipart-post-2.0.0
1 gem installed
Installing ri documentation for multipart-post-2.0.0...
rdoc --ri --op /tmp/mk-gem2rpm/rpmbuild/BUILD/multipart-post-2.0.0/usr/lib/ruby/gems/1.8/doc/multipart-post-2.0.0/ri --main README.md -SHN -f darkfish --quiet lib --title multipart-post-2.0.0 Documentation
Invalid output formatter
For help on options, try 'rdoc --help'
error: Bad exit status from /var/tmp/rpm-tmp.GTcHk9 (%build)
RPM build errors:
Bad exit status from /var/tmp/rpm-tmp.GTcHk9 (%build)
/tmp/mk-gem2rpm/gems/cache/semantic_puppet-0.1.1.gem
executing: gem2rpm -t spec.template /tmp/mk-gem2rpm/gems/cache/semantic_puppet-0.1.1.gem > /tmp/mk-gem2rpm/rpmbuild/SPECS/semantic_puppet-0.1.1.spec
executing: rpmbuild --define '_unpackaged_files_terminate_build 0' --define '_topdir /tmp/mk-gem2rpm/rpmbuild' -ba /tmp/mk-gem2rpm/rpmbuild/SPECS/semantic_puppet-0.1.1.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.zqNALv
# cat /var/tmp/rpm-tmp.GTcHk9
#!/bin/sh
RPM_SOURCE_DIR="/tmp/mk-gem2rpm/rpmbuild/SOURCES"
RPM_BUILD_DIR="/tmp/mk-gem2rpm/rpmbuild/BUILD"
RPM_OPT_FLAGS="-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic"
RPM_ARCH="x86_64"
RPM_OS="linux"
export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS
RPM_DOC_DIR="/usr/share/doc"
export RPM_DOC_DIR
RPM_PACKAGE_NAME="rubygem-multipart-post"
RPM_PACKAGE_VERSION="2.0.0"
RPM_PACKAGE_RELEASE="1.el6"
export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE
LANG=C
export LANG
unset CDPATH DISPLAY ||:
RPM_BUILD_ROOT="/tmp/mk-gem2rpm/rpmbuild/BUILDROOT/rubygem-multipart-post-2.0.0-1.el6.x86_64"
export RPM_BUILD_ROOT
PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/lib64/pkgconfig:/usr/share/pkgconfig"
export PKG_CONFIG_PATH
set -x
umask 022
cd "/tmp/mk-gem2rpm/rpmbuild/BUILD"
cd 'multipart-post-2.0.0'
LANG=C
export LANG
unset DISPLAY
# Create the gem as gem install only works on a gem file
gem build multipart-post.gemspec
# %gem_install compiles any C extensions and installs the gem into ./%gem_dir
# by default, so that we can move it into the buildroot in %install
mkdir -p ./usr/lib/ruby/gems/1.8
CONFIGURE_ARGS="--with-cflags='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' $CONFIGURE_ARGS" \
gem install \
-V \
--local \
--install-dir ./usr/lib/ruby/gems/1.8 \
--bindir ./usr/bin \
--force \
multipart-post-2.0.0.gem
String#length returns charactor length. Not byte-size.
String#bytesize returns length of string in bytes.
For gems depending on multipart-post that want to add a pessimistic version constraint (e.g. '~> 2.2'), it is useful to know if multipart-post follows the semantic versioning scheme.
I tend to believe it is, but I cannot find it in the README.
For those using JRuby. Image upload may not work with this gem.
Try the following code on JRuby:
f = File.open("test.png")
obj = f.read(f.size)
f.size and obj.size are not the same. It causes content-length and stream size not the same, and image file is corrupted.
I want to upload 2 files within one request.
Is there a way to do this with your lib?
There is an example in Java. It seems like I need to upload a json file and an attachment in this case.
Couldn't figure out how to do it. Do you have a hint?
JAVA EXAMPLE:
File imageFile = new File("/path/imageToUpload.jpeg"); File metadataFile = new File("/path/metadataToUpload.json");
PostMethod filePost = new PostMethod("http://host/../attachment");
Part[] parts = {
new FilePart(“metadata”, metadataFile, “application/json”, "UTF8"),
new FilePart(“attachment”, imageFile, “image/jpeg”, null);
};
filePost.setRequestEntity(
new MultipartRequestEntity(parts, filePost.getParams()) ); HttpClient client = new HttpClient(); int status = client.executeMethod(filePost);
Regards,
Christian
0af8dde#diff-9d2b9709d7d6d6706a5d7de795405083R62
Current version of multipart-post
have two \r\n
in the end of line:
class EpiloguePart
include Part
def initialize(boundary)
@part = "--#{boundary}--\r\n\r\n"
@io = StringIO.new(@part)
end
end
But the same case in other programming languages stdlib there just have one
For example Go:
http://golang.org/src/mime/multipart/writer.go?s=619:653#L160
153 func (w *Writer) Close() error {
154 if w.lastpart != nil {
155 if err := w.lastpart.close(); err != nil {
156 return err
157 }
158 w.lastpart = nil
159 }
160 _, err := fmt.Fprintf(w.w, "\r\n--%s--\r\n", w.boundary)
161 return err
162 }
Is \r\n\r\n
in the end of the line is correct?
This will not let our project upload success, becuase upload server care about that.
Trying to update multipart-post package for Fedora, I have noticed there is not license file included [1]. Could you please consider to including one? I think that inclusion of the README would be nice at minimum.
I'm using Faraday which requires this gem as a dependency. When I try this code in the rails console
conn = Faraday.new('http://localhost:3000') do |far|
far.request :multipart
far.request :url_encoded
end
params = {}
params[:user] = {:avatar => Faraday::UploadIO.new('sample.jpg', 'image/jpeg') }
response = conn.put('/users', params)
I get the following error:
Errno::ENOENT: No such file or directory - local.path
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/multipart-post-1.1.5/lib/parts.rb:51:in `size'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/multipart-post-1.1.5/lib/parts.rb:51:in `initialize'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/multipart-post-1.1.5/lib/parts.rb:11:in `new'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/multipart-post-1.1.5/lib/parts.rb:11:in `new'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:37:in `block in create_multipart'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:57:in `call'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:57:in `block in process_params'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:47:in `each'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:47:in `inject'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:47:in `process_params'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:55:in `block in process_params'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:47:in `each'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:47:in `inject'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:47:in `process_params'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:36:in `create_multipart'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:11:in `block in call'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/url_encoded.rb:20:in `match_content_type'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/request/multipart.rb:7:in `call'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/connection.rb:226:in `run_request'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/faraday-0.8.4/lib/faraday/connection.rb:99:in `put'
from (irb):60
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/railties-3.2.11/lib/rails/commands/console.rb:47:in `start'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/railties-3.2.11/lib/rails/commands/console.rb:8:in `start'
from /Users/jeremy/.rvm/gems/ruby-1.9.3-p362/gems/railties-3.2.11/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'1.9.3p362 :061 >
Using version 1.1.5
Hi, first of all thanks for this gem.
I'm trying to make it work but I don't see the uploaded file at my server. It may be related to several things, and, in order to debug, I wanted to see the request information, for example whether it's a 404 not found or a 403 not allowed.
When I do this: puts "Result: #{res}", nothing is echoed. Is there anyway to debug the result of a request.
Thanks, Diego.
ajinkya@ajinkya-Inspiron-N5010:~$ gem2deb multipart-post
multipart-post doesn't seem to exist. Let's try to download it with 'gem fetch multipart-post'
gem fetch multipart-post
Fetching: multipart-post-1.1.5.gem (100%)
Downloaded multipart-post-1.1.5
-- Creating source tarball from multipart-post-1.1.5.gem ...
tar xfm /home/ajinkya/multipart-post-1.1.5.gem
tar xzfm data.tar.gz
zcat metadata.gz > metadata.yml
tar czf /home/ajinkya/multipart-post-1.1.5.tar.gz multipart-post-1.1.5
-- Successfully created multipart-post-1.1.5.tar.gz
-- Creating Debian source package from multipart-post-1.1.5.tar.gz ...
tar xzf ruby-multipart-post_1.1.5.orig.tar.gz
-- Generated Debian source tree in ruby-multipart-post-1.1.5
-- Building Debian package ...
dpkg-buildpackage -us -uc
dpkg-buildpackage: export CFLAGS from dpkg-buildflags (origin: vendor): -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security
dpkg-buildpackage: export CPPFLAGS from dpkg-buildflags (origin: vendor): -D_FORTIFY_SOURCE=2
dpkg-buildpackage: export CXXFLAGS from dpkg-buildflags (origin: vendor): -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security
dpkg-buildpackage: export FFLAGS from dpkg-buildflags (origin: vendor): -g -O2
dpkg-buildpackage: export LDFLAGS from dpkg-buildflags (origin: vendor): -Wl,-Bsymbolic-functions -Wl,-z,relro
dpkg-buildpackage: source package ruby-multipart-post
dpkg-buildpackage: source version 1.1.5-1
dpkg-buildpackage: source changed by ajinkya ajinkya@ajinkya-Inspiron-N5010
dpkg-buildpackage: host architecture i386
dpkg-source --before-build ruby-multipart-post-1.1.5
fakeroot debian/rules clean
dh clean --buildsystem=ruby --with ruby
dh_testdir -O--buildsystem=ruby
dh_auto_clean -O--buildsystem=ruby
Entering dh_ruby --clean
Leaving dh_ruby --clean
dh_clean -O--buildsystem=ruby
dpkg-source -b ruby-multipart-post-1.1.5
dpkg-source: info: using source format 3.0 (quilt)' dpkg-source: info: building ruby-multipart-post using existing ./ruby-multipart-post_1.1.5.orig.tar.gz dpkg-source: info: building ruby-multipart-post in ruby-multipart-post_1.1.5-1.debian.tar.gz dpkg-source: info: building ruby-multipart-post in ruby-multipart-post_1.1.5-1.dsc debian/rules build dh build --buildsystem=ruby --with ruby dh_testdir -O--buildsystem=ruby dh_auto_configure -O--buildsystem=ruby dh_auto_build -O--buildsystem=ruby dh_auto_test -O--buildsystem=ruby fakeroot debian/rules binary dh binary --buildsystem=ruby --with ruby dh_testroot -O--buildsystem=ruby dh_prep -O--buildsystem=ruby dh_installdirs -O--buildsystem=ruby dh_auto_install -O--buildsystem=ruby Entering dh_ruby --install install -d /home/ajinkya/ruby-multipart-post-1.1.5/debian/ruby-multipart-post/usr/lib/ruby/vendor_ruby install -D -m644 lib/composite_io.rb /home/ajinkya/ruby-multipart-post-1.1.5/debian/ruby-multipart-post/usr/lib/ruby/vendor_ruby/composite_io.rb install -D -m644 lib/net/http/post/multipart.rb /home/ajinkya/ruby-multipart-post-1.1.5/debian/ruby-multipart-post/usr/lib/ruby/vendor_ruby/net/http/post/multipart.rb install -D -m644 lib/multipartable.rb /home/ajinkya/ruby-multipart-post-1.1.5/debian/ruby-multipart-post/usr/lib/ruby/vendor_ruby/multipartable.rb install -D -m644 lib/multipart_post.rb /home/ajinkya/ruby-multipart-post-1.1.5/debian/ruby-multipart-post/usr/lib/ruby/vendor_ruby/multipart_post.rb install -D -m644 lib/parts.rb /home/ajinkya/ruby-multipart-post-1.1.5/debian/ruby-multipart-post/usr/lib/ruby/vendor_ruby/parts.rb /usr/bin/ruby1.8 -I/usr/lib/ruby/vendor_ruby /usr/lib/ruby/vendor_ruby/gem2deb/test_runner.rb Running tests for ruby1.8 with test file list from debian/ruby-test-files.yaml ... -e:1:in
require': no such file to load -- test/multibyte.txt (LoadError)
from -e:1
from -e:1:in `each'
from -e:1
Test "ruby1.8" failed. Continue building the package? (Y/N)
gem version: 1.1.5
I have the following method (for reproducing)
require 'net/http/post/multipart'
def submit_file
f = './lib/qa_monitoring/video_source/test.mp4'
uri = URI.parse('https://api.tout.com/api/v1/touts')
header = {"Authorization"=>"Bearer some_api_token", "Connection"=>"keep-alive", "Accept"=>"application/json"}
File.open(f) do |video|
req = Net::HTTP::Post::Multipart.new(uri.path,
{"file" => UploadIO.new(video, 'video/mp4', "video.mp4")},
header)
res = Net::HTTP.start(uri.host, uri.port) do |http|
http.request(req)
end
end
res
end
When I run this in irb, I get the following exception:
Errno::EPIPE: Broken pipe
from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/protocol.rb:199:in write' from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/protocol.rb:199:in
write0'
from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/protocol.rb:173:in block in write' from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/protocol.rb:190:in
writing'
from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/protocol.rb:172:in write' from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/http.rb:1955:in
send_request_with_body_stream'
from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/http.rb:1921:in exec' from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/http.rb:1317:in
block in transport_request'
from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/http.rb:1316:in catch' from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/http.rb:1316:in
transport_request'
from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/http.rb:1293:in request' from (irb):12:in
block (2 levels) in submit_file'
from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/http.rb:745:in start' from /Users/kris/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/net/http.rb:557:in
start'
from (irb):11:in block in submit_file' from (irb):7:in
open'
from (irb):7:in `submit_file'
With the correct token, I can upload the same file via a REST client.
I have a function that uses the Net::HTTP::Post::Multipart class.
When I run my code through IRB, it works fine, but when I run it inside my Sinatra application, it hangs when calling http.request(request)
.
Try running this simple Sinatra app: http://gist.github.com/619788
Any ideas? Thanks!
I want to send some nested params with the file. Is it not getting send properly.
For example
sub_params = { contact: { 'first_name' => 'prathamesh', 'language' => 'Ruby' } }
params = sub_params.merge({ "file" => UploadIO.new(csv, "text/csv", "test.csv") })
request = Net::HTTP::Post::Multipart.new(url.path, params)
On Rails side, i get
Parameters: {"contact"=>"{\"first_name\"=>\"prathamesh\", \"language\"=>\"Ruby\"}", "file"=>#<ActionDispatch::Http::UploadedFile:0x0000000628cea8 ....}
Nested attributes first_name
and language
are delimited. But they should be not.
Right now, parts
are created assuming that value
is String
. So it is failing here where value
is Hash
like in case of nested hash.
The UploadIO
initializer accepts a list of options and uses them to construct MIME headers, but it only pulls out headers it knows about. It would be nice to be able to include arbitrary headers.
For an example use case, see the Packaging
and Content-MD5
headers in the SWORD 2.0 spec, e.g.
Content-Type: application/zip
Content-Disposition: attachment; name=payload; filename=[filename]
Packaging: http://purl.org/net/sword/package/SimpleZip
Content-MD5: [md5-digest]
MIME-Version: 1.0
...binary package data...
Hi, I'm new to ruby and I'm trying to use your gem to upload an image to ImageShack. I'm getting this error when I run the code below:
Execution:
MultipartPostTest.new
Source:
require 'rubygems'
require 'net/http/post/multipart'
class MultipartPostTest
def initialize
url = URI.parse('http://www.imageshack.us/upload_api.php')
File.open('c:/x.jpg') do |jpg|
req = Net::HTTP::Post::Multipart.new url.path,
"fileupload" => UploadIO.new(jpg, "image/jpeg", 'c:/x.jpg')
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
end
end
end
Trace:
EOFError: end of file reached
from ruby/lib/ruby/1.8/net/protocol.rb:133:in sysread' from ruby/lib/ruby/1.8/net/protocol.rb:133:in
rbuf_fill'
from ruby/lib/ruby/1.8/timeout.rb:56:in timeout' from ruby/lib/ruby/1.8/timeout.rb:76:in
timeout'
from ruby/lib/ruby/1.8/net/protocol.rb:132:in rbuf_fill' from ruby/lib/ruby/1.8/net/protocol.rb:116:in
readuntil'
from ruby/lib/ruby/1.8/net/protocol.rb:126:in readline' from ruby/lib/ruby/1.8/net/http.rb:2029:in
read_status_line'
from ruby/lib/ruby/1.8/net/http.rb:2018:in read_new' from ruby/lib/ruby/1.8/net/http.rb:1059:in
request'
from test_project/lib/multipart_post_test.rb:11:in initialize' from ruby/lib/ruby/1.8/net/http.rb:547:in
start'
from ruby/lib/ruby/1.8/net/http.rb:440:in start' from test_project/lib/multipart_post_test.rb:10:in
initialize'
from test_project/lib/multipart_post_test.rb:7:in open' from test_project/lib/multipart_post_test.rb:7:in
initialize'
from (irb):1:in `new'
from (irb):1>>
Thank you for useful gem!
On some systems, a preview of an image is not displayed correctly when I specify "local.path" as a filename. To solve this behavior, could you simply set "file" as a default filename?
If you agree with this issue, I will create a pull request. I would like to know your opinion.
One of those systems is Slack for Mac. Starting at 2021/05/05 05:30 UTC, Slack client no longer correctly displays previews of images when the filename is "local.path".
Expectation | Reality |
---|---|
The relevant code of this issue is here.
https://github.com/socketry/multipart-post/blob/master/lib/multipart/post/composite_read_io.rb#L80-L88
This is not global issue, maybe a kind of case report.
2.2.0 contains big refactoring (#65) and it makes sense. However compatibility code made an issue on my code.
I have Parts
module,
module Parts
class Foo; end
end
And with 2.1.1, it works fine.
$ bundle exec irb
2.7.2 :001 > require_relative 'parts/foo'
=> true
2.7.2 :002 > require 'net/http/post/multipart'
=> true
2.7.2 :003 > Parts::Foo.class
=> Class
2.7.2 :004 > Parts.constants
=> [:Foo, :Part, :EpiloguePart, :FilePart, :ParamPart]
However, with 2.2.0, it have loading order issue.
When load modules on following order, it works.
Parts
module2.7.2 :001 > require 'net/http/post/multipart'
=> true
2.7.2 :003 > Multipart::Post::Parts.class
=> Module
2.7.2 :006 > require_relative 'parts/foo'
=> true
2.7.2 :007 > Parts.class
=> Module
2.7.2 :011 > Parts.constants
=> [:Foo]
But when following order, it does not work.
Parts
module2.7.2 :001 > require_relative 'parts/foo'
=> true
2.7.2 :002 > require 'net/http/post/multipart'
/usr/local/rvm/gems/ruby-2.7.2/gems/multipart-post-2.2.3/lib/multipart/post/parts.rb:151: warning: already initialized constant Parts
/workspaces/sandbox-ruby/simple/parts/foo.rb:3: warning: previous definition of Parts was here
=> true
2.7.2 :003 > Parts::Foo
Traceback (most recent call last):
21: from /usr/local/rvm/gems/ruby-2.7.2/bin/ruby_executable_hooks:22:in `<main>'
20: from /usr/local/rvm/gems/ruby-2.7.2/bin/ruby_executable_hooks:22:in `eval'
19: from /usr/local/rvm/gems/ruby-2.7.2/bin/irb:23:in `<main>'
18: from /usr/local/rvm/gems/ruby-2.7.2/bin/irb:23:in `load'
17: from /usr/local/rvm/gems/ruby-2.7.2/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
(irb):3:in `<main>': uninitialized constant Multipart::Post::Parts::Foo (NameError)
I guess it led by here
multipart-post/lib/multipart/post/parts.rb
Line 151 in 31500a7
If that part of code change, it would be breaking change. so, I'm not sure how it should be fixed.
Do you have any ideas? Like applying a monkey patch?
Travis ended, what do we want to use next? GitHub Actions?
After running parts_spec.rb
, I get those two tests failing.
test_multibyte_file_length
expected: == 187
got: 186
./spec/parts_spec.rb:34:in `assert_part_length'
./spec/parts_spec.rb:76:in `block (2 levels) in <top (required)>'
test_multibyte_filename
Errno::EINVAL: Invalid argument @ rb_sysopen - C:/Users/parteau/AppData/Local/Temp/ファイル
20170803-137124-14setfh
./spec/parts_spec.rb:81:in `new'
./spec/parts_spec.rb:81:in `block (2 levels) in <top (required)>'
-e:1:in `load'
-e:1:in `<main>'
OS : Windows Version 10.0.14393
Ruby : ruby 2.3.0p0
Running the tests with the released 1.1.3 gem causes an error because the multibyte.txt file isn't included in the gem.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.