Currently, I am working on a Remix app where I have implemented a form to select and upload an image using a simple
<input name="image" type="file" />
The form sends a POST
request to a Remix handler. In the handler (refer to the code below), I am attempting to upload this image to Amazon S3 using the v3 SDK. I have experimented with both the PutObjectCommand
from client-s3
and the Upload
method from lib-storage
, but encountered the same outcome...
The upload process seems to be successful as it creates the file in the bucket without any issues. The file size matches exactly what I expect when compared to uploading the file directly into the S3 bucket via the web UI.
However, when trying to open the uploaded file as an "image", it does not display correctly. When viewing the image from the S3 bucket, the browser shows the standard "broken image icon" (similar issue occurs if attempting to open the image in Preview on OSX) - unfortunately, there isn't much information available about what might be wrong. It appears that something may be corrupted or created in a manner that prevents the file from being recognized as an image.
Within the handler, the file data is received as an AsyncIterable<Uint8Array>
. My main processing task involves converting this data into a single Uint8Array
for the Upload operation (I have already tried setting the body to both buffer and blob with no success).
Could there be an issue with my conversion to a Uint8Array
? Is there a more appropriate way to perform this conversion for the upload operation, perhaps using a different data type?
Alternatively, is there a specific configuration that needs to be adjusted regarding how the upload to S3 is being set up?
async ({ name, contentType, data, filename }) => {
const arrayOfUInt8Array: Uint8Array[] = [];
let length = 0;
for await (const x of data)
{
arrayOfUInt8Array.push(x);
length += x.length;
}
const uInt8Array = new Uint8Array(length);
for (const x of arrayOfUInt8Array) {
uInt8Array.set(x);
}
// Tried creating a buffer from the Uint8Array...
const buff = Buffer.from(uInt8Array);
// Tried creating a blob from the Uint8Array...
const blob = new Blob([uInt8Array], { type: contentType });
const uploadCommand = new Upload({
client: s3Client,
params: {
Bucket: s3Bucket,
Key: filename,
Body: uInt8Array,
ContentType: contentType,
}
});
await uploadCommand.done();
return '';
},