From 48c89713ba985363a126caef49fcdb7e7b53689d Mon Sep 17 00:00:00 2001 From: Sucukdeluxe Date: Sun, 1 Mar 2026 02:00:52 +0100 Subject: [PATCH] Release v1.4.35 with 413 handling for both dcrypt endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Handle 413 from paste endpoint (not just upload) - Show clear German error "DLC-Datei zu groß für dcrypt.it" when both endpoints reject the file due to size - Add tests for dual-413 and upload-413+paste-500 scenarios Co-Authored-By: Claude Opus 4.6 --- package.json | 2 +- src/main/container.ts | 8 +++++++- tests/container.test.ts | 26 +++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 4f60c90..7fc1eac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "real-debrid-downloader", - "version": "1.4.34", + "version": "1.4.35", "description": "Real-Debrid Downloader Desktop (Electron + React + TypeScript)", "main": "build/main/main/main.js", "author": "Sucukdeluxe", diff --git a/src/main/container.ts b/src/main/container.ts index 1b6ba74..6549ee5 100644 --- a/src/main/container.ts +++ b/src/main/container.ts @@ -190,7 +190,7 @@ async function tryDcryptUpload(fileContent: Buffer, fileName: string): Promise { +async function tryDcryptPaste(fileContent: Buffer): Promise { const form = new FormData(); form.set("content", fileContent.toString("ascii")); @@ -198,6 +198,9 @@ async function tryDcryptPaste(fileContent: Buffer): Promise { method: "POST", body: form }); + if (response.status === 413) { + return null; + } const text = await response.text(); if (!response.ok) { throw new Error(compactErrorText(text)); @@ -214,6 +217,9 @@ async function decryptDlcViaDcrypt(filePath: string): Promise { expect(fetchSpy).toHaveBeenCalledTimes(3); }); - it("throws when both dcrypt endpoints fail", async () => { + it("throws when both dcrypt endpoints return 413", async () => { + const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-dlc-")); + tempDirs.push(dir); + const filePath = path.join(dir, "huge.dlc"); + fs.writeFileSync(filePath, Buffer.alloc(100, 1).toString("base64")); + + const fetchSpy = vi.fn(async (url: string | URL | Request) => { + const urlStr = String(url); + if (urlStr.includes("service.jdownloader.org")) { + return new Response("", { status: 404 }); + } + if (urlStr.includes("dcrypt.it/decrypt/upload")) { + return new Response("Request Entity Too Large", { status: 413 }); + } + if (urlStr.includes("dcrypt.it/decrypt/paste")) { + return new Response("Request Entity Too Large", { status: 413 }); + } + return new Response("", { status: 500 }); + }); + globalThis.fetch = fetchSpy as unknown as typeof fetch; + + await expect(importDlcContainers([filePath])).rejects.toThrow(/zu groß für dcrypt/i); + }); + + it("throws when upload returns 413 and paste returns 500", async () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-dlc-")); tempDirs.push(dir); const filePath = path.join(dir, "doomed.dlc");