Copy link to clipboard
Copied
I'm using the Instructure Canvas API for uploading files. After the initial API call, Canvas returns information that is used to make a POST request to Amazon Web Services's S3 service to upload a file.
Here is the request I'm using to post the file to AWS S3, populated with the data returned by the Canvas API:
<cfhttp url="#aws.upload_url#" result="result" method="post" multipart="yes">
<cfhttpparam type="formfield" name="key" value="#aws.upload_params.key#" />
<cfhttpparam type="formfield" name="acl" value="#aws.upload_params.acl#" />
<cfhttpparam type="formfield" name="Filename" value="#photoName#" />
<cfhttpparam type="formfield" name="AWSAccessKeyId" value="#aws.upload_params.AWSAccessKeyId#" />
<cfhttpparam type="formfield" name="Policy" value="#aws.upload_params.Policy#" />
<cfhttpparam type="formfield" name="Signature" value="#aws.upload_params.Signature#" />
<cfhttpparam type="formfield" name="Content-Type" value="#aws.upload_params['content-type']#" />
<cfhttpparam type="formfield" name="success_action_redirect" value="#aws.upload_params['success_action_redirect']#" />
<cfhttpparam type="file" name="file" file="#fullPath#" />
</cfhttp>
This request works on a ColdFusion 9 server (the response returns "200 OK"), but fails on a ColdFusion 10 server (the response returns "500 Internal Server Error"). The Canvas API call works in both cases.
Any ideas or suggestions appreciated.
I set the cfhttp redirect attribute to "no" on both the CF9 and CF10 versions. In both cases, S3 returns a 303 response code with a URL in a location field that looks similar (only the file-specific identifiers inthe query-string differ).
My current solution is to leave the redirect attribute to "no" and send a third HTTP request to get the redirect location (which in this case includes a variety of metadata regarding the successful upload).
Thanks to both Peter and Petro for the suggesstions.
Copy link to clipboard
Copied
Can you add throwonerror=false to the cfhttp tag, and then cfdump the #result# variable - there is probably some more info in the http response besides the 500 internal server error that might help you out.
Copy link to clipboard
Copied
FWIW, why don't you use native API for S3 in CF9/10? Works like a charm.
Copy link to clipboard
Copied
Thanks for the replies. I used cfdump to examine the results, but other than a custom 500 error page, I didn't see anything out of the ordinary.
Using CF's built-in S3 capabilities may work. I haven't used it before and so I was just following the steps provided in Canvas's documentation. I am not positive how to use the data returned from the initial Canvas API call to form the S3 request. I tried the following:
<cffile
action="write"
output="S3 Specifications" file="s3://#jsonData.upload_params.AWSAccessKeyId#:#jsonData.upload_params.policy#@#Replace(jsonData.upload_url,'https://','','ALL')##jsonData.upload_params.key#"/>
Assuming that the returned policy value (a 545-character random string) is the secrect key and that the upload_params_key should be appended to the bucket location (it looks approximately like this: account_XXXXX/attachments/XXXXXXXX/XXXXXXXXXX.jpg). I was getting a SignatureDoesNotMatch error from that request.
Additionally, I tried sending the requests to a basic web server that should capture the request data and write them to a file. It doesn't look like it worked like I expected it to--I'm not sure why neither instance includes all the data--but here are the results in case they are relevant:
CF9:
POST / HTTP/1.1
Host: osric.com:50000
Connection: close, TE
TE: trailers, deflate, gzip, compress
User-Agent: ColdFusion
Accept-Encoding: deflate, gzip, x-gzip, compress, x-compress
Content-type: multipart/form-data; boundary=-----------------------------7d0d117230764
Content-length: 6289
CF10:
POST / HTTP/1.1
User-Agent: ColdFusion
Content-Type: multipart/form-data; boundary=-----------------------------7d0d117230764
Connection: close
Content-Length: 6289
Host: osric.com:50000
-------------------------------7d0d117230764
Content-Disposition: form-data; name="key"
Content-Type: text/plain; charset=UTF-8
account_XXXXX/attachments/XXXXXXXX/XXXXXXXXX.jpg
-------------------------------7d0d117230764
Content-Disposition: form-data; name="acl"
Content-Type: text/plain; charset=UTF-8
private
-------------------------------7d0d117230764
Content-Disposition: form-data; name="Filename"
Content-Type: text/plain; charset=UTF-8
XXXXXXXXX.jpg
-------------------------------7d0d117230764
Content-Disposition: form-data; name="AWSAccessKeyId"
Content-Type: text/plain; charset=UTF-8
XXXXXXXXXXXXXXXXXXXXXX
-------------------------------7d0d117230764
Content-Disposition: form-data; name="Policy"
Content-Type: text/plain; charset=UTF-8
XXXXXXXXXXXXXXXXXXXXX[...lots of characters...]XXXXX
-------------------------------7d0d117230764
Content-Disposition: form-data; name="Signature"
Content-Type: text/plain; charset=UTF-
Copy link to clipboard
Copied
I’d still recommend using built-in features of CF10 for S3. Operations like copy, delete work the same we’ve used to.
e.g.
</cfif
Copy link to clipboard
Copied
One point of clarification: the server error 500 was not returned by the ColdFusion server when performing the chttp call, but as the result of the cfhttp call. That was unclear in my original post.
Also, it appears that the file upload is successful, but that the server is not returning the expected success message when the file is uploaded via CF10 (rather than CF9). This is peculiar, as the correct success_action_redirect
must be passed in order for signature verification to pass.
Copy link to clipboard
Copied
I set the cfhttp redirect attribute to "no" on both the CF9 and CF10 versions. In both cases, S3 returns a 303 response code with a URL in a location field that looks similar (only the file-specific identifiers inthe query-string differ).
My current solution is to leave the redirect attribute to "no" and send a third HTTP request to get the redirect location (which in this case includes a variety of metadata regarding the successful upload).
Thanks to both Peter and Petro for the suggesstions.