fix: vidmoly redirect loop, body leak, update error handling, submenu overflow
- Add max redirect depth (10) to Vidmoly _fetch to prevent stack overflow - Drain undici response body on redirect to prevent connection leaks - Fix installUpdate unhandled promise rejection in main.js - Fix context menu submenu viewport overflow with flip-left CSS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9c56fabce1
commit
52b2e0a1e4
@ -45,7 +45,8 @@ class VidmolyUploader {
|
||||
/**
|
||||
* Simple GET/POST using built-in fetch (handles redirects)
|
||||
*/
|
||||
async _fetch(url, opts = {}) {
|
||||
async _fetch(url, opts = {}, _redirectCount = 0) {
|
||||
const MAX_REDIRECTS = 10;
|
||||
const headers = {
|
||||
'User-Agent': USER_AGENT,
|
||||
...(opts.headers || {})
|
||||
@ -64,10 +65,15 @@ class VidmolyUploader {
|
||||
|
||||
// Follow redirects manually (to capture cookies at each hop)
|
||||
if ([301, 302, 303, 307, 308].includes(res.status)) {
|
||||
// Drain body to prevent connection leak
|
||||
try { await res.text(); } catch {}
|
||||
if (_redirectCount >= MAX_REDIRECTS) {
|
||||
throw new Error('Zu viele Redirects');
|
||||
}
|
||||
const location = res.headers.get('location');
|
||||
if (location) {
|
||||
const nextUrl = new URL(location, url).href;
|
||||
return this._fetch(nextUrl, { ...opts, method: 'GET', body: undefined });
|
||||
return this._fetch(nextUrl, { ...opts, method: 'GET', body: undefined }, _redirectCount + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,11 +246,13 @@ class VidmolyUploader {
|
||||
let resultHtml;
|
||||
if ([301, 302, 303].includes(statusCode)) {
|
||||
const location = headers && headers.location;
|
||||
// Always drain the original body to prevent connection leak
|
||||
try { await body.text(); } catch {}
|
||||
if (location) {
|
||||
const resultRes = await this._fetch(new URL(location, uploadUrl).href);
|
||||
resultHtml = await resultRes.text();
|
||||
} else {
|
||||
resultHtml = await body.text();
|
||||
resultHtml = '';
|
||||
}
|
||||
} else {
|
||||
resultHtml = await body.text();
|
||||
|
||||
22
main.js
22
main.js
@ -349,17 +349,17 @@ ipcMain.handle('app:check-updates', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('app:install-update', async () => {
|
||||
try {
|
||||
installUpdate((progress) => {
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
mainWindow.webContents.send('app:update-progress', progress);
|
||||
}
|
||||
});
|
||||
return { started: true };
|
||||
} catch (err) {
|
||||
return { error: err.message };
|
||||
}
|
||||
ipcMain.handle('app:install-update', () => {
|
||||
installUpdate((progress) => {
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
mainWindow.webContents.send('app:update-progress', progress);
|
||||
}
|
||||
}).catch((err) => {
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
mainWindow.webContents.send('app:update-progress', { stage: 'error', error: err.message });
|
||||
}
|
||||
});
|
||||
return { started: true };
|
||||
});
|
||||
|
||||
ipcMain.handle('app:abort-update', () => {
|
||||
|
||||
@ -342,8 +342,14 @@ function showContextMenu(x, y) {
|
||||
if (aotItem) aotItem.textContent = alwaysOnTopState ? 'Immer im Vordergrund ✓' : 'Immer im Vordergrund';
|
||||
|
||||
menu.style.display = 'block';
|
||||
menu.style.left = Math.min(x, window.innerWidth - menu.offsetWidth - 5) + 'px';
|
||||
const menuX = Math.min(x, window.innerWidth - menu.offsetWidth - 5);
|
||||
menu.style.left = menuX + 'px';
|
||||
menu.style.top = Math.min(y, window.innerHeight - menu.offsetHeight - 5) + 'px';
|
||||
|
||||
// Flip submenus if they would overflow the viewport right edge
|
||||
menu.querySelectorAll('.ctx-submenu-items').forEach(sub => {
|
||||
sub.classList.toggle('flip-left', menuX + menu.offsetWidth + sub.offsetWidth > window.innerWidth);
|
||||
});
|
||||
}
|
||||
|
||||
function hideContextMenu() {
|
||||
|
||||
@ -314,8 +314,11 @@ body {
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
min-width: 160px;
|
||||
max-width: calc(100vw - 16px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
/* Flip submenu to the left when it would overflow the viewport */
|
||||
.ctx-submenu-items.flip-left { left: auto; right: 100%; }
|
||||
.ctx-submenu:hover .ctx-submenu-items { display: block; }
|
||||
|
||||
/* Settings View */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user