Cache Etag nginx et PHP ?

WRInaute accro
Bonjour

Je suis en train d'arranger le cache de mon Nginx 1.14.2 sous Debian 10.

J'ai mis Expires à 2h et Cache-Control à 7200.


J'ai deux problèmes :

- Le pragma: no-cache qui se glisse dans le header,

- Comment générer un Etag sur du contenu dynamique ( script php ).

Pour l'instant je les génère à la mano mais çà ne marche pas pour le cache.

$Etag = md5($contenu_html);

Je crois qu'il y a un module natif de Nginx pour celà, mais comment l'installer ?

Sinon, voici les en-têtes que j'obtiens.

Merci beaucoup pour votre aide.


Code:
HTTP/2 200
server: nginx/1.14.2
date: Sat, 07 Aug 2021 12:17:36 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
set-cookie: SES=10k2fcebgp695479os8q2frlan; path=/; secure; HttpOnly; SameSite=Strict
expires: Sat, 07 Aug 2021 14:17:36 GMT
cache-control: max-age=7200
pragma: no-cache
etag: /W"aa090ff39cd1aeda709f9c5bf8511377"
vary: User-Agent
strict-transport-security: max-age=31536000; includeSubDomains; preload
 
WRInaute accro
Bonjour

J'ai la méthode pour installer Nginx 1.20.1 et PHP 8.0, mais j'hésite.

Comment me débarrasser des packages anciens résiduels ?

Les apt-get purge vont me supprimer tous les packages du vps.

Ceci est-il suffisant ?

PHP:
   echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | tee /etc/apt/preferences.d/99nginx


et pour le PHP 7.3, purger les paquets ?

Merci beaucoup pour vos avis et conseils.

Très respectueusement.
 
WRInaute accro
Rebonjour

Voilà, tout est prêt pour demain matin.

Les configurations sont sauvegardées et réduites.

Le script shell de migration est en place.

Amicalement.
 
WRInaute accro
Et au final, tout cela va te permettre de sortir ton site de sa pénalité, lui permettre de retrouver son niveau d'avant ?

Proverbe Renault : Il ne sert à rien de polisher ta voiture si le moteur est cassé, elle n'avancera pas plus vite.
 
WRInaute accro
Bonjour cthierry

J'ai demandé ma levée de pénalité le 30 Juillet.

Ils ne m'ont pas refusé pour l'instant.

Ce matin, le serveur Nginx était down de 9h à 11h environ.

Maintenant çà marche, mais le PHP 8.0 de sury n'a pas encore le module php8.0-sysysem à jour, donc j'ai été obligé de débrancher la classe semaphore_non_blocking, ce qui laisse la possibilité que des fichiers de cache html, soient accédés en écriture par plusieurs processus en même temps.

Et je n'ai toujours pas de module pour traiter les etags en mode dynamique ( pas html ).

Il y a des modules propriétaires, mais...

Et le module php8.0-json ne peut pas être installé.

Espérons que celà soit temporaire.

Merci beaucoup de ton aide.

Amicalement.
 
WRInaute accro
Je te demande pardon.

Le module sysvsem est bien installé et fonctionne correctement.

Il ne reste plus que le etag dynamique et le module json.

Respectueusement.
 
WRInaute accro
Voilà c'est fait.

Grâce à des programmes glané sur le net, j'ai une gestion potable de Cache-Control, Expires ( c'est la config Nginx ), If-None-Match, If-Modified-Since, et If-Modified.

J'ai mis à 3600 secondes : Cache-Control, et Expires.

Cà roule pour le php. ;)

Merci beaucoup de votre aide.
 
WRInaute accro
Pardon.

Voici la fonction génératrice d'en-têtes http.

$etag est weak :

PHP:
  $etag = 'W/"' . md5($html_content) . '"'.


Merci de corriger les erreurs éventuelles.

En particulier, si une page change ( ETag différent ), et que le If-Modified-Since est plus récent que Last-Modified, il semblerait qu'il y ait "HTTP 304 Not Modified".

Comment corriger celà ?

Addendum :

A = If-Modified-Since encore valide,
B = Etag existe

Il semblerait qu'il y ait 304 si B == true et A == true, sinon 200.

Actuellement c'est un ou.

Je vais revoir la fonction.

Fin de l'addendum.

Merci beaucoup de votre aide.

Amicalement.


PHP:
<?php

    function caching_headers ($etag, $lastModified, $age) {
        $gmt_mtime = $lastModified;
        header('ETag: '. $etag);
        header('Last-Modified: '.$gmt_mtime);
        header('Cache-Control: must-revalidate, proxy-revalidate, max-age=' . $age);
        //    header('Cache-Control: max-age=' . $age);
        if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] >= $gmt_mtime) {
            header('HTTP/1.1 304 Not Modified');
            header("Vary: Accept-Encoding,User-Agent");
            exit();
        }
        if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
            $array_if_none_match = array();
            if(strpos(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']), ",") === false) {
                $array_if_none_match[0] = to_vide(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
            } else {
                $array_if_none_match = preg_split("{[, ]+}", stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
            }
            if(in_array($etag, $array_if_none_match)) {
                header('HTTP/1.1 304 Not Modified');
                header("Vary: Accept-Encoding,User-Agent");
                exit();
            }
        }
    }
?>
 
Dernière édition:
WRInaute accro
Repardon.

Voici la nouvelle version :

PHP:
<?php
function caching_headers ($etag, $lastModified, $age) {
        header('ETag: '. $etag);
        header('Last-Modified: '.$lastModified);
        header('Cache-Control: must-revalidate, proxy-revalidate, max-age=' . $age);
        //    header('Cache-Control: max-age=' . $age);
        $condition_not_modified    = false;
        $condition_etag_found    = false;
        if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] >= $lastModified) {
                $condition_not_modified = true;
        }
        if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
                $array_if_none_match = array();
                if(strpos(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']), ",") === false) {
                        $array_if_none_match[0] = to_vide(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
                } else {
                        $array_if_none_match = preg_split("{[, ]+}", stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
                }
                if(in_array($etag, $array_if_none_match)) {
                        $condition_etag_found = true;
                }
        }
        if($condition_etag_found === true && $condition_not_modified === true) {
                header('HTTP/1.1 304 Not Modified');
                header("Vary: Accept-Encoding,User-Agent");
                exit();
        }
}
?>
 
WRInaute accro
Rebond.

Là j'ai un problème.

Les deux critères ETag et If-Modified , semblent indépendants l'un de l'autre, et ETag est prioritaire quand les deux critères coexistent.

Si ETag est mis systématiquement par ma fonction, le ETag détermine entièrement le 304 ou 200.

Et le ETag est beaucoup plus précis que le If-Modified.

Dans ces conditions, peut-on ou doit-on ne pas utiliser le If-Modified ?

Il y a un autre problème :

Le navigateur envoie-t-il le If-None-Match dans tous les cas où il a au moins un Etag de l'url, ou seulement quand la ressource est stale ( d'après le Expires ) ?

Merci beaucoup de votre aide.
 
WRInaute accro
Et voilà

De mes notes :

Code:
-----------------------------------------------
If-Modified-Since
-----------------
En-tête de requête.
*******************
Avec If-None-Match, traité seulement
************************************
si le serveur ignore If-None-Match.
***********************************
Seulement avec GET ou HEAD.
***************************
Syntax :
********
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
-----------------------------------------------


