ente/src/services/upload/uploadHttpClient.ts

151 lines
4.5 KiB
TypeScript
Raw Normal View History

import HTTPService from 'services/HTTPService';
import { getEndpoint } from 'utils/common/apiUtil';
import { getToken } from 'utils/common/key';
import { logError } from 'utils/sentry';
2021-08-11 08:00:59 +00:00
import { UploadFile, UploadURL } from './uploadService';
import { File } from '../fileService';
import { CustomError } from 'utils/common/errorUtil';
import { retryAsyncFunction } from 'utils/network';
import { MultipartUploadURLs } from './multiPartUploadService';
const ENDPOINT = getEndpoint();
const MAX_URL_REQUESTS = 50;
class UploadHttpClient {
2021-08-11 04:46:06 +00:00
private uploadURLFetchInProgress = null;
2021-08-11 04:46:06 +00:00
async uploadFile(uploadFile: UploadFile): Promise<File> {
try {
const token = getToken();
if (!token) {
return;
}
2021-08-11 04:46:06 +00:00
const response = await retryAsyncFunction(() =>
HTTPService.post(`${ENDPOINT}/files`, uploadFile, null, {
'X-Auth-Token': token,
2021-08-13 03:38:02 +00:00
})
2021-08-11 04:46:06 +00:00
);
return response.data;
} catch (e) {
logError(e, 'upload Files Failed');
throw e;
}
}
2021-08-11 04:46:06 +00:00
async fetchUploadURLs(count: number, urlStore: UploadURL[]): Promise<void> {
try {
if (!this.uploadURLFetchInProgress) {
try {
const token = getToken();
if (!token) {
return;
}
this.uploadURLFetchInProgress = HTTPService.get(
`${ENDPOINT}/files/upload-urls`,
{
2021-08-11 04:46:06 +00:00
count: Math.min(MAX_URL_REQUESTS, count * 2),
},
2021-08-13 03:38:02 +00:00
{ 'X-Auth-Token': token }
);
const response = await this.uploadURLFetchInProgress;
urlStore.push(...response.data['urls']);
} finally {
this.uploadURLFetchInProgress = null;
}
}
return this.uploadURLFetchInProgress;
} catch (e) {
logError(e, 'fetch upload-url failed ');
throw e;
}
}
async fetchMultipartUploadURLs(
2021-08-13 03:38:02 +00:00
count: number
): Promise<MultipartUploadURLs> {
try {
const token = getToken();
if (!token) {
return;
}
const response = await HTTPService.get(
`${ENDPOINT}/files/multipart-upload-urls`,
{
count,
},
2021-08-13 03:38:02 +00:00
{ 'X-Auth-Token': token }
);
return response.data['urls'];
} catch (e) {
logError(e, 'fetch multipart-upload-url failed');
throw e;
}
}
async putFile(
fileUploadURL: UploadURL,
file: Uint8Array,
2021-08-13 03:38:02 +00:00
progressTracker
): Promise<string> {
try {
2021-08-11 04:46:06 +00:00
await retryAsyncFunction(() =>
HTTPService.put(
fileUploadURL.url,
file,
null,
null,
2021-08-13 03:38:02 +00:00
progressTracker
)
);
return fileUploadURL.objectKey;
} catch (e) {
logError(e, 'putFile to dataStore failed ');
throw e;
}
}
2021-08-09 15:15:11 +00:00
async putFilePart(
partUploadURL: string,
filePart: Uint8Array,
2021-08-13 03:38:02 +00:00
progressTracker
) {
try {
2021-08-11 04:46:06 +00:00
const response = await retryAsyncFunction(async () => {
const resp = await HTTPService.put(
2021-08-09 15:15:11 +00:00
partUploadURL,
filePart,
null,
null,
2021-08-13 03:38:02 +00:00
progressTracker
2021-08-09 15:15:11 +00:00
);
if (!resp?.headers?.etag) {
2021-08-11 04:46:06 +00:00
const err = Error(CustomError.ETAG_MISSING);
2021-08-09 15:15:11 +00:00
logError(err);
throw err;
}
2021-08-09 15:15:11 +00:00
return resp;
});
return response.headers.etag as string;
2021-08-09 15:15:11 +00:00
} catch (e) {
logError(e, 'put filePart failed');
throw e;
}
}
2021-08-11 04:46:06 +00:00
async completeMultipartUpload(completeURL: string, reqBody: any) {
2021-08-09 15:15:11 +00:00
try {
2021-08-11 04:46:06 +00:00
await retryAsyncFunction(() =>
2021-08-09 15:15:11 +00:00
HTTPService.post(completeURL, reqBody, null, {
'content-type': 'text/xml',
2021-08-13 03:38:02 +00:00
})
);
} catch (e) {
logError(e, 'put file in parts failed');
throw e;
}
}
}
2021-08-09 15:15:11 +00:00
export default new UploadHttpClient();