fix: Bug - Sending files between users doesn't really work
Stream oversized generic attachments to disk instead of silently dropping chunks, avoid loading completed file downloads into renderer memory, and surface a clear error when the browser client cannot receive a file. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+34
-6
@@ -9,13 +9,20 @@ import { AttachmentStorageService } from '../../infrastructure/services/attachme
|
||||
import { MAX_AUTO_SAVE_SIZE_BYTES } from '../../domain/constants/attachment.constants';
|
||||
import { isImageAttachment, resolvePublishAttachmentIsImage } from '../../domain/logic/attachment-image.rules';
|
||||
import { isSharingFromThisDevice } from '../../domain/logic/attachment-sharing.rules';
|
||||
import { shouldCopyUploaderMediaToAppData, shouldPersistDownloadedAttachment } from '../../domain/logic/attachment.logic';
|
||||
import {
|
||||
canReceiveAttachment,
|
||||
isAttachmentMedia,
|
||||
shouldCopyUploaderMediaToAppData,
|
||||
shouldPersistDownloadedAttachment,
|
||||
shouldStreamAttachmentReceiveToDisk
|
||||
} from '../../domain/logic/attachment.logic';
|
||||
import type { Attachment, AttachmentMeta } from '../../domain/models/attachment.model';
|
||||
import {
|
||||
ATTACHMENT_TRANSFER_EWMA_CURRENT_WEIGHT,
|
||||
ATTACHMENT_TRANSFER_EWMA_PREVIOUS_WEIGHT,
|
||||
DEFAULT_ATTACHMENT_MIME_TYPE,
|
||||
ATTACHMENT_DOWNLOAD_FAILED_KEY,
|
||||
ATTACHMENT_FILE_TOO_LARGE_KEY,
|
||||
ATTACHMENT_CHUNKS_OUT_OF_ORDER_KEY,
|
||||
ATTACHMENT_OPEN_DOWNLOAD_FAILED_KEY,
|
||||
ATTACHMENT_PREPARE_DOWNLOAD_FAILED_KEY,
|
||||
@@ -188,6 +195,13 @@ export class AttachmentTransferService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canReceiveAttachment(attachment, this.receiveCapabilities())) {
|
||||
this.runtimeStore.deletePendingRequest(requestKey);
|
||||
attachment.requestError = this.appI18n.instant(ATTACHMENT_FILE_TOO_LARGE_KEY);
|
||||
this.runtimeStore.touch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (clearedRequestError)
|
||||
this.runtimeStore.touch();
|
||||
|
||||
@@ -344,7 +358,9 @@ export class AttachmentTransferService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.shouldReceiveToDisk(attachment) && attachment.size > MAX_AUTO_SAVE_SIZE_BYTES) {
|
||||
if (!canReceiveAttachment(attachment, this.receiveCapabilities())) {
|
||||
attachment.requestError = this.appI18n.instant(ATTACHMENT_FILE_TOO_LARGE_KEY);
|
||||
this.runtimeStore.touch();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -784,10 +800,14 @@ export class AttachmentTransferService {
|
||||
}
|
||||
|
||||
private shouldReceiveToDisk(attachment: Attachment): boolean {
|
||||
return this.isPlayableMedia(attachment) &&
|
||||
!attachment.filePath &&
|
||||
this.attachmentStorage.canStreamToDisk() &&
|
||||
this.attachmentStorage.canPersistSize(attachment.size);
|
||||
return shouldStreamAttachmentReceiveToDisk(attachment, this.receiveCapabilities());
|
||||
}
|
||||
|
||||
private receiveCapabilities() {
|
||||
return {
|
||||
canStreamToDisk: this.attachmentStorage.canStreamToDisk(),
|
||||
canPersistSize: (bytes: number) => this.attachmentStorage.canPersistSize(bytes)
|
||||
};
|
||||
}
|
||||
|
||||
private enqueueDiskFileChunk(
|
||||
@@ -851,6 +871,14 @@ export class AttachmentTransferService {
|
||||
|
||||
attachment.savedPath = assembly.path;
|
||||
|
||||
if (!isAttachmentMedia(attachment)) {
|
||||
attachment.available = true;
|
||||
this.diskReceiveAssemblies.delete(assemblyKey);
|
||||
this.runtimeStore.touch();
|
||||
void this.persistence.persistAttachmentMeta(attachment);
|
||||
return;
|
||||
}
|
||||
|
||||
const restoredForDisplay = await this.persistence.ensureInlineDisplayObjectUrl(attachment);
|
||||
|
||||
if (!restoredForDisplay) {
|
||||
|
||||
Reference in New Issue
Block a user