Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/services/drive/drive-file.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,32 @@ export class DriveFileService {
return driveFileItem;
};

public replaceFile = async (uuid: string, payload: StorageTypes.FileEntryByUuid): Promise<DriveFileItem> => {
const storageClient = SdkManager.instance.getStorage();
const driveFile = await storageClient.replaceFile(uuid, {
fileId: payload.fileId ?? '',
size: payload.size,
});

const driveFileItem: DriveFileItem = {
itemType: 'file',
name: driveFile.plainName ?? driveFile.name,
uuid: driveFile.uuid,
size: driveFile.size,
bucket: driveFile.bucket,
createdAt: new Date(driveFile.createdAt),
updatedAt: new Date(driveFile.updatedAt),
fileId: driveFile.fileId ?? null,
type: driveFile.type ?? null,
status: driveFile.status as DriveFileItem['status'],
folderUuid: driveFile.folderUuid,
creationTime: new Date(driveFile.creationTime ?? driveFile.createdAt),
modificationTime: new Date(driveFile.modificationTime ?? driveFile.updatedAt),
};

return driveFileItem;
};

private readonly createDriveFileEntry = async (
payload: StorageTypes.FileEntryByUuid,
): Promise<StorageTypes.DriveFileData> => {
Expand Down
32 changes: 24 additions & 8 deletions src/webdav/handlers/PUT.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@ export class PUTRequestHandler implements WebDavMethodHandler {
webdavLogger.info(
`[PUT] File '${resource.name}' already exists in '${resource.path.dir}', it will be replaced...`,
);
try {
await WebDavUtils.deleteOrTrashItem(driveFileItem);
await DriveItemRepository.instance.delete([driveFileItem.uuid]);
} catch {
//noop
}
}

const { user } = await AuthService.instance.getAuthDetails();
Expand Down Expand Up @@ -104,15 +98,37 @@ export class PUTRequestHandler implements WebDavMethodHandler {
}

const driveTimer = CLIUtils.timer();
const file = await DriveFileService.instance.createFile({
const filePayload = {
plainName: resource.path.name,
type: fileType,
size: contentLength,
folderUuid: parentDriveFolderItem.uuid,
fileId,
bucket,
encryptVersion: EncryptionVersion.Aes03,
});
};

let file;
if (driveFileItem?.itemType === 'file' && contentLength > 0) {
try {
file = await DriveFileService.instance.replaceFile(driveFileItem.uuid, filePayload);
} catch (error) {
webdavLogger.warn(
`[PUT] File replace failed for '${resource.url}', falling back to delete and create: ${
error instanceof Error ? error.message : String(error)
}`,
);
await WebDavUtils.deleteOrTrashItem(driveFileItem);
await DriveItemRepository.instance.delete([driveFileItem.uuid]);
file = await DriveFileService.instance.createFile(filePayload);
}
} else {
if (driveFileItem?.itemType === 'file') {
await WebDavUtils.deleteOrTrashItem(driveFileItem);
await DriveItemRepository.instance.delete([driveFileItem.uuid]);
}
file = await DriveFileService.instance.createFile(filePayload);
}
timings.driveUpload = driveTimer.stop();

await DriveItemRepository.instance.createOrUpdate([
Expand Down
14 changes: 12 additions & 2 deletions test/webdav/handlers/PUT.handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ describe('PUT request handler', () => {
.mockResolvedValue(UserCredentialsFixture);
const uploadStub = vi.spyOn(networkFacade, 'uploadFile').mockResolvedValue('uploaded-file-id');
const createDriveFileStub = vi.spyOn(DriveFileService.instance, 'createFile').mockResolvedValue(fileFixture);
const replaceDriveFileStub = vi.spyOn(DriveFileService.instance, 'replaceFile').mockResolvedValue(fileFixture);

await sut.handle(request, response);
expect(response.status).toHaveBeenCalledWith(204);
Expand All @@ -176,7 +177,16 @@ describe('PUT request handler', () => {
expect(getDriveFolderFromResourceStub).toHaveBeenCalledOnce();
expect(getAuthDetailsStub).toHaveBeenCalledOnce();
expect(uploadStub).toHaveBeenCalledOnce();
expect(createDriveFileStub).toHaveBeenCalledOnce();
expect(deleteDriveFileStub).toHaveBeenCalledOnce();
expect(replaceDriveFileStub).toHaveBeenCalledWith(
fileFixture.uuid,
expect.objectContaining({
fileId: 'uploaded-file-id',
folderUuid: folderFixture.uuid,
plainName: requestedFileResource.path.name,
size: 100,
}),
);
expect(createDriveFileStub).not.toHaveBeenCalled();
expect(deleteDriveFileStub).not.toHaveBeenCalled();
});
});
Loading