From 6a40fdd4357b7d8b5814cf83a10af5764cf5bf7d Mon Sep 17 00:00:00 2001 From: Administrator Date: Sun, 19 Apr 2026 22:43:17 +0200 Subject: [PATCH] fix(vidmoly): correct multipart fields & JSON response shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Captured the real browser upload POST and compared to our request. Two corrections: - The file field is named 'file', not 'file_0'. The XFS-indexed naming was a bad guess — the current transit accepts only 'file'. - The form also needs 'to_json=1' (forces JSON response instead of an HTML redirect page, matching what the browser submits) and 'fld_id=0' (destination folder, 0 = root). Dropped upload_type, srv_tmp_url, utype — those were XFS remnants and aren't part of the current server's contract. - Response shape is now { status: 'OK', file_code, msg } instead of the older { files: [...] } / { result: ... } XFS variants; the parser handles all three plus carries the server's msg forward on explicit rejections. --- lib/vidmoly-upload.js | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/lib/vidmoly-upload.js b/lib/vidmoly-upload.js index 25ebbbe..bdcc6c1 100644 --- a/lib/vidmoly-upload.js +++ b/lib/vidmoly-upload.js @@ -141,9 +141,10 @@ class VidmolyUploader { } return { uploadUrl: payload.upload_url, - // Classic XFS upload fields in the order the server expects. - params: { upload_type: 'file', sess_id: payload.sess_id, srv_tmp_url: '', utype: 'reg' }, - fileFieldName: 'file_0' + // Fields verified from a real browser POST capture. + // to_json=1 forces a JSON response instead of an HTML redirect page. + params: { sess_id: payload.sess_id, to_json: '1', fld_id: '0' }, + fileFieldName: 'file' }; } @@ -244,28 +245,33 @@ class VidmolyUploader { resultHtml = await body.text(); } - // Try JSON first (some XFS versions return JSON) + // Try JSON first. The current transit server returns + // { status: "OK", file_code: "...", msg: "Upload Completed" }. + // Legacy XFS shapes (json.files / json.result) are kept as fallback. try { const json = JSON.parse(resultHtml); + if (json.status && /ok/i.test(json.status) && json.file_code) { + return this._buildUrlsFromCode(json.file_code); + } + if (json.file_code || json.filecode) { + return this._buildUrlsFromCode(json.file_code || json.filecode); + } if (json.files && json.files.length > 0) { const f = json.files[0]; - const code = f.filecode || f.file_code; - return { - download_url: code ? `${BASE_URL}/w/${code}` : null, - embed_url: code ? `${BASE_URL}/embed-${code}.html` : null, - file_code: code - }; + return this._buildUrlsFromCode(f.filecode || f.file_code); } if (json.result) { const r = Array.isArray(json.result) ? json.result[0] : json.result; const code = r.filecode || r.file_code; - return { - download_url: r.download_url || (code ? `${BASE_URL}/w/${code}` : null), - embed_url: r.embed_url || (code ? `${BASE_URL}/embed-${code}.html` : null), - file_code: code - }; + const urls = this._buildUrlsFromCode(code); + if (urls) return urls; } - } catch {} + if (json.status && !/ok/i.test(json.status) && json.msg) { + throw new Error(`Vidmoly Upload abgelehnt: ${json.msg}`); + } + } catch (err) { + if (err && /Vidmoly Upload abgelehnt/.test(err.message)) throw err; + } try { return this._parseUploadResult(resultHtml);