FCGI::Buffer - Vérifier, mettre en cache et optimiser la sortie FCGI
Version 0.19
FCGI::Buffer vérifie le code HTML que vous produisez en le transmettant via HTML::Lint
.
FCGI::Buffer optimise les programmes FCGI en réduisant, filtrant et compressant la sortie pour accélérer la transmission et en utilisant de manière presque transparente les caches client et serveur.
Pour exploiter les caches clients, c'est-à-dire réduire les appels inutiles vers votre serveur demandant les mêmes données :
use FCGI;
use FCGI::Buffer;
# ...
my $request = FCGI::Request();
while($request->FCGI::Accept() >= 0) {
my $buffer = FCGI::Buffer->new();
$buffer->init(
optimise_content => 1,
lint_content => 0,
);
# ...
}
Pour utiliser également les caches du serveur, c'est-à-dire pour sauvegarder la sortie régénérée lorsque différents clients vous demandent les mêmes données, vous devrez créer un cache. Mais c'est simple :
use FCGI;
use CHI;
use FCGI::Buffer;
# ...
my $request = FCGI::Request();
while($request->FCGI::Accept() >= 0) {
my $buffer = FCGI::Buffer->new();
$buffer->init(
optimise_content => 1,
lint_content => 0,
cache => CHI->new(driver => 'File')
);
if($buffer->is_cached()) {
# Nothing has changed - use the version in the cache
$request->Finish();
next;
# ...
}
}
Pour empêcher temporairement l'utilisation de caches côté serveur, par exemple lors du débogage avant de publier une modification de code, définissez la variable d'environnement NO_CACHE sur n'importe quelle valeur non nulle. Cela empêchera également l'ajout d'ETag à l'en-tête. Si vous obtenez des erreurs concernant les caractères larges lors de l'impression, cela signifie que vous avez oublié d'émettre du HTML pur sur les caractères non-ASCII. Voir HTML :: Entités. En guise de solution de piratage, vous pouvez également supprimer les accents, etc. en utilisant Text::Unidecode, qui fonctionne bien mais n'est pas vraiment ce que vous voulez.
Créez un objet FCGI::Buffer. Faites-en une pour chaque FCGI::Accept.
Définissez diverses options et remplacez les valeurs par défaut.
# Put this toward the top of your program before you do anything
# By default, generate_tag, generate_304 and compress_content are ON,
# optimise_content and lint_content are OFF. Set optimise_content to 2 to
# do aggressive JavaScript optimisations which may fail.
use FCGI::Buffer;
my $buffer = FCGI::Buffer->new()->init({
generate_etag => 1, # make good use of client's cache
generate_last_modified => 1, # more use of client's cache
compress_content => 1, # if gzip the output
optimise_content => 0, # optimise your program's HTML, CSS and JavaScript
cache => CHI->new(driver => 'File'), # cache requests
cache_key => 'string', # key for the cache
cache_age => '10 minutes', # how long to store responses in the cache
logger => $self->{logger},
lint_content => 0, # Pass through HTML::Lint
generate_304 => 1, # When appropriate, generate 304: Not modified
save_to => { directory => '/var/www/htdocs/save_to', ttl => 600, create_table => 1 },
info => CGI::Info->new(),
lingua => CGI::Lingua->new(),
});
Si aucune clé de cache n'est donnée, une clé sera générée et elle ne sera peut-être pas unique. Le cache_key doit être une valeur unique dépendant des valeurs définies par le navigateur.
L'objet cache sera un objet qui comprend les messages get_object(), set(), remove() et create_at(), comme un objet CHI. Il est utilisé comme cache côté serveur pour réduire le besoin de réexécuter les accès à la base de données.
Les éléments restent par défaut dans le cache côté serveur pendant 10 minutes. Cela peut être remplacé par l'en-tête HTTP cache_control dans la requête, et la valeur par défaut peut être modifiée par l'argument cache_age en init().
Save_to est une fonctionnalité qui stocke la sortie des pages dynamiques dans votre arborescence htdocs et remplace les futurs liens pointant vers cette page par des liens statiques pour éviter de passer par CGI. Ttl est défini sur le nombre de secondes pendant lesquelles les pages statiques sont considérées comme étant actives, la valeur par défaut est de 10 minutes. Si la valeur est 0, la page est active pour toujours. Pour activer save_to, une information et des arguments lingua doivent également être fournis. Cela fonctionne mieux lorsque le cache est également fourni. À utiliser uniquement lorsque la sortie est garantie d'être la même avec un ensemble d'arguments donné (les mêmes critères pour activer generate_304). Vous pouvez le désactiver au cas par cas ainsi :
my $params = CGI::Info->new()->params();
if($params->{'send_private_email'}) {
$buffer->init('save_to' => undef);
}
Info est un argument facultatif pour donner des informations sur l'environnement FCGI, par exemple un objet CGI::Info.
Logger sera un objet qui comprend debug() tel qu'un objet Log::Log4perl.
Pour générer un en-tête last_modified, vous devez donner un objet cache.
Init permet de transmettre une référence des options. Donc les deux fonctionnent : utilisez FCGI::Buffer ; #... mon $buffer = FCGI::Buffer->new(); $b->init(generate_etag => 1); $b->init({ generate_etag => 1, info => CGI::Info->new() });
De manière générale, il est préférable de passer par référence car cela copie moins sur la pile.
Si vous donnez un cache à init() puis donnez plus tard cache => undef, le cache côté serveur n'est plus utilisé. Ceci est utile lorsque vous trouvez une condition d'erreur lors de la création de votre code HTML et décidez que vous ne souhaitez plus stocker la sortie dans le cache.
Synonyme d'init, conservé pour des raisons historiques.
Renvoie vrai si le serveur est autorisé à stocker les résultats localement. Il s'agit de la valeur de X-Cache dans l'en-tête renvoyé.
Renvoie vrai si la sortie est mise en cache. Si tel est le cas, cela signifie que toutes les routines coûteuses du script FCGI peuvent être contournées car le résultat est déjà stocké dans le cache.
# Put this toward the top of your program before you do anything
# Example key generation - use whatever you want as something
# unique for this call, so that subsequent calls with the same
# values match something in the cache
use CGI::Info;
use CGI::Lingua;
use FCGI::Buffer;
my $i = CGI::Info->new();
my $l = CGI::Lingua->new(supported => ['en']);
# To use server side caching you must give the cache argument, however
# the cache_key argument is optional - if you don't give one then one will
# be generated for you
my $buffer = FCGI::Buffer->new();
if($buffer->can_cache()) {
$buffer->init(
cache => CHI->new(driver => 'File'),
cache_key => $i->domain_name() . '/' . $i->script_name() . '/' . $i->as_string() . '/' . $l->language()
);
if($buffer->is_cached()) {
# Output will be retrieved from the cache and sent automatically
exit;
}
}
# Not in the cache, so now do our expensive computing to generate the
# results
print "Content-type: text/htmln";
# ...
Nigel Horne, <njh at bandsman.co.uk>
FCGI::Buffer devrait être sûr même dans les scripts qui produisent de nombreux résultats différents, par exemple dans les situations de commerce électronique. Cependant, sur de telles pages, je vous conseille fortement de définir generate_304 sur 0 et d'envoyer l'en-tête HTTP "Cache-Control: no-cache".
Lorsque vous utilisez un modèle, assurez-vous de ne pas l'utiliser pour sortir sur STDOUT, vous devrez plutôt le capturer dans une variable et l'imprimer. Par exemple:
my $output;
$template->process($input, $vars, $output) || ($output = $template->error());
print $output;
Peut produire du JavaScript bogué si vous utilisez la technique <!-- HIDING. Il s'agit d'un bug dans JavaScript :: Packer, pas dans FCGI :: Buffer.
Mod_deflate peut confondre cela lors de la compression de la sortie. Assurez-vous que la déflation est désactivée pour les fichiers .pl :
SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png|pl)$ no-gzip dont-vary
Si vous demandez une sortie compressée puis une sortie non compressée (ou vice versa) sur une entrée qui produit la même sortie, le statut sera 304. La lettre de la spécification dit que c'est faux, donc je le note ici, mais en pratique vous ne devriez pas voir cela se produire ou avoir des difficultés à cause de cela.
FCGI :: Buffer n'a pas été testé par rapport à FastCGI.
Je conseille d'ajouter FCGI::Buffer comme dernière instruction d'utilisation afin qu'elle soit effacée en premier. En particulier, il doit être chargé après Log::Log4perl, si vous l'utilisez, afin que tous les messages qu'il produit soient imprimés après que les en-têtes HTTP aient été envoyés par FCGI::Buffer ;
Save_to ne comprend pas les liens en JavaScript, ce qui signifie que si vous utilisez des CGI auto-appelant chargés en tant que page statique, ils peuvent pointer vers le mauvais endroit. La solution de contournement consiste à éviter les CGI auto-appelants en JavaScript
Veuillez signaler tout bug ou demande de fonctionnalité à bug-fcgi-buffer at rt.cpan.org
ou via l'interface Web à http://rt.cpan.org/NoAuth/ReportBug.html?Queue=FCGI-Buffer. Je serai informé, puis vous serez automatiquement informé de la progression de votre bug au fur et à mesure que j'apporterai des modifications.
L'opération lint ne fonctionne que sur HTML4, en raison d'une restriction dans HTML::Lint.
CGI :: Buffer, HTML :: Packer, HTML :: Lint
Vous pouvez trouver la documentation de ce module avec la commande perldoc.
perldoc FCGI::Buffer
Vous pouvez également rechercher des informations sur :
RT : le suivi des requêtes du CPAN
http://rt.cpan.org/NoAuth/Bugs.html?Dist=FCGI-Buffer
Notes CPAN
http://cpanratings.perl.org/d/FCGI-Buffer
Rechercher
http://search.cpan.org/dist/FCGI-Buffer/
L'inspiration et le code pour une partie de cela sont cgi_buffer de Mark Nottingham : https://www.mnot.net/blog/2003/04/24/etags.
La licence pour cgi_buffer est :
"(c) 2000 Copyright Mark Nottingham <[email protected]>
This software may be freely distributed, modified and used,
provided that this copyright notice remain intact.
This software is provided 'as is' without warranty of any kind."
Le reste du programme est protégé par Copyright 2015-2023 Nigel Horne et est publié sous la licence suivante : GPL2.