Search code examples
amazon-s3coldfusioncoldfusion-2016

In ColdFusion, Is it possible to upload files to amazon s3 directly using a scheduled task?


I have to make a scheduled script/cfm that downlaods an image from a certain file location (no problem) and then uploads it to our amazon s3 location (problem). Is this possible and if so how? Downlaod is ok, and file is stored in a temp folder. How do I/can I get this file to Amazon s3?

Sofar I tried :

  1. Store on s3 directly when downloading the file :
<cfhttp method="get" url="#cimage#" path="https://s3-eu-west-1.amazonaws.com/ourfilelocation/" file="#theimage#" />

giving me the erorr 'this is a read-only resource, can't write to it'

  1. First download it to a temp file location and then in a new cfhttp upload to s3 :
<cfhttp method="get" url="#cimage#" path="#tmpfileloc#" file="#theimage#" />
<cfhttp method="post" url="https://s3-eu-west-1.amazonaws.com/ourfilelocation/" path="#tmpfileurl#" file="#theimage#" />

giving me the error '405 Method Not Allowed'

3.

<cffile action="upload" file="#tmpfileurl#/#theimage#" destination="https://s3-eu-west-1.amazonaws.com/ourfilelocation/">

which ofcourse gives me 'no file send with this form' because there is no form

4.

<cfhttp method="post" url="https://s3-eu-west1.amazonaws.com/ourfilelocation"> 
<cfhttpparam type="file" name="#theimage#" file="#tmpfileurl#/#theimage#"> </cfhttp>

giving me 'Connection Failure. Status code unavailable.' I guess you cannot just post to that url, it makes no sense. But I wouldn't know if there is a way in which you could.


Solution

  • It looks like you're trying to save the file to the AWS URL, as opposed to the bucket. You really only want to use those URLs for retrieving files. And, you don't want to use CFHTTP.

    CF has the ability to work with S3 in most of its 'File' operation functions. You'll need to create a user in AWS IAM with access to your S3 buckets and get the AWS AccessKeyID and Secret for that user.

    You didn't mention what version of CF you are using but S3 support has been available since 2016, I believe?

    So, for 2016 and 2018 you can use the FileCopy function and simply use "S3" as your drive letter like so:

    <cfset FileCopy(yourSourceFilePAth,"s3://#awsS3accessKeyId#:#awsS3Secret#@Your/Bucket/Path/Here")>
    

    You then have to set permissions using the storeSetACL() function but that's beyond the scope of the question.

    In addition, there are other ways to set your variables and CF2021 added more capabilities but that's beyond the scope of your question.