Reputation: 3226
I use AWS S3 with presigned urls both for uploading (putObject
) and downloading (getObject
).
I noticed that the generated urls to load pdfs are downloaded instead of being displayed in the _blank
target. I tracked it down to the fact that my s3 objects have a metadata field ContentType
set to application/x-www-form-urlencoded
instead of application/pdf
as I requested. It works when I manually change the content type metadata on S3.
The code used to generate the presigned putObject
url is this:
console.log("presigning with ", fileInput);
/* Will print something like:
presigning with [Object: null prototype] {
name: 'myFile.pdf',
mimetype: 'application/pdf',
size: 321528
}
*/
const { name, size, mimetype } = fileInput
const signedUrlExpireSeconds = 60 * 60
let data = {}
const key = "articles/" + Date.now().toString() + ".pdf"
let params = {
Bucket: 'mybucket',
Key: key,
Expires: signedUrlExpireSeconds,
ContentType: mimetype
};
data.url = await uploadToS3(params)// what I will use to upload from the client browser
export const uploadToS3 = (params) => {
AWS.config.update({
accessKeyId: process.env.S3ACCESSKEYID,
secretAccessKey: process.env.S3SECRETACCESSKEY,
region: process.env.S3REGION
});
var s3 = new AWS.S3();
return s3.getSignedUrlPromise('putObject', params);
}
The generated url contains indeed the content type option like follows (truncated url):
https://mybucket.s3.eu-west-3.amazonaws.com/articles/1582299553999.pdf?Content-Type=application%2Fpdf&X-Amz-Algorithm......
However, when I try to display my pdf in a _blank
tab, the browser downloads it because of the faulty application/x-www-form-urlencoded
content type set during the S3 upload.
I assume the getObject
presigned url is ok since it works when I manually update on S3 the content type of the file.
Am I missing something with the upload?
UPDATE
I wondered if maybe it was related to the axios put request made on the basis of the presigned url. Based on this issue comments, I managed to get the proper content type.
However, The pdf does not load because the favicon is not available... There is 2 network call, one for the pdf that ok with 304, and one for a favicon that gets a 400 bad request on firefox, and a 403 forbidden on chromium. As a consequence (it seems), the pdf file is seen as invalid.
I made the favico file the only public one, but the PDF is still seen as invalid. However, it displays correctly when downloaded.
Upvotes: 4
Views: 3588
Reputation: 902
For everyone's future reference, when sending a presigned URL request, you need to provide the Content-Type in the request, in the axios
, or whatever is your http client. Otherwise it will be given this application/x-www-form-urlencoded
.
That's why when you retrieve with .getObject
, you see the Content-Type
set to application/x-www-form-urlencoded
.
Upvotes: 3