-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(s3): support copy/delete/get/head object APIs (#11515)
* fix(s3): add URL polyfill for react-native
- Loading branch information
1 parent
835b74f
commit 3e2c1a9
Showing
15 changed files
with
2,066 additions
and
182 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
packages/storage/__tests__/AwsClients/S3/cases/copyObject.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { copyObject } from '../../../../src/AwsClients/S3'; | ||
import { ApiFunctionalTestCase } from '../../testUtils/types'; | ||
import { | ||
defaultConfig, | ||
DEFAULT_RESPONSE_HEADERS, | ||
expectedMetadata, | ||
} from './shared'; | ||
|
||
// API Reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html | ||
const copyObjectHappyCase: ApiFunctionalTestCase<typeof copyObject> = [ | ||
'happy case', | ||
'copyObject', | ||
copyObject, | ||
defaultConfig, | ||
{ | ||
Bucket: 'bucket', | ||
CopySource: 'sourceBucket/sourceKey', // TODO: test with encoded source key | ||
Key: 'key', | ||
CacheControl: 'cacheControl', | ||
ContentType: 'contentType', | ||
ACL: 'acl', | ||
ServerSideEncryption: 'serverSideEncryption', | ||
SSECustomerAlgorithm: 'sseCustomerAlgorithm', | ||
SSECustomerKey: 'sseCustomerKey', | ||
SSECustomerKeyMD5: 'sseCustomerKeyMD5', | ||
SSEKMSKeyId: 'sseKMSKeyId', | ||
}, | ||
expect.objectContaining({ | ||
url: expect.objectContaining({ | ||
href: 'https://bucket.s3.us-east-1.amazonaws.com/key', | ||
}), | ||
method: 'PUT', | ||
headers: expect.objectContaining({ | ||
'x-amz-copy-source': 'sourceBucket/sourceKey', | ||
'cache-control': 'cacheControl', | ||
'content-type': 'contentType', | ||
'x-amz-acl': 'acl', | ||
'x-amz-server-side-encryption': 'serverSideEncryption', | ||
'x-amz-server-side-encryption-customer-algorithm': 'sseCustomerAlgorithm', | ||
'x-amz-server-side-encryption-customer-key': 'sseCustomerKey', | ||
'x-amz-server-side-encryption-customer-key-md5': 'sseCustomerKeyMD5', | ||
'x-amz-server-side-encryption-aws-kms-key-id': 'sseKMSKeyId', | ||
}), | ||
}), | ||
{ | ||
status: 200, | ||
headers: DEFAULT_RESPONSE_HEADERS, | ||
body: | ||
'<CopyObjectResult>' + | ||
'<ETag>string</ETag>' + | ||
'<LastModified>timestamp</LastModified>' + | ||
'<ChecksumCRC32>string</ChecksumCRC32>' + | ||
'<ChecksumCRC32C>string</ChecksumCRC32C>' + | ||
'<ChecksumSHA1>string</ChecksumSHA1>' + | ||
'<ChecksumSHA256>string</ChecksumSHA256>' + | ||
'</CopyObjectResult>', | ||
}, | ||
{ | ||
$metadata: expect.objectContaining(expectedMetadata), | ||
}, | ||
]; | ||
|
||
export default [copyObjectHappyCase]; |
38 changes: 38 additions & 0 deletions
38
packages/storage/__tests__/AwsClients/S3/cases/deleteObject.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { deleteObject } from '../../../../src/AwsClients/S3'; | ||
import { ApiFunctionalTestCase } from '../../testUtils/types'; | ||
import { | ||
defaultConfig, | ||
DEFAULT_RESPONSE_HEADERS, | ||
expectedMetadata, | ||
} from './shared'; | ||
|
||
// API Reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html | ||
const deleteObjectHappyCase: ApiFunctionalTestCase<typeof deleteObject> = [ | ||
'happy case', | ||
'deleteObject', | ||
deleteObject, | ||
defaultConfig, | ||
{ | ||
Bucket: 'bucket', | ||
Key: 'key', | ||
}, | ||
expect.objectContaining({ | ||
url: expect.objectContaining({ | ||
href: 'https://bucket.s3.us-east-1.amazonaws.com/key', | ||
}), | ||
method: 'DELETE', | ||
}), | ||
{ | ||
status: 200, | ||
headers: DEFAULT_RESPONSE_HEADERS, | ||
body: '', | ||
}, | ||
{ | ||
$metadata: expect.objectContaining(expectedMetadata), | ||
}, | ||
]; | ||
|
||
export default [deleteObjectHappyCase]; |
184 changes: 184 additions & 0 deletions
184
packages/storage/__tests__/AwsClients/S3/cases/getObject.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { getObject } from '../../../../src/AwsClients/S3'; | ||
import { ApiFunctionalTestCase } from '../../testUtils/types'; | ||
import { | ||
defaultConfig, | ||
DEFAULT_RESPONSE_HEADERS, | ||
expectedMetadata, | ||
EMPTY_SHA256, | ||
} from './shared'; | ||
|
||
const getObjectResponseHeaders = { | ||
'x-amz-delete-marker': 'true', | ||
'accept-ranges': 'types', | ||
'x-amz-expiration': | ||
'expiry-date="Fri, 23 Dec 2012 00:00:00 GMT", rule-id="picture-deletion-rule"', | ||
'x-amz-restore': | ||
'ongoing-request="false", expiry-date="Fri, 21 Dec 2012 00:00:00 GMT"', // Ref: https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html#AmazonS3-HeadObject-response-header-Restore | ||
'last-modified': 'Sun, 1 Jan 2006 12:00:00 GMT', | ||
'content-length': '434234', | ||
etag: 'fba9dede5f27731c9771645a39863328', | ||
'x-amz-checksum-crc32': '696e1637', | ||
'x-amz-checksum-crc32c': '028A5A90', | ||
'x-amz-checksum-sha1': '5f3446f6cb2f4962082dfe2d298d1b1a32a21b21', | ||
'x-amz-checksum-sha256': | ||
'1643577c036c1e057505b4dce59f3d34bd3fe6224f1064c80dd5426b27a12360', | ||
'x-amz-missing-meta': '2', | ||
'x-amz-version-id': '3HL4kqtJlcpXroDTDmjVBH40Nrjfkd', | ||
'cache-control': 'no-store', | ||
'content-disposition': 'attachment', | ||
'content-encoding': 'zip', | ||
'content-language': 'en-US', | ||
'content-range': 'bytes 0-9/443', | ||
'content-type': 'text/plain', | ||
expires: 'Thu, 01 Dec 1994 16:00:00 GMT', | ||
'x-amz-website-redirect-location': 'http://www.example.com/', | ||
'x-amz-server-side-encryption': 'aws:kms', | ||
'x-amz-server-side-encryption-customer-algorithm': 'AES256', | ||
'x-amz-server-side-encryption-customer-key-md5': 'ZjQrne1X/iTcskbY2m3example', | ||
'x-amz-server-side-encryption-aws-kms-key-id': '12345keyId', | ||
'x-amz-server-side-encryption-bucket-key-enabled': 'true', | ||
'x-amz-storage-class': 'STANDARD', | ||
'x-amz-request-charged': 'requester', | ||
'x-amz-replication-status': 'COMPLETE', | ||
'x-amz-mp-parts-count': '100', | ||
'x-amz-tagging-count': '100', | ||
'x-amz-object-lock-mode': 'COMPLIANCE', | ||
'x-amz-object-lock-retain-until-date': 'Fri, 23 Dec 2012 00:00:00 GMT', | ||
'x-amz-object-lock-legal-hold': 'ON', | ||
// metadata | ||
'x-amz-meta-param1': 'value 1', | ||
'x-amz-meta-param2': 'value 2', | ||
} as const; | ||
|
||
// API Reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html | ||
const getObjectHappyCase: ApiFunctionalTestCase<typeof getObject> = [ | ||
'happy case', | ||
'getObject', | ||
getObject, | ||
defaultConfig, | ||
{ | ||
Bucket: 'bucket', | ||
Key: 'key', | ||
ResponseCacheControl: 'ResponseCacheControl', | ||
ResponseContentDisposition: 'ResponseContentDisposition', | ||
ResponseContentEncoding: 'ResponseContentEncoding', | ||
ResponseContentLanguage: 'ResponseContentLanguage', | ||
ResponseContentType: 'ResponseContentType', | ||
SSECustomerAlgorithm: 'SSECustomerAlgorithm', | ||
SSECustomerKey: 'SSECustomerKey', | ||
SSECustomerKeyMD5: 'SSECustomerKeyMD5', | ||
}, | ||
expect.objectContaining({ | ||
url: expect.objectContaining({ | ||
href: 'https://bucket.s3.us-east-1.amazonaws.com/key?response-cache-control=ResponseCacheControl&response-content-disposition=ResponseContentDisposition&response-content-encoding=ResponseContentEncoding&response-content-language=ResponseContentLanguage&response-content-type=ResponseContentType', | ||
}), | ||
method: 'GET', | ||
headers: expect.objectContaining({ | ||
authorization: expect.stringContaining('Signature'), | ||
host: 'bucket.s3.us-east-1.amazonaws.com', | ||
'x-amz-server-side-encryption-customer-algorithm': 'SSECustomerAlgorithm', | ||
'x-amz-server-side-encryption-customer-key': 'SSECustomerKey', | ||
'x-amz-server-side-encryption-customer-key-md5': 'SSECustomerKeyMD5', | ||
'x-amz-content-sha256': EMPTY_SHA256, | ||
'x-amz-date': expect.stringMatching(/^\d{8}T\d{6}Z/), | ||
'x-amz-user-agent': expect.stringContaining('aws-amplify'), | ||
}), | ||
}), | ||
{ | ||
status: 200, | ||
// all header names are already lowercased by transfer handlers | ||
headers: { | ||
...DEFAULT_RESPONSE_HEADERS, | ||
...getObjectResponseHeaders, | ||
}, | ||
body: 'mockBody', | ||
}, | ||
{ | ||
DeleteMarker: true, | ||
AcceptRanges: 'types', | ||
Expiration: getObjectResponseHeaders['x-amz-expiration'], | ||
Restore: getObjectResponseHeaders['x-amz-restore'], | ||
LastModified: new Date(getObjectResponseHeaders['last-modified']), | ||
ContentLength: Number(getObjectResponseHeaders['content-length']), | ||
ETag: getObjectResponseHeaders.etag, | ||
ChecksumCRC32: getObjectResponseHeaders['x-amz-checksum-crc32'], | ||
ChecksumCRC32C: getObjectResponseHeaders['x-amz-checksum-crc32c'], | ||
ChecksumSHA1: getObjectResponseHeaders['x-amz-checksum-sha1'], | ||
ChecksumSHA256: getObjectResponseHeaders['x-amz-checksum-sha256'], | ||
MissingMeta: Number(getObjectResponseHeaders['x-amz-missing-meta']), | ||
VersionId: getObjectResponseHeaders['x-amz-version-id'], | ||
CacheControl: getObjectResponseHeaders['cache-control'], | ||
ContentDisposition: getObjectResponseHeaders['content-disposition'], | ||
ContentEncoding: getObjectResponseHeaders['content-encoding'], | ||
ContentLanguage: getObjectResponseHeaders['content-language'], | ||
ContentRange: getObjectResponseHeaders['content-range'], | ||
ContentType: getObjectResponseHeaders['content-type'], | ||
Expires: new Date(getObjectResponseHeaders.expires), | ||
WebsiteRedirectLocation: | ||
getObjectResponseHeaders['x-amz-website-redirect-location'], | ||
ServerSideEncryption: | ||
getObjectResponseHeaders['x-amz-server-side-encryption'], | ||
SSECustomerAlgorithm: | ||
getObjectResponseHeaders[ | ||
'x-amz-server-side-encryption-customer-algorithm' | ||
], | ||
SSECustomerKeyMD5: | ||
getObjectResponseHeaders['x-amz-server-side-encryption-customer-key-md5'], | ||
SSEKMSKeyId: | ||
getObjectResponseHeaders['x-amz-server-side-encryption-aws-kms-key-id'], | ||
BucketKeyEnabled: true, | ||
StorageClass: getObjectResponseHeaders['x-amz-storage-class'], | ||
RequestCharged: getObjectResponseHeaders['x-amz-request-charged'], | ||
ReplicationStatus: getObjectResponseHeaders['x-amz-replication-status'], | ||
PartsCount: Number(getObjectResponseHeaders['x-amz-mp-parts-count']), | ||
TagCount: Number(getObjectResponseHeaders['x-amz-tagging-count']), | ||
ObjectLockMode: getObjectResponseHeaders['x-amz-object-lock-mode'], | ||
ObjectLockRetainUntilDate: new Date( | ||
getObjectResponseHeaders['x-amz-object-lock-retain-until-date'] | ||
), | ||
ObjectLockLegalHoldStatus: | ||
getObjectResponseHeaders['x-amz-object-lock-legal-hold'], | ||
Metadata: { | ||
param1: 'value 1', | ||
param2: 'value 2', | ||
}, | ||
Body: expect.objectContaining({ | ||
text: expect.any(Function), | ||
blob: expect.any(Function), | ||
json: expect.any(Function), | ||
}), | ||
$metadata: expect.objectContaining(expectedMetadata), | ||
}, | ||
]; | ||
|
||
const getObjectAccelerateEndpoint: ApiFunctionalTestCase<typeof getObject> = [ | ||
'happy case', | ||
'getObject with accelerate endpoint', | ||
getObject, | ||
{ | ||
...defaultConfig, | ||
useAccelerateEndpoint: true, | ||
} as Parameters<typeof getObject>[0], | ||
{ | ||
Bucket: 'bucket', | ||
Key: 'key', | ||
}, | ||
expect.objectContaining({ | ||
url: expect.objectContaining({ | ||
href: 'https://bucket.s3-accelerate.amazonaws.com/key', | ||
}), | ||
}), | ||
{ | ||
status: 200, | ||
headers: DEFAULT_RESPONSE_HEADERS, | ||
body: 'mockBody', | ||
}, | ||
expect.objectContaining({ | ||
/** skip validating response */ | ||
}) as any, | ||
]; | ||
|
||
export default [getObjectHappyCase, getObjectAccelerateEndpoint]; |
58 changes: 58 additions & 0 deletions
58
packages/storage/__tests__/AwsClients/S3/cases/headObject.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { headObject } from '../../../../src/AwsClients/S3'; | ||
import { ApiFunctionalTestCase } from '../../testUtils/types'; | ||
import { | ||
defaultConfig, | ||
DEFAULT_RESPONSE_HEADERS, | ||
expectedMetadata, | ||
} from './shared'; | ||
|
||
// API Reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html | ||
const headObjectHappyCase: ApiFunctionalTestCase<typeof headObject> = [ | ||
'happy case', | ||
'headObject', | ||
headObject, | ||
defaultConfig, | ||
{ | ||
Bucket: 'bucket', | ||
Key: 'key', | ||
SSECustomerAlgorithm: 'sseCustomerAlgorithm', | ||
SSECustomerKey: 'sseCustomerKey', | ||
SSECustomerKeyMD5: 'sseCustomerKeyMD5', | ||
}, | ||
expect.objectContaining({ | ||
url: expect.objectContaining({ | ||
href: 'https://bucket.s3.us-east-1.amazonaws.com/key', | ||
}), | ||
method: 'HEAD', | ||
headers: expect.objectContaining({ | ||
'x-amz-server-side-encryption-customer-algorithm': 'sseCustomerAlgorithm', | ||
'x-amz-server-side-encryption-customer-key': 'sseCustomerKey', | ||
'x-amz-server-side-encryption-customer-key-md5': 'sseCustomerKeyMD5', | ||
}), | ||
}), | ||
{ | ||
status: 200, | ||
headers: { | ||
...DEFAULT_RESPONSE_HEADERS, | ||
'content-length': '434234', | ||
'content-type': 'text/plain', | ||
etag: 'etag', | ||
'last-modified': 'Sun, 1 Jan 2006 12:00:00 GMT', | ||
'x-amz-version-id': 'versionId', | ||
}, | ||
body: '', | ||
}, | ||
{ | ||
$metadata: expect.objectContaining(expectedMetadata), | ||
ContentLength: 434234, | ||
ContentType: 'text/plain', | ||
ETag: 'etag', | ||
LastModified: new Date('Sun, 1 Jan 2006 12:00:00 GMT'), | ||
VersionId: 'versionId', | ||
}, | ||
]; | ||
|
||
export default [headObjectHappyCase]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.