ruby multipart http upload

ruby’s stdlib doesn’t provide any class to generate multipart format. Therefore, I refer to this article (Multipart POST in Ruby) from Keigth’s blog to write my Multipart class.

I found that there is some bug in Keigth’s code. This bug causes my ruby program freeze until the connection timeout.
Here are some bugfixs:

change

query = fp.collect {|p| "--" + BOUNDARY + "rn" + p.to_multipart }.join("") + "--" + BOUNDARY + "--"

to

query = fp.collect {|p| "--" + BOUNDARY + "rn" + p.to_multipart }.join("") + "--" + BOUNDARY + "--rn"

and

HEADER = {"Content-type" => "multipart/form-data, boundary=" + BOUNDARY + " "}

to

HEADER = {"Content-type" => "multipart/form-data; boundary=" + BOUNDARY}

Here is My code:


#--
# mostly taken from http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/113774
# refer to http://kfahlgren.com/blog/2006/11/01/multipart-post-in-ruby-2/
# http://deftcode.com/code/flickr_upload/multipartpost.rb
#--

require 'cgi'
require 'net/http'

class Param
  attr_accessor :k, :v
  def initialize( k, v )
    @k = k
    @v = v
  end

  def to_multipart
    return "Content-Disposition: form-data; name="#{CGI::escape(k)}"rnrn#{v}rn"
  end
end

class FileParam
  attr_accessor :k, :filename, :content
  def initialize( k, filename, content )
    @k = k
    @filename = filename
    @content = content
  end

  def to_multipart
    return "Content-Disposition: form-data; name="#{CGI::escape(k)}"; filename="#{filename}"rn" +
          #"Content-Transfer-Encoding: binaryrn" +
          "Content-Type: application/octet-streamrnrn" +
          content + "rn"
   end
end

if __FILE__ == $0 then
  filename = '20491501v001m.doc'
  content = open( filename,"rb") do |f|
    f.read()
  end

  boundary = "-------ruby-311721796827358"
  params = [ #Param.new("action", "Upload"),
              FileParam.new( "fileupload1", filename, content ),
              FileParam.new( "fileupload2", "", "" ),
              FileParam.new( "fileupload3", "", "" ),
              FileParam.new( "fileupload4", "", "" ),
              FileParam.new( "fileupload5", "", "" )
           ]

  query = params.collect { |p|
      "--" + boundary + "rn" + p.to_multipart
    }.join("") + "--" + boundary + "--rn"
    
  http = Net::HTTP.new("192.168.11.4")
  path="/temp/"

  response = http.post( path, query, "Content-type" => "multipart/form-data; boundary=" + boundary)
end

2 則回應給 ruby multipart http upload

  1. After spending some time I came up with a class that works better with big files such as videos.

    The code is here:

    http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

你正使用 WordPress.com 帳號留言。 登出 / 變更 )

Twitter picture

你正使用 Twitter 帳號留言。 登出 / 變更 )

Facebook照片

你正使用 Facebook 帳號留言。 登出 / 變更 )

Google+ photo

你正使用 Google+ 帳號留言。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: