import {PutObjectCommand} from "@aws-sdk/client-s3"; import Base from './base' import {S3ClientHttpRequestHandler} from "../utils/S3ClientHttpRequestHandler"; import {createXHR} from "../utils"; import {QiniuError, QiniuErrorName} from "../errors"; export default class Direct extends Base { protected async run() { this.logger.info('start run Direct.') const xhr = createXHR() const requestHandler = new S3ClientHttpRequestHandler(xhr) this.addXhr(xhr); requestHandler.onProgress$.subscribe(progress => { this.updateDirectProgress(progress.progressEvent.loaded, progress.progressEvent.total) }); this.s3Client.config.requestHandler = requestHandler const res = await this.s3Client.send(new PutObjectCommand({ Body: this.file, Bucket: this.bucketName, Key: this.key })); const metadata = res.$metadata; if (metadata && metadata.httpStatusCode != 200) { throw new QiniuError(QiniuErrorName.RequestError, '上传文件失败'); } this.logger.info('Direct progress finish.') this.finishDirectProgress() } private updateDirectProgress(loaded: number, total: number) { // 当请求未完成时可能进度会达到100,所以total + 1来防止这种情况出现 this.progress = {total: this.getProgressInfoItem(loaded, total + 1)} this.onData(this.progress) } private finishDirectProgress() { // 在某些浏览器环境下,xhr 的 progress 事件无法被触发,progress 为 null,这里 fake 下 if (!this.progress) { this.logger.warn('progress is null.') this.progress = {total: this.getProgressInfoItem(this.file.size, this.file.size)} this.onData(this.progress) return } const {total} = this.progress this.progress = {total: this.getProgressInfoItem(total.loaded + 1, total.size)} this.onData(this.progress) } }