Donc, si le serveur ( c'est le cas avec ma fonction ) admet If-None-Match , il ne faut pas traiter If-Modified-Since.

Dans d'autres endroits dans mes notes, le navigateur envoie l'en-tête If-None-Match quand la validation est nécessaire.

C'est-à-dire quand le Expires ou le Cache-Control considère la ressource comme stale.

Donc, il faudrait effacer de la fonction le traitement de If-Modified-Since, et ne garder que ETag ?

Merci de vos avis.

Respectueusement.
 
Olivier Duffez (admin)
Membre du personnel
Je propose de t'ouvrir un forum rien que pour toi !

PS : désolé mais je ne suis pas dév, je ne peux pas aider
 
WRInaute accro
Bonjour Monsieur Duffez

Il me semble que j'ai trouvé la bonne fonction.

Si None-Match n'est pas présent, le If-Modified assure.

Sinon c'est le ETag.

Merci beaucoup.



PHP:
<?php

function caching_headers ($etag, $lastModified, $age) {
        header('ETag: '. $etag);
        header('Last-Modified: '.$lastModified);
        header('Cache-Control: must-revalidate, proxy-revalidate, max-age=' . $age);
        //    header('Cache-Control: max-age=' . $age);
        if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
                $array_if_none_match = array();
                if(strpos(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']), ",") === false) {
                        $array_if_none_match[0] = to_vide(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
                } else {
                        $array_if_none_match = preg_split("{[, ]+}", stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
                }
                if(in_array($etag, $array_if_none_match)) {
                        header('HTTP/1.1 304 Not Modified');
                        header("Vary: Accept-Encoding,User-Agent");
                        exit();
                }
        } elseif(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
                $_SERVER['HTTP_IF_MODIFIED_SINCE'] >= $lastModified) {
                header('HTTP/1.1 304 Not Modified');
                header("Vary: Accept-Encoding,User-Agent");
                exit();
        }
}
?>
 
WRInaute accro
Bonjour

Théoriquement, le response_time est le moment où le navigateur reçoit le contenu html.

Comment obtenir celà en php ?

Merci beaucoup.
 
WRInaute accro
Voilà

Vous pouvez tester.

Le response _time - "Date" a été fixé à 10 ms.

Peut-être faudrait-il l'amener à 100 ms.

Question de réseau.

Le cache semble fonctionner.

Les en-têtes y sont :

Expires,( 1h ), Cache-Control ( 3600 ), Date, ETag, Last-Modified, Age, etc...

Je donne le code.

Bien amicalement.
 
WRInaute accro
Rebonjour

Il y un a bug dans le concept.

Si If-Modified-Since est intégré par le navigateur lors de la dernière mise à jour du cache, ( ressource "stale" ), alors le If-Modified du serveur est mis à jour en même temps.

Donc, si ces deux dates restent égales, c'est que la ressource n'est plus "stale", donc c'est le cache que lit le navigateur.

Si If-Modifed ( server ) augmente, If-Modified > If-Modified -Since, donc mise à jour du cache ?

Je croyais que If-Modified-Since indiquait la limite en deçà de laquelle le cache est utilisé ( 304 Not Modified ) plutôt que le serveur ( 200 OK ) ?

Merci beaucoup de vos réponses.
 
WRInaute accro
Bonjour

Les en-êtes Expires sont maintenant théoriquement à peu près corrects.

Quand le cache est refait, ( ressource "stale" ) Last-Modified est mis à "Date", et Expires à : "Date" + 3600 sec.

Sinon, Last-Modified est constant, et on calcule Expires = Last-Modified + 3600 sec.

Tout le problème, est de savoir si le If-None-Match du client est comparé tout le temps à ETag, ou seulement quand "Date" >= Expires.

Pour l'instant, j'ai implémenté "tout le temps", mais je ne sais pas si c'est conforme au protocole HTTP.

Merci de votre aide.
 
WRInaute accro
Bonjour

Si vous voulez tester :

https://www.pronostics-courses.fr

Sur certaines pages internes j'obtiens ( avec Lighthouse ), 1,2 sec le premier chargement, et 176 millisecondes au troisième chargement.

J'ai enlevé le traitement du IfModifiedSince et LastModified, et laissé celui du IfNoneMatch et ETag.

Depuis le 31 Juillet, j'attends le résultat de ma demande de la levée de la pénalité de mon site.

J'espère que les nombreuses mises au point sur mon serveur VPS n'ont pas été considérées par Google comme des erreurs empêchant la levée.

Merci beaucoup de votre aide.
 
WRInaute accro
Bonjour

Mon cache HTTP est une extension, et intègre, le cache HTML de noren.

Cette classe de cache HTTP est flanquée d'un système non bloquant de verrouillage des fichiers de cache.

Je donne les deux classes, demandez seulement.

Bien amicalement.
 
WRInaute accro
Qu'est-ce que tu peux te prendre la tête à refaire des trucs à mon sens inutile ?!
Mon conseil, concentre plutôt ton énergie à des améliorations plus fonctionnelles que techniques
 
WRInaute accro
Pardon ?

D'après Lighhtouse de Chrome, j'ai 176 miilisecondes d'accès aux pages de courses, ( 2ème accès ) au lieu de 1,2 secondes ( 1er accès ).

Le mot "fonctionnel" me semble plus ou moins équivalent à "technique".

Je suis en train de porter le soft pour une API FETCH, pour ma PWA.

Amicalement.
 
WRInaute accro
Et au final, tout cela va te permettre de sortir ton site de sa pénalité, lui permettre de retrouver son niveau d'avant ?

Proverbe Renault : Il ne sert à rien de polisher ta voiture si le moteur est cassé, elle n'avancera pas plus vite.



Bonjour cthierry

J'ai complété la classe de cache HTML de noren avec une prise en compte pratiquement complète, du protocole de cache HTTP.

Il y a la prise en compte des ETags, Expires, LastModified, IfModifiedSince, Age, mais le CacheControl n'est pas pris en compte ( avec Age ), sinon les pages se rafraichiraient trop lentement.

Les Etags sont "weak" ( de la forme : W/"string" ), et les Expires maxi sont à 1800 sec.

Cà marche bien à partir d'un navigateur, mais maintenant Google Speed Insight ne m'affiche plus la page d'accueil, alors que les autres pages ont un CLS=0, FPS=27ms, le reste à 1sec.

D'un autre côté, j'ai mis le répertoire de cache dans une RAM virtuelle en le montant avec fmps.

cthierry, que faut-il faire pour augmenter la rapidité de mon site ?

Merci beaucoup pour tes avis.

Très amicalement et respectueusement.
 
Dernière édition:
WRInaute accro
Bon bon...

J'ai enlevé tout le code relatif au cache HTTP, tout en laissant le cache monté en tmpfs.

Cà marche avec Lighthouse : Tout à 100% sauf la page d'accueil 99% pour le timing, et 100% le reste.

Environ 1,7 sec hors tout, CLS=0; PFS=0.

Merci de me dire ce que je pourrais améliorer.

Sur le plan de la rapidité, no problem.

Problèmes techniques résolus, je penserai à un graphiste quand j'aurai le temps.

Bien à vous.

Amicalement.
 
WRInaute accro
Honnêtement ? Un site un peu plus friendly users, d'ailleurs c'est ce que te demande Google ave ta pénalité pour tes contenus de résultats de courses.

Comme je te 'ai dit plus haut : Proverbe Renault : Il ne sert à rien de polisher ta voiture si le moteur est cassé, elle n'avancera pas plus vite.

Ton problème n'a jamais été la rapidité mais le contenu et accessoirement l'interface qui gagnerait des utilisateurs à être plus moderne, ou dans l'air du temps.

HS: Quand tu te prends une pénalité par Google, la route est longue pour en sortir petit scarabée :)
 
WRInaute accro
"Ton problème n'a jamais été la rapidité mais le contenu et accessoirement l'interface qui gagnerait des utilisateurs à être plus moderne, ou dans l'air du temps."

Bonjour cthierry

Le fond et la forme ?

C'est ce que tu veux dire par contenu et interface ?

Pour l'interface, un graphiste et ma programmation de ce qu'il suggère,

Pour le contenu ?

Si c'est de l'édition manuelle, je ne peux pas le faire.

Je ne peux pas non plus, pour le contenu, copier d'autres sites.

J'ai enlevé hier soir le traitement php pour le cache http, en laissant le cache html de noren et le système de verrouillage non bloquant d'accès aux fichiers.

Merci beaucoup de me donner tes avis pour mes questions ci-dessus.

Très amicalement et respectueusement.
 
WRInaute accro
Je ne sais pas, le dada ce n'est pas trop on truc. Mais tu peux agrémenter l'ensemble de l'histoire des hippodromes par exemple, le pédigrée des chevaux, celui des jockeys, des entraineurs, bref faire autorité dans ta thématique. Et pour le code, comme je te l'ai déjà dit, je ne tente pas de réinventer la roue en gérant mes sites avec des serveurs sous interface Plesk, pour ne pas avoir à mettre les mains dans le cambouis.
 
WRInaute accro
Merci beaucoup cthierry

Je vais faire appel prochainement à un graphiste.

Merci beaucoup pour tes avis.

Respectueusement.
 
Discussions similaires
Haut