Pergunta

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"
         file_queue_limit:1
         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) =>
           @queued(data)

When a file is queued, this is run:

$.ajax
  url: '/uploads/new'
  data: { key: file.name, bucket: '<%= configatron.aws.cms.bucket %>' }
  success: (data) =>
    @upload(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:

{"AWSAccessKeyId":"MY_KEY_ID",
 "key":"blutrotermond.mp3",
 "policy":"base64-encoded-policy",
 "signature":"the-signature",
 "acl":"public-read",
 "success_action_status":"201"}

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...."
  @swfu.startUpload()

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.

{"expiration":"2012-05-02T19:33:31Z",
 "conditions":[{"bucket":"my-bucket"},
               {"key":"blutrotermond.mp3"},
               {"acl":"public-read"},
               {"success_action_status":"201"}]}

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.

Foi útil?

Solução 2

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.

Outras dicas

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top