FCGI::Buffer - Verifique, armazene em cache e otimize a saída FCGI
Versão 0.19
FCGI::Buffer verifica o HTML que você produz passando-o por HTML::Lint
.
FCGI::Buffer otimiza programas FCGI reduzindo, filtrando e compactando a saída para acelerar a transmissão e fazendo uso quase contínuo de caches de cliente e servidor.
Para utilizar caches de clientes, ou seja, reduzir chamadas desnecessárias ao seu servidor solicitando os mesmos dados:
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,
);
# ...
}
Para também fazer uso dos caches do servidor, ou seja, para salvar a saída da regeneração quando clientes diferentes solicitarem os mesmos dados, você precisará criar um cache. Mas isso é simples:
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;
# ...
}
}
Para impedir temporariamente o uso de caches do lado do servidor, por exemplo, durante a depuração antes de publicar uma alteração de código, defina a variável de ambiente NO_CACHE para qualquer valor diferente de zero. Isso também impedirá que ETag seja adicionado ao cabeçalho. Se você receber erros sobre caracteres largos na impressão, significa que você esqueceu de emitir HTML puro em caracteres não-ASCII. Consulte HTML::Entidades. Como solução alternativa, você também pode remover acentos e similares usando Text::Unidecode, que funciona bem, mas não é realmente o que você deseja.
Crie um objeto FCGI::Buffer. Faça um destes para cada FCGI::Accept.
Defina várias opções e substitua os valores padrão.
# 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(),
});
Se nenhuma cache_key for fornecida, será gerada uma que pode não ser única. O cache_key deve ser um valor exclusivo dependente dos valores definidos pelo navegador.
O objeto de cache será um objeto que entende as mensagens get_object(), set(), remove() ecreated_at(), como um objeto CHI. Ele é usado como cache do lado do servidor para reduzir a necessidade de reexecutar acessos ao banco de dados.
Os itens permanecem no cache do servidor por padrão por 10 minutos. Isso pode ser substituído pelo cabeçalho HTTP cache_control na solicitação, e o padrão pode ser alterado pelo argumento cache_age para init().
Save_to é um recurso que armazena a saída de páginas dinâmicas em sua árvore htdocs e substitui links futuros que apontam para essa página por links estáticos para evitar passar por CGI. Ttl é definido como o número de segundos durante os quais as páginas estáticas são consideradas ativas; o padrão é 10 minutos. Se definido como 0, a página ficará ativa para sempre. Para habilitar save_to, argumentos info e lingua também devem ser fornecidos. Funciona melhor quando o cache também é fornecido. Use apenas onde a saída for garantidamente a mesma com um determinado conjunto de argumentos (os mesmos critérios para habilitar generate_304). Você pode desligá-lo caso a caso assim:
my $params = CGI::Info->new()->params();
if($params->{'send_private_email'}) {
$buffer->init('save_to' => undef);
}
Info é um argumento opcional para fornecer informações sobre o ambiente FCGI, por exemplo, um objeto CGI::Info.
Logger será um objeto que entende debug() como um objeto Log::Log4perl.
Para gerar um cabeçalho last_modified, você deve fornecer um objeto de cache.
O init permite que uma referência das opções seja passada. Portanto, ambos funcionam: use FCGI::Buffer; #... meu $buffer = FCGI::Buffer->new(); $b->init(generate_etag => 1); $b->init({ generate_etag => 1, info => CGI::Info->new() });
De modo geral, passar por referência é melhor, pois copia menos para a pilha.
Se você fornecer um cache para init() e depois fornecer cache => undef, o cache do lado do servidor não será mais usado. Isto é útil quando você encontra uma condição de erro ao criar seu HTML e decide que não deseja mais armazenar a saída no cache.
Sinônimo de init, mantido por razões históricas.
Retorna verdadeiro se o servidor tiver permissão para armazenar os resultados localmente. Este é o valor do X-Cache no cabeçalho retornado.
Retorna verdadeiro se a saída estiver armazenada em cache. Se for, significa que todas as rotinas caras no script FCGI podem ser ignoradas porque já temos o resultado armazenado no 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,
FCGI::Buffer deve ser seguro mesmo em scripts que produzem muitos resultados diferentes, por exemplo, situações de comércio eletrônico. Nessas páginas, entretanto, recomendo fortemente definir generate_304 como 0 e enviar o cabeçalho HTTP "Cache-Control: no-cache".
Ao usar o modelo, certifique-se de não usá-lo para gerar saída para STDOUT; em vez disso, você precisará capturar em uma variável e imprimi-la. Por exemplo:
my $output;
$template->process($input, $vars, $output) || ($output = $template->error());
print $output;
Pode produzir JavaScript com bugs se você usar a técnica