简体   繁体   中英

XML error completing a multi-part upload to S3 with AWS SDK for JavaScript v3

A multi-part upload to S3 is divided in 3 steps:

  • Initiate the multi-part upload
  • Upload parts
  • Complete the multi-part upload

Using AWS SDK for JavaScript v3 (exactly v3.22), the first two steps are successful:

  • The UploadId comes from the initialisation.
  • Each part upload comes with its ETag needed to complete the upload.

The issue comes requesting the upload completion, that is done with:

  const completeParams: CompleteMultipartUploadCommandInput = {
    Bucket,
    Key,
    UploadId,
    MultipartUpload: { Parts },
  };
  return client.send(new CompleteMultipartUploadCommand(completeParams));

Where Parts is an array of valid CompletedPart objects sorted by PartNumber .

Analysing the network call, the request is done to

https://{Bucket}.s3.{Location}.scw.cloud/{Key}?uploadId={UploadId}&x-id=CompleteMultipartUpload

Note: replaced sensible data with placeholders, but they are the expected values.

And the body generated by the AWS SDK is:

<?xml version="1.0" encoding="UTF-8"?>
<CompletedMultipartUpload xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Part>
    <ETag>&quot;610c4...&quot;</ETag>
    <PartNumber>1</PartNumber>
  </Part>
  <Part>
    <ETag>&quot;2edb4...&quot;</ETag>
    <PartNumber>2</PartNumber>
  </Part>
</CompletedMultipartUpload>

Note: showing just the first 5 chars of each ETag to show that they are different and came from uploading parts.

But the answer from S3 is:

The XML you provided was not well-formed or did not validate against our published schema.

Sequence of calls: 在此处输入图片说明

Reading the extensive documentation , there is a subtle difference: the root element of the XML should be CompleteMultipartUpload instead of CompletedMultipartUpload , but the XML is generated by the AWS SDK and I would expect it to be right.

What could be wrong?

Issue

This is an open issue at aws-sdk-js-v3 official repository.

The error is, indeed, a typo on a XML element. It must be CompleteMultipartUpload instead of CompletedMultipartUpload (extra d ).

Workaround

Using a middleware that replaces the invalid XML tag, like this:

const patchS3CompleteMultipartUpload = (client: S3Client): void => {
  client.middlewareStack.add(
    (next, _context) => (args: any) => {
      if ('string' === typeof args.request?.body && args.request.body.includes('CompletedMultipartUpload')) {
        args.request.body = args.request.body.replace(/CompletedMultipartUpload/g, 'CompleteMultipartUpload');
      }
      return next(args);
    },
    {
      step: 'build',
      priority: 'high',
    }
  );
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM