diff --git a/src/internal/s3.ts b/src/internal/s3.ts index f9debdf..6e5ad77 100644 --- a/src/internal/s3.ts +++ b/src/internal/s3.ts @@ -168,7 +168,11 @@ export class S3Client extends AWSClient { * @throws {S3ServiceError} * @throws {InvalidSignatureError} */ - async getObject(bucketName: string, objectKey: string): Promise { + async getObject( + bucketName: string, + objectKey: string, + additionalHeaders: object = {} + ): Promise { // Prepare request const method = 'GET' @@ -177,13 +181,27 @@ export class S3Client extends AWSClient { method: method, endpoint: this.endpoint, path: encodeURI(`/${bucketName}/${objectKey}`), - headers: {}, + headers: { + ...additionalHeaders, + }, }, {} ) + // If the Accept header is set to 'application/octet-stream', we want to + // return the response as binary data. + let responseType: ResponseType = 'text' + if ( + 'Accept' in additionalHeaders && + additionalHeaders['Accept'] !== undefined && + additionalHeaders['Accept'] === 'application/octet-stream' + ) { + responseType = 'binary' + } + const res = await http.asyncRequest(method, signedRequest.url, null, { headers: signedRequest.headers, + responseType: responseType as ResponseType, }) this._handle_error('GetObject', res) @@ -537,7 +555,7 @@ export class S3Object { etag: string size: number storageClass: StorageClass - data?: string | bytes | null + data?: string | ArrayBuffer | null /** * Create an S3 Object @@ -547,7 +565,7 @@ export class S3Object { * @param {string} etag - S3 object's etag * @param {number} size - S3 object's size * @param {StorageClass} storageClass - S3 object's storage class - * @param {string | bytes | null} data=null - S3 Object's data + * @param {string | ArrayBuffer | null} data=null - S3 Object's data */ constructor( key: string, @@ -555,7 +573,7 @@ export class S3Object { etag: string, size: number, storageClass: StorageClass, - data?: string | bytes | null + data?: string | ArrayBuffer | null ) { this.key = key this.lastModified = lastModified diff --git a/tests/internal/s3.js b/tests/internal/s3.js index 70d2b5b..3c7b26a 100644 --- a/tests/internal/s3.js +++ b/tests/internal/s3.js @@ -73,6 +73,21 @@ export async function s3TestSuite(data) { expect(getNonExistingObjectError).to.be.an.instanceOf(S3ServiceError) }) + await asyncDescribe('s3.getObject [binary]', async (expect) => { + // Act + const gotBinaryObject = await s3Client.getObject( + data.s3.testBucketName, + data.s3.testObjects[0].key, + { Accept: 'application/octet-stream' } + ) + + // Assert + expect(gotBinaryObject).to.be.an('object') + expect(gotBinaryObject.key).to.equal(data.s3.testObjects[0].key) + expect(gotBinaryObject.data).to.be.an('ArrayBuffer') + expect(gotBinaryObject.data.byteLength).to.equal(data.s3.testObjects[0].body.length) + }) + await asyncDescribe('s3.putObject', async (expect) => { // Act let putObectError