Skip to content

Instantly share code, notes, and snippets.

@makevoid
Created April 7, 2010 02:08
Show Gist options
  • Save makevoid/358396 to your computer and use it in GitHub Desktop.
Save makevoid/358396 to your computer and use it in GitHub Desktop.
Multipart file upload ruby
# from: http://kfahlgren.com/blog/2006/11/01/multipart-post-in-ruby-2/
# edited by makevoid, http://makevoid.com
URL = "http://localhost:3000/your_url"
TIMEOUT_SECONDS = 10
params = {}
file = File.open(filename, "rb")
params["file[replay]"] = file
# TODO: need auth
mp = Multipart::MultipartPost.new
# Get both the headers and the query ready, given the new MultipartPost and the params Hash
query, headers = mp.prepare_query(params)
file.close
url = URI.parse(URL)
response = post_form(url, query, headers)
case response
when Net::HTTPSuccess
puts "Hooray, got response: #{response.inspect}"
when Net::HTTPInternalServerError
raise "Server blew up"
else
raise "Unknown error: #{response}"
end
#######
def self.post_form(url, query, headers)
Net::HTTP.start(url.host, url.port) {|con|
con.read_timeout = TIMEOUT_SECONDS
begin
return con.post(url.path, query, headers)
rescue => e
puts "POSTING Failed #{e}... #{Time.now}"
end
}
end
module Multipart
# From: http://deftcode.com/code/flickr_upload/multipartpost.rb
## Helper class to prepare an HTTP POST request with a file upload
## Mostly taken from
#http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/113774
### WAS:
## Anything that's broken and wrong probably the fault of Bill Stilwell
##(bill@marginalia.org)
### NOW:
## Everything wrong is due to keith@oreilly.com
require 'rubygems'
require 'mime/types'
require 'net/http'
require 'cgi'
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)}\"\r\n\r\n#{v}\r\n"
# Don't escape mine...
return "Content-Disposition: form-data; name=\"#{k}\"\r\n\r\n#{v}\r\n"
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}\"\r\n" + "Content-Transfer-Encoding: binary\r\n" + "Content-Type: #{MIME::Types.type_for(@filename)}\r\n\r\n" + content + "\r\n "
# Don't escape mine
return "Content-Disposition: form-data; name=\"#{k}\"; filename=\"#{filename}\"\r\n" + "Content-Transfer-Encoding: binary\r\n" + "Content-Type: #{MIME::Types.type_for(@filename)}\r\n\r\n" + content + "\r\n"
end
end
class MultipartPost
BOUNDARY = 'tarsiers-rule0000'
HEADER = {"Content-type" => "multipart/form-data, boundary=" + BOUNDARY + " "}
def prepare_query (params)
fp = []
params.each {|k,v|
if v.respond_to?(:read)
fp.push(FileParam.new(k, v.path, v.read))
else
fp.push(Param.new(k,v))
end
}
query = fp.collect {|p| "--" + BOUNDARY + "\r\n" + p.to_multipart }.join("") + "--" + BOUNDARY + "--"
return query, HEADER
end
end
end
@JosephCastro
Copy link

If I want to add other headers, like User-Agent or Cookie, I just need to add to MultipartPost.HEADER ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment