Cesse de demander au serveur une couverture qui n'existe pas
La mise en cache retombait sur le relais dès que la tentative directe n'était pas « ok », sans distinguer « je n'ai pas pu demander » de « on m'a répondu qu'il n'y a rien ». Un 404 est une réponse : le relais irait chercher la même URL et ne peut pas faire mieux. D'où deux 404 par vignette manquante sur la bibliographie d'un auteur, à chaque affichage puisque rien ne se met alors en cache — et dont le second venait de notre propre serveur, qui refuse par construction une URL absente de la base. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1887,6 +1887,34 @@ Les suivre reste sûr précisément parce que le garde est **à la connexion** :
|
|||||||
chaque saut, cible de redirection comprise. C'est la position du garde, et non l'interdiction de
|
chaque saut, cible de redirection comprise. C'est la position du garde, et non l'interdiction de
|
||||||
rediriger, qui ferme le SSRF. Bornées à 3 sauts.
|
rediriger, qui ferme le SSRF. Bornées à 3 sauts.
|
||||||
|
|
||||||
|
### ⚠️ Le relais ne rattrape qu'un accès EMPÊCHÉ, jamais une image absente (2026-08-22)
|
||||||
|
|
||||||
|
Constaté en console sur la bibliographie d'un auteur : **deux 404 par vignette manquante**, dont
|
||||||
|
un de *notre* serveur. Le second n'apprenait rien et ne pouvait rien apprendre.
|
||||||
|
|
||||||
|
`couvertureMettreEnCache` retombait sur le relais dès que la tentative directe n'était pas `ok`
|
||||||
|
— sans distinguer **« je n'ai pas pu demander »** de **« on m'a répondu qu'il n'y a rien »**. Or
|
||||||
|
un 404 est une réponse : l'hôte a parlé, et le relais ira chercher la **même** URL. Il ne peut
|
||||||
|
par construction pas faire mieux.
|
||||||
|
|
||||||
|
Le cas se produit à chaque affichage, et pas une fois pour toutes : rien ne se met en cache
|
||||||
|
quand l'image n'existe pas, donc la paire de 404 revient à chaque rendu. Et sur une
|
||||||
|
bibliographie, l'URL n'est de toute façon **jamais** en base — le garde du relais la refuse par
|
||||||
|
construction, ce qui rend le second appel doublement vain.
|
||||||
|
|
||||||
|
Le repli sur le relais est donc réservé à un **échec de la requête** (CORS, hôte injoignable) ou
|
||||||
|
à un statut qui n'est pas un refus définitif. `404` et `410` s'arrêtent là.
|
||||||
|
|
||||||
|
⚠️ **Ce qui n'est PAS un défaut, et qu'il ne faut pas « corriger »** : le 404 d'OpenLibrary
|
||||||
|
lui-même. `?default=false` existe précisément pour l'obtenir franc plutôt qu'une image
|
||||||
|
d'attente, et `onerror` fait apparaître le substitut à initiale. Une couverture inexistante
|
||||||
|
**doit** produire un 404 en console.
|
||||||
|
|
||||||
|
Vérifié en exécution, magasin `couvertures` vidé au préalable : sur une bibliographie de
|
||||||
|
47 œuvres, une couverture absente ne produit plus qu'un seul appel (celui d'OpenLibrary), une
|
||||||
|
couverture existante d'œuvre **non possédée** se range bien en cache, et l'unique appel au relais
|
||||||
|
— l'hébergeur sans CORS — répond **200**.
|
||||||
|
|
||||||
### L'ordre des tentatives, côté client
|
### L'ordre des tentatives, côté client
|
||||||
|
|
||||||
`couvertureMettreEnCache` tente **d'abord l'URL directe** — elle profite du cache HTTP du
|
`couvertureMettreEnCache` tente **d'abord l'URL directe** — elle profite du cache HTTP du
|
||||||
|
|||||||
@@ -125,7 +125,16 @@ export async function couvertureMettreEnCache(url) {
|
|||||||
// Bloqué par le CORS, ou hôte injoignable : on ne sait pas lequel, et peu importe.
|
// Bloqué par le CORS, ou hôte injoignable : on ne sait pas lequel, et peu importe.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reponse || !reponse.ok) {
|
// ⚠️ Le relais ne rattrape QU'UN ACCÈS EMPÊCHÉ, jamais une image absente. Un 404 (ou un
|
||||||
|
// 410) est une réponse : l'hôte a parlé, et il a dit qu'il n'avait rien — or le relais
|
||||||
|
// ira chercher la MÊME url, il ne peut donc pas faire mieux. L'appeler quand même
|
||||||
|
// produit un second 404, de notre serveur cette fois, sur toute couverture
|
||||||
|
// qu'OpenLibrary ne connaît pas (« ?default=false » les rend franches, c'est voulu).
|
||||||
|
// C'est ce qui se voyait en console sur la bibliographie d'un auteur, à chaque
|
||||||
|
// affichage puisque rien ne se met jamais en cache.
|
||||||
|
const absente = reponse !== null && (reponse.status === 404 || reponse.status === 410);
|
||||||
|
|
||||||
|
if (!absente && (!reponse || !reponse.ok)) {
|
||||||
reponse = await fetch('/api/couvertures?url=' + encodeURIComponent(url));
|
reponse = await fetch('/api/couvertures?url=' + encodeURIComponent(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user