Skip to content

Commit 1a80eeb

Browse files
committed
feat: enhance PUT request handler to support multipart uploads
1 parent 0a89592 commit 1a80eeb

1 file changed

Lines changed: 43 additions & 10 deletions

File tree

src/webdav/handlers/PUT.handler.ts

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { DriveFileItem, DriveFolderItem } from '../../types/drive.types';
1111
import { DriveFolderService } from '../../services/drive/drive-folder.service';
1212
import { TrashService } from '../../services/drive/trash.service';
1313
import { EncryptionVersion } from '@internxt/sdk/dist/drive/storage/types';
14+
import { CLIUtils } from '../../utils/cli.utils';
1415

1516
export class PUTRequestHandler implements WebDavMethodHandler {
1617
constructor(
@@ -68,19 +69,50 @@ export class PUTRequestHandler implements WebDavMethodHandler {
6869

6970
const { user } = await authService.getAuthDetails();
7071

71-
let lastLoggedProgress = 0;
72-
const [uploadPromise] = await networkFacade.uploadFromStream(user.bucket, user.mnemonic, contentLength, req, {
73-
progressCallback: (progress) => {
74-
const percentage = Math.floor(100 * progress);
72+
const timer = CLIUtils.timer();
73+
74+
const minimumMultipartThreshold = 100 * 1024 * 1024;
75+
const useMultipart = contentLength > minimumMultipartThreshold;
76+
const partSize = 30 * 1024 * 1024;
77+
const parts = Math.ceil(contentLength / partSize);
78+
79+
let uploadOperation: Promise<
80+
[
81+
Promise<{
82+
fileId: string;
83+
hash: Buffer;
84+
}>,
85+
AbortController,
86+
]
87+
>;
88+
89+
const progressCallback = (progress: number) => {
90+
webdavLogger.info(`[PUT] Upload progress for file ${resource.name}: ${progress}%`);
91+
};
92+
93+
if (useMultipart) {
94+
uploadOperation = networkFacade.uploadMultipartFromStream(user.bucket, user.mnemonic, contentLength, req, {
95+
parts,
96+
progressCallback,
97+
});
98+
} else {
99+
uploadOperation = networkFacade.uploadFromStream(user.bucket, user.mnemonic, contentLength, req, {
100+
progressCallback,
101+
});
102+
}
103+
104+
const [uploadPromise, abortable] = await uploadOperation;
75105

76-
if (percentage >= lastLoggedProgress + 1) {
77-
lastLoggedProgress = percentage;
78-
webdavLogger.info(`[PUT] Upload progress for file ${resource.name}: ${percentage}%`);
79-
}
80-
},
106+
let uploaded = false;
107+
res.on('close', () => {
108+
if (!uploaded) {
109+
webdavLogger.info('[PUT] ❌ HTTP Client has been disconnected, res has been closed.');
110+
abortable.abort('HTTP Client has been disconnected.');
111+
}
81112
});
82113

83114
const uploadResult = await uploadPromise;
115+
uploaded = true;
84116

85117
webdavLogger.info('[PUT] ✅ File uploaded to network');
86118

@@ -95,7 +127,8 @@ export class PUTRequestHandler implements WebDavMethodHandler {
95127
name: '',
96128
});
97129

98-
webdavLogger.info('[PUT] ✅ File uploaded to internxt drive');
130+
const uploadTime = timer.stop();
131+
webdavLogger.info(`[PUT] ✅ File uploaded in ${uploadTime}ms to Internxt Drive`);
99132

100133
await driveDatabaseManager.createFile(file, resource.path.dir + '/');
101134

0 commit comments

Comments
 (0)