Multipart POST in Ruby

In Merb is the new black Josh Susser mentions:

I also wrote a little client command line script in Ruby that wraps curl to upload the files to the web service. (I had to use curl because Ruby doesn’t have a simple solution for doing multipart file uploads.)

I ran into this once, and ended up writing a solution (for essentially the same problem) as a Multipart module. It’s ugly but functional, and almost all borrowed from here and Bill Stilwell.

One Response to “Multipart POST in Ruby”

  1. Keith Says:

    Someone asked me how this actually gets used. Here’s a quick example:

    
      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 
    
        # my server expects the params of the POST to
        # use the rails-like "blah[bar]” syntax, and I
        # need to send two things other than the file
        # itself. These are stored in the params Hash
        params = Hash.new
    
        # Open the actually file I want to send
        file = File.open(filename, “rb”)
    
        # set the params to meaningful values
        params["file[new_file]“] = file
        params["file[abc_filename]“] = abc_filename
        params["xyz"] = xyz
    
        # make a MultipartPost
        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)
    
        # done with file now
        file.close
    
        # Make sure the URL is useable
        url = URI.parse(URL)
    
        # Do the actual POST, given the right inputs
        res = post_form(url, query, headers)
    
        # res holds the response to the POST
        case res
        when Net::HTTPSuccess
          puts “Hooray”
        when Net::HTTPInternalServerError
          raise “Server blew up”
        else
          raise “Unknown error #{res}: #{res.inspect}”
        end
    

Leave a Reply

You must be logged in to post a comment.