Why is this SWFUpload -> Presigned Post to S3 setup not working? (Rails)

I am trying to do a presigned post to S3 with SWFUpload and AWS-SDK. Long story short, it's not working.

I set up SWFUpload thusly (pardon the coffeescript):

@swfu = new SWFUpload
         flash_url: "<%= asset_path 'swfupload.swf' %>"
         file_size_limit: "1000 MB"
         file_types: "*.mp3"
         debug: true
         upload_url: "http://<%= configatron.aws.cms.bucket %>.s3.amazonaws.com"
         button_placeholder_id : "SWFUploadButton"
         button_action: SWFUpload.BUTTON_ACTION.SELECT_FILE
         button_width: '112'
         button_height: '33'
         button_text: '<button class="orange-button">Upload MP3s</button>',
         button_cursor : SWFUpload.CURSOR.HAND
         http_success : [201, 303, 200]
         file_post_name: "file"
         file_queued_handler: (data) =>

When a file is queued, this is run:

  url: '/uploads/new'
  data: { key: file.name, bucket: '<%= configatron.aws.cms.bucket %>' }
  success: (data) =>

/uploads/new points to a controller which returns JSON, in the end, from this line, using the aws-sdk gem (I've snipped some bits about instantiating the bucket):

  policy = bucket.presigned_post key: key, success_action_status: 201, acl: 'public-read'
  render json: policy

A sample JSON response looks like this:


Back in javascript land, armed with a signature, I take this response and add the parameters to SWFUpload:

upload: (data) ->
  @swfu.setPostParams data
  console.log "uploading...."

SWFUpload's console then tells me that Amazon is unhappy with my signature process (or so I assume, as whatever magic SWFUpload does means that the POST itself does not appear in Chrome's inspector, denying me a more direct look at what is being posted):

SWF DEBUG: Event: fileQueued : File ID: SWFUpload_0_0
SWF DEBUG: Event: fileDialogComplete : Finished processing selected files. Files selected: 1. Files Queued: 1
SWF DEBUG: StartUpload: First file in queue
SWF DEBUG: Event: uploadStart : File ID: SWFUpload_0_0
SWF DEBUG: Global Post Item: signature=signature
SWF DEBUG: Global Post Item: acl=public-read
SWF DEBUG: Global Post Item: AWSAccessKeyId=MY_KEY_ID
SWF DEBUG: Global Post Item: key=blutrotermond.mp3
SWF DEBUG: Global Post Item: success_action_status=201
SWF DEBUG: Global Post Item: policy=MY_ENCODED_POLICY
SWF DEBUG: ReturnUploadStart(): File accepted by startUpload event and readied for upload.  Starting upload to http://my-bucket.s3.amazonaws.com for File ID: SWFUpload_0_0
SWF DEBUG: Event: uploadProgress (OPEN): File ID: SWFUpload_0_0
SWF DEBUG: Event: uploadProgress: File ID: SWFUpload_0_0. Bytes: 490792. Total: 2167327
SWF DEBUG: Event: uploadProgress: File ID: SWFUpload_0_0. Bytes: 2167327. Total: 2167327
SWF DEBUG: Event: uploadError: HTTP ERROR : File ID: SWFUpload_0_0. HTTP Status: 403.
SWF DEBUG: Event: uploadComplete : Upload cycle complete.

I've gotten down into the guts of AWS-SDK, and this is what the policy is, and what's being signed. It seems right to me.


So I'm unsure how to further debug this; SWFUpload hides things from me and I'm not sure what's wrong with my post parameters/signature. Any help would be appreciated.


You can debug the Amazon response with WireShark.

The first thing I've seen is you don't have "x-amz-meta-uuid" parameter posted to Amazon. You can check this PHP example and port it to Ruby. Actually I did on .NET and works perfect.

The answer turned out to be that Flash adds a field to all post uploads, requiring adjustments to the parameters signed in the post. I added support for this field to the aws-sdk gem, and voila.

For debugging, it's possible to get an error response out of AWS by inspecting the exceptions that the aws-sdk throws with a little more detail. The actual Net::HTTP response is in there somewhere, and that had a descriptive error message that the exception messages themselves were swallowing.

See https://github.com/amazonwebservices/aws-sdk-for-ruby/pull/43 for the code that added support for this to aws-sdk, and a quick example of the field to add to the post parameters.

Need Your Help

How can I serialize an object array server side using c#?

c# ajax json serialization webforms

I need to return an object array from server side. How can I serialize the example below so that it looks like that using c# and webforms?

Javascript: Understanding function syntax and parameters

javascript jquery bootstrap-multiselect

I am trying to make sense of the onchange event of bootstrap-multiselect. In particular, I am trying to understand the function syntax and parameters.