SWFUpload is an open-source Flash 8 embedded application that lets users upload multiple files in a web application. It looked like an easy answer to all of our single-file-uploading woes until we discovered that we couldn’t maintain session state with it.

The problem is that Flash 8 has no way of sending meta data with the uploaded file–for example, who the file belongs to! This is extremely important for us in our iMemoryBook application, since we want uploaded files to be associated with the user’s account–not just a public file repository.

So the culprit (inasmuch as we can’t fix Flash 8 ) appears to be in Ruby’s CGI::Session class: no matter what we tried, it would not pick up the _session_id in the query string when the HTTP request was a POST.

Normally the work-around is quite simple. In a POST-type request, a form is submitted to the server (e.g. a Rails application). In this scenario, we could simply send the _session_id as a hidden field and all would be well.

With Flash 8, however, there is no way to add a ‘hidden field’ to the multi-part form data, thus Rails will fail to recognize the _session_id in the query string portion of our request.

Tracking things down was the hard part. The hackish work-around wasn’t so bad:


# The following code is a work-around for the
# Flash 8 bug that prevents our multiple file uploader
# from sending the _session_id.  Here, we hack the
# Session#initialize method and force the session_id
# to load from the query string via the request uri.
# (Tested on Lighttpd)

class CGI::Session
  alias original_initialize initialize
  def initialize(request, option = {})
    session_key = option['session_key'] || '_session_id'
    option['session_id'] =
      request.env_table["REQUEST_URI"][0..-1].
      scan(/#{session_key}=(.*?)(&.*?)*$/).
      flatten.first
    original_initialize(request, option)
  end
end

Put the above code in your environment.rb file, or separate it out as a file in your lib directory and include it.

This code is also available at my favorite snippet place, BigBold’s snippets directory.

Update: The above code doesn’t work on Mongrel/Apache, so I’ve modified it and uploaded the new code here.