fix(favorites): Logo auch fuer Seiten, die es per JavaScript setzen
hosteurope.de liefert im HTML nur einen leeren data:-Platzhalter, das echte Symbol setzt erst JavaScript; /favicon.ico antwortet mit HTML. Die Kachel zeigte deshalb nur den Buchstaben. Scheitert das gespeicherte Symbol, fragt getIconBytes jetzt einmal den DuckDuckGo-Symboldienst - nur fuer oeffentlich erreichbare Seiten, interne Hostnamen verlassen das Haus nicht; kennt der Dienst nichts (404), bleibt es beim Buchstaben. Wirkt auch fuer bestehende Favoriten. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,18 @@ const MAX_REDIRECTS = 2;
|
||||
const MAX_HTML_CHARS = 200000;
|
||||
const MAX_ICON_BYTES = 1_000_000;
|
||||
|
||||
/**
|
||||
* quick-261001-hbi — oeffentlicher Symbol-Dienst als letzter Rueckfall. Manche
|
||||
* Seiten setzen ihr Symbol erst per JavaScript (hosteurope.de: im HTML nur
|
||||
* `<link rel="icon" href="data:;base64,=">`, `/favicon.ico` liefert eine
|
||||
* HTML-Seite) — ohne Browser findet die Suche dort nichts. DuckDuckGo kennt
|
||||
* das gerenderte Symbol und antwortet fuer Unbekanntes mit 404 (dann bleibt
|
||||
* der Buchstabe). Gefragt wird NUR fuer oeffentlich erreichbare Adressen,
|
||||
* damit interne Hostnamen (docuvita.ctl.local, private IPs) das Haus nie
|
||||
* verlassen; der Dienst erfaehrt nur den Hostnamen.
|
||||
*/
|
||||
const PUBLIC_ICON_SERVICE = 'https://icons.duckduckgo.com/ip3/';
|
||||
|
||||
/**
|
||||
* 260917-jdd — Ziel ist ein Bildchen, kein Geheimnis: selbstsignierte,
|
||||
* abgelaufene oder falsch benannte Zertifikate sollen das Symbol eines
|
||||
@@ -426,6 +438,22 @@ export class IconDiscoveryService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* quick-261001-hbi: Symbol fuer die Seite `pageUrl` beim oeffentlichen
|
||||
* Symbol-Dienst holen (siehe PUBLIC_ICON_SERVICE). Wirft, wenn die Seite
|
||||
* nicht oeffentlich erreichbar ist (dann wird der Dienst NICHT gefragt) oder
|
||||
* der Dienst kein Symbol kennt (404) — wie `fetchIconBytes`.
|
||||
*/
|
||||
async fetchPublicServiceIconBytes(
|
||||
pageUrl: string,
|
||||
): Promise<{ contentType: string; body: Buffer }> {
|
||||
const page = new URL(normalizeUrl(pageUrl));
|
||||
if (!(await isPublicHttpUrl(page))) {
|
||||
throw new Error('Page is not public, icon service not asked');
|
||||
}
|
||||
return this.fetchIconBytes(`${PUBLIC_ICON_SERVICE}${page.hostname}.ico`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the raw bytes of a stored icon URL, SSRF-guarded, for streaming
|
||||
* back to the browser from Tessera's own origin (avoids Cross-Origin-
|
||||
|
||||
Reference in New Issue
Block a user