1

I'm trying to upload a file to my S3 bucket. Below I've set up my request with credentials. I'm having trouble deducing what should be in the headers and in the body. The secret acces key is within the signature. What am I missing?

  def params
    {
      :key => key_prefix + file_name, 
      :aws_access_key_id => access_key_id,
      :acl => "private",
      :policy => encoded_policy,
      :signature => encoded_signature
    }
  end

  def headers
    {
      "Content-Type" => mime_type,
      "x-amz-security-token" => session_token
    }
  end

  def upload
    connection.post do |req|
      req.headers = headers
      req.body = params.to_json
    end
  end

  def connection
    Faraday.new(:url => bucket_url) do |builder|
      builder.request :multipart
      builder.request :url_encoded
      builder.adapter :typhoeus
    end
  end

The error I receive is:

<Error><Code>PreconditionFailed</Code><Message>At least one of the pre-conditions you 
specified did not hold</Message><Condition>Bucket POST must be of the enclosure-type 
multipart/form-data</Condition>
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
jozwright
  • 99
  • 3
  • 11
  • Is Faraday a strict requirement for your project? Because it would be much simpler to use the AWS gem. – Marco Sandrini Nov 05 '15 at 21:47
  • @MarcoSandrini Yes, Faraday is compulsory. Any help or direction would be appreciated. – jozwright Nov 05 '15 at 23:32
  • If Faraday is the only way to go, then I would recommend looking at the specs for the PUT Object method (http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html), which is slightly simpler than building by hand a multipart POST request. – Marco Sandrini Nov 05 '15 at 23:41

1 Answers1

3

Great question! I ran into the same thing.

The hard part of this in including the file. This seems to work:

  def params
    {
      :key => key_prefix + file_name, 
      :aws_access_key_id => access_key_id,
      :acl => "private",
      :policy => encoded_policy,
      :signature => encoded_signature
      :file => Faraday::UploadIO.new(StringIO.new(<<FILECONTENTS>>), <<MIMETYPE>>)
    }
  end
Todd R
  • 18,236
  • 8
  • 31
  • 39