Erik A. Hanson's Weblog

Testing File Uploads To A Rack Server

Posted: March 28th, 2009    Tags: Howto, Ruby

I wrote a web app on top of Rack that includes the ability to accept file uploads. It took some time to figure out how to successfully test the file upload using Rack::Test.

The trick was to encode the file exactly correctly, and then post it with the correct headers. I wrote a simple post_file method to do this.

  def post_file(url, param_name, file_path, content_type)
    file_name = File.basename(file_path)
    boundary = "AaB03x"
    data = "--#{boundary}\r\n" +
           "Content-Disposition: form-data; name=\"#{param_name}\"; filename=\"#{file_name}\"\r\n" +
           "Content-Type: #{content_type}\r\n" +
           "\r\n" +
           "#{File.read(file_path)}\r\n" +
           "--#{boundary}--\r\n" +
           "\r\n"
    post(url, {}, {
      "CONTENT_TYPE" => "multipart/form-data, boundary=\"#{boundary}\"",
      "CONTENT_LENGTH" => data.length, :input => data })
  end

I call it from my test like this:

...
post_file("/my_app/upload", "uploaded_image", "../test-images/originals/loki.jpg", "image/jpeg")
...

and my app reads it like this:

...
request = Rack::Request.new(env)
...
uploaded_image = request.params["uploaded_image"][:tempfile]
...


2 Responses to “Testing File Uploads To A Rack Server”

  1. Logan Koester Says:

    A solution similar to this has been officially implemented as Rack::Test::UploadedFile

    Example:
    post “/photos”, “file” => Rack::Test::UploadedFile.new(“me.jpg”, “image/jpeg”)

    http://gitrdoc.com/rdoc/brynary/rack-test/6d8c25af8592faf2efb3f5ab73b0219eadf30ea4/classes/Rack/Test/UploadedFile.html

  2. Erik Says:

    Nice!

Leave a Reply



(Comments are moderated to keep out spam. Please be patient.)