2

I use the aws-sdk for java to upload a file to s3 (Frankfurt region).

ObjectMetadata omd = new ObjectMetadata();
omd.setContentDisposition("attachment;filename=\"" + someFileNameWithNonASCIIChars + "\"");
...
PutObjectRequest por = new PutObjectRequest(bucket, key, stream, omd);

...

s3Object.putObject(por);

The last line throws a AmazonServiceException stating SignatureDoesNotMatch as the reason:

The request signature we calculated does not match the signature you provided.

This only happens when non-ASCII characters are in the Content-Disposition header value.

I am aware of the workaround for browsers that cannot handle utf-8 encoding decoding:

How to encode the filename parameter of Content-Disposition header in HTTP?

I can use this solution. But is this the intended result from S3? Is there some way to send UTF-8 characters in the Content-Disposition header? And then I can just let the browsers deal with the non-ASCII characters.

Also, using the *=utf-8'' workaround causes spaces to be decoded to "+" signs rather than back to spaces, which isn't ideal. It's explained here.

Thanks.

theyuv
  • 1,556
  • 4
  • 26
  • 55

1 Answers1

4

But is this the intended result from S3?

Unfortunately, it is. A long-standing issue with S3 prevents signatures that are actually correct from being detected as correct when headers contain non-ascii characters, because the service actually calculates the signature incorrectly -- apparently the original design made the assumption that the utf-8 characters shouldn't be there... so utf-8 values can't be used.

For the + issue, just change those to %20 after you do the encoding and they should work. Any actual + in the filename before the encoding will appear in the encoded string as %2B so any remaining + is really a space.

Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427