Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

s3.getSignedUrl ResponseContentDisposition parameter not working

I'm successfully generating a signed url that I can then use for a limited time to download resources from my s3 bucket. However I'm trying to use the ResponseContentDisposition attribute in the params as documented here:

  1. http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
  2. http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property

I'm not sure if I'm doing this wrong but for some reason the headers are not being set. For example if I use the url I get back from s3.getSignedUrl:

curl -i "https://foo-dev.s3.amazonaws.com/images/foo.jpg?AWSAccessKeyId=AKIAICBHUC26S6B446PQ&Expires=1468359314&Signature=EeBqx1G83oeusarBl2KUbbCCBgA%3D&response-content-disposition=attachment%3B%20filename%3Ddata.jpg"

the headers are:

x-amz-id-2: SG9rjYQCcuqgKfjBmMbDQC2CNLcnqBAFzP7zINa99VYUwNijPOm5Ea/5fllZ6cnt/Qti7e26hbE=
x-amz-request-id: 2670068008525B1D
Date: Tue, 12 Jul 2016 21:26:16 GMT
Content-Disposition: inline; filename=foo.jpg
Last-Modified: Tue, 12 Jul 2016 00:47:23 GMT
ETag: "2a8e36651b24769170f4faa429f40f54"
Accept-Ranges: bytes
Content-Type: image/jpeg
Content-Length: 43373
Server: AmazonS3

I'm setting this, using the javascript s3 sdk like this:

function tempRedirect(req, res) {
    var filename = req.params[0];
    var contentDisposition = 'attachment; filename=data.jpg';
    var params = {
        Bucket: S3_BUCKET,
        ResponseContentDisposition: contentDisposition,
        Key: checkTrailingSlash(getFileKeyDir(req)) + filename
    };
    var s3 = new aws.S3(s3Options);
    s3.getSignedUrl('getObject', params, function(err, url) {
        res.redirect(url);
    });
};

The docs are pretty light and I can only find PHP examples but it does look like I'm setting content disposition correctly.

Anyone know what is going wrong here??

like image 619
eagspoo Avatar asked Jul 12 '16 21:07

eagspoo


1 Answers

According to RFC- 2616, your value is malformed.

The expected format is attachment; filename="funny-cat.jpg". The filename is a quoted string.

And, my original assumption was that S3 was rejecting it as invalid and silently refusing to replace the value.

Subsequent tests reveal unexpected behavior: if Content-Disposition is not stored with the object, then &response-content-disposition=... works as expected, setting the response header. But if there is a header stored with the object, this query string parameter does not have the documented effect of "overriding" that value.

Conversely, &response-content-type=... does override a stored Content-Type: for the object.

That's what a few quick tests revealed for me.

But this appears to be a bug -- or more accurately, some kind of regression -- in S3. According to one support forum post, the behavior is actually inconsistent, sometimes working and sometimes not.

S3 is aware of this issue and we are working to resolve it. (2016-07-12)

https://forums.aws.amazon.com/thread.jspa?threadID=235006

like image 186
Michael - sqlbot Avatar answered Oct 20 '22 14:10

Michael - sqlbot