in packages/storage/src/providers/AWSS3Provider.ts [496:629]
public put<T extends S3ProviderPutConfig>(
key: string,
object: PutObjectCommandInput['Body'],
config?: T
): S3ProviderPutOutput<T> {
const opt = Object.assign({}, this._config, config);
const { bucket, track, progressCallback, level, resumable } = opt;
const {
contentType,
contentDisposition,
contentEncoding,
cacheControl,
expires,
metadata,
tagging,
acl,
} = opt;
const {
serverSideEncryption,
SSECustomerAlgorithm,
SSECustomerKey,
SSECustomerKeyMD5,
SSEKMSKeyId,
} = opt;
const type = contentType ? contentType : 'binary/octet-stream';
const params: PutObjectCommandInput = {
Bucket: bucket,
Key: key,
Body: object,
ContentType: type,
};
if (cacheControl) {
params.CacheControl = cacheControl;
}
if (contentDisposition) {
params.ContentDisposition = contentDisposition;
}
if (contentEncoding) {
params.ContentEncoding = contentEncoding;
}
if (expires) {
params.Expires = expires;
}
if (metadata) {
params.Metadata = metadata;
}
if (tagging) {
params.Tagging = tagging;
}
if (serverSideEncryption) {
params.ServerSideEncryption = serverSideEncryption;
}
if (SSECustomerAlgorithm) {
params.SSECustomerAlgorithm = SSECustomerAlgorithm;
}
if (SSECustomerKey) {
params.SSECustomerKey = SSECustomerKey;
}
if (SSECustomerKeyMD5) {
params.SSECustomerKeyMD5 = SSECustomerKeyMD5;
}
if (SSEKMSKeyId) {
params.SSEKMSKeyId = SSEKMSKeyId;
}
const emitter = new events.EventEmitter();
const uploader = new AWSS3ProviderManagedUpload(params, opt, emitter);
if (acl) {
params.ACL = acl;
}
if (resumable === true) {
const s3Client = this._createNewS3Client(opt);
// we are using aws sdk middleware to inject the prefix to key, this way we don't have to call
// this._ensureCredentials() which allows us to make this function sync so we can return non-Promise like UploadTask
s3Client.middlewareStack.add(
createPrefixMiddleware(opt, key),
prefixMiddlewareOptions
);
const addTaskInput: AddTaskInput = {
bucket,
key,
s3Client,
file: object as Blob,
emitter,
accessLevel: level,
params,
};
// explicitly asserting the type here as Typescript could not infer that resumable is of type true
return this.startResumableUpload(
addTaskInput,
config as typeof config & { resumable: true }
) as S3ProviderPutOutput<T>;
}
try {
if (progressCallback) {
if (typeof progressCallback === 'function') {
emitter.on(SEND_UPLOAD_PROGRESS_EVENT, progress => {
progressCallback(progress);
});
} else {
logger.warn(
'progressCallback should be a function, not a ' +
typeof progressCallback
);
}
}
return uploader.upload().then(response => {
logger.debug('upload result', response);
dispatchStorageEvent(
track,
'upload',
{ method: 'put', result: 'success' },
null,
`Upload success for ${key}`
);
return { key };
}) as S3ProviderPutOutput<T>;
} catch (error) {
logger.warn('error uploading', error);
dispatchStorageEvent(
track,
'upload',
{ method: 'put', result: 'failed' },
null,
`Error uploading ${key}`
);
throw error;
}
}