From 91e239bf55979eeec235f6e7871ccc63c51fcb81 Mon Sep 17 00:00:00 2001 From: nig Date: Fri, 15 Nov 2024 15:01:02 +0100 Subject: [PATCH] [desktop] fix not sending Content-Length header in native file upload Co-authored-by: nif --- src/common/desktop/files/DesktopFileFacade.ts | 2 ++ .../desktop/files/DesktopFileFacadeTest.ts | 28 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/common/desktop/files/DesktopFileFacade.ts b/src/common/desktop/files/DesktopFileFacade.ts index 72926f11bcb..bc2cb3b9397 100644 --- a/src/common/desktop/files/DesktopFileFacade.ts +++ b/src/common/desktop/files/DesktopFileFacade.ts @@ -219,6 +219,8 @@ export class DesktopFileFacade implements FileFacade { async upload(fileUri: string, targetUrl: string, method: string, headers: Record): Promise { const fileStream = this.fs.createReadStream(fileUri) + const stat = await this.fs.promises.stat(fileUri) + headers["Content-Length"] = `${stat.size}` const response = await this.net.executeRequest(new URL(targetUrl), { method, headers, timeout: 20000 }, fileStream) let responseBody: Uint8Array diff --git a/test/tests/desktop/files/DesktopFileFacadeTest.ts b/test/tests/desktop/files/DesktopFileFacadeTest.ts index 0fbe76180f4..59cd836ed12 100644 --- a/test/tests/desktop/files/DesktopFileFacadeTest.ts +++ b/test/tests/desktop/files/DesktopFileFacadeTest.ts @@ -36,6 +36,7 @@ o.spec("DesktopFileFacade", function () { fs = object() tfs = object() fs.promises = object() + when(fs.promises.stat(matchers.anything())).thenResolve({ size: 42 }) electron = object() // @ts-ignore read-only prop electron.shell = object() @@ -210,7 +211,13 @@ o.spec("DesktopFileFacade", function () { const fileToUploadPath = "/tutnaota/tmp/path/encrypted/toUpload.txt" const targetUrl = "https://test.tutanota.com/rest/for/a/bit" - function mockResponse(statusCode: number, resOpts: { responseBody?: Uint8Array; responseHeaders?: Record }): http.IncomingMessage { + function mockResponse( + statusCode: number, + resOpts: { + responseBody?: Uint8Array + responseHeaders?: Record + }, + ): http.IncomingMessage { const { responseBody, responseHeaders } = resOpts const response: http.IncomingMessage = object() response.statusCode = statusCode @@ -237,7 +244,17 @@ o.spec("DesktopFileFacade", function () { } const fileStreamMock = mockReadStream() when(fs.createReadStream(fileToUploadPath)).thenReturn(fileStreamMock) - when(net.executeRequest(urlMatches(new URL(targetUrl)), { method: "POST", headers, timeout: 20000 }, fileStreamMock)).thenResolve(response) + when( + net.executeRequest( + urlMatches(new URL(targetUrl)), + { + method: "POST", + headers, + timeout: 20000, + }, + fileStreamMock, + ), + ).thenResolve(response) const uploadResult = await ff.upload(fileToUploadPath, targetUrl, "POST", headers) o(uploadResult.statusCode).equals(200) @@ -332,7 +349,12 @@ o.spec("DesktopFileFacade", function () { o("open on windows", async function () { n.setPlatform("win32") - when(electron.dialog.showMessageBox(matchers.anything())).thenReturn(Promise.resolve({ response: 1, checkboxChecked: false })) + when(electron.dialog.showMessageBox(matchers.anything())).thenReturn( + Promise.resolve({ + response: 1, + checkboxChecked: false, + }), + ) await ff.open("exec.exe") verify(electron.shell.openPath(matchers.anything()), { times: 0 }) })