AWS getSignedUrl with UploadId and PartNumber

714 Views Asked by At

I'm trying to convert the following JS into PHP:

client.getSignedUrl('uploadPart', {
    Bucket: config.bucket,
    Key: key,
    UploadId: uploadId,
    PartNumber: partNumber,
    Body: '',
    Expires: ms('5 minutes') / 1000
}, (err, url) => {
    if (err) {
        next(err)
        return
    }
    res.json({ url })
})

Here's the origin

I'm not able to find an equivalent for PHP in the AWS docs, and I also cannot find where "UploadId" and "PartNumber" are referenced in the AWS docs for the JS.

Does anyone know what I may be missing?


I'm trying to create a multipart upload using AWS S3. I'm not sure if this is the missing piece, but I believe it is.

If I upload a large file purely PHP side using the AWS multipart upload, it works. What I need to do though is move the upload process client-side. In order to do that, I need a pre-signed URL to upload to.

The code snippet above is from the Uppy companion controller. I'm pretty sure it generates a pre-signed URL with some data such as the UploadId and PartNumber. I've not been able to find a way to do this server-side/PHP.

This generates a URL and I'm able to upload to it, but I don't think it's adding the UploadId and PartNumber:

$cmd = $client->getCommand('PutObject', [
    'Bucket'        => 'bucket-name',
    'Key'           => $key,
    'UploadId'      => $uploadId, // I didn't see a ref to this in the docs
    'PartNumber'    => $partNumber, // Or this.
]);

When I try to complete the upload after uploading the parts using the pre-signed URL using this code:

$result = $client->completeMultipartUpload([
    'Bucket'          => 'bucket-name',
    'Key'             => $key,
    'UploadId'        => $uploadId,
    'MultipartUpload' => [
        'Parts' => $parts,
    ],
]);

I get the following error:

"Error executing "CompleteMultipartUpload" on "https://bucket-name.s3.amazonaws.com/NewProject.png?uploadId=nlWLdbNgB9zgarpLBXnj17eOIGAmQM_xyBArymtwdM71fhbFvveggDmL6fz4blz.B95TLhMatDvodbMb5p2ZMKqdlLeLFoSW1qcu33aRQTlt6NbiP_dkDO90DFO.pWGH"; AWS HTTP error: Client error: POST https://bucket-name.s3.amazonaws.com/NewProject.png?uploadId=nlWLdbNgB9zgarpLBXnj17eOIGAmQM_xyBArymtwdM71fhbFvveggDmL6fz4blz.B95TLhMatDvodbMb5p2ZMKqdlLeLFoSW1qcu33aRQTlt6NbiP_dkDO90DFO.pWGH resulted in a 400 Bad Request response: InvalidPartOne or more of the specified parts could not be found. The part may not have be (truncated...) InvalidPart (client): One or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's entity tag. - InvalidPartOne or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's en"

1

There are 1 best solutions below

0
On BEST ANSWER

I found the PHP equivalent.

$command = $client->getCommand('UploadPart', [
    'Bucket'        => 'the-bucket-name',
    'Key'           => $key,
    'PartNumber'    => $partNumber,
    'UploadId'      => $uploadId,
    'Body'          => '',
]);

$presignedUrl = $client->createPresignedRequest($command, '+20 minutes');
$presignedUrlString = (string)$presignedUrl->getUri();