JS#
O módulo é usado para implementar manipuladores em njs — um subconjunto da linguagem JavaScript.
Em nossos repositórios, o módulo é construído
dinamicamente
e está disponível como um pacote separado chamado angie-module-njs
ou angie-pro-module-njs
.
Nota
Uma versão leve do pacote, chamada ...-njs-light
, também está
disponível; no entanto, ela não pode ser usada junto com a versão regular.
Exemplo de Configuração#
http {
js_import http.js;
js_set $foo http.foo;
js_set $summary http.summary;
js_set $hash http.hash;
resolver 127.0.0.53;
server {
listen 8000;
location / {
add_header X-Foo $foo;
js_content http.baz;
}
location = /summary {
return 200 $summary;
}
location = /hello {
js_content http.hello;
}
location = /fetch {
js_content http.fetch;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}
location = /crypto {
add_header Hash $hash;
return 200;
}
}
}
O arquivo http.js
:
function foo(r) {
r.log("hello from foo() handler");
return "foo";
}
function summary(r) {
var a, s, h;
s = "JS summary\n\n";
s += "Method: " + r.method + "\n";
s += "HTTP version: " + r.httpVersion + "\n";
s += "Host: " + r.headersIn.host + "\n";
s += "Remote Address: " + r.remoteAddress + "\n";
s += "URI: " + r.uri + "\n";
s += "Headers:\n";
for (h in r.headersIn) {
s += " header '" + h + "' is '" + r.headersIn[h] + "'\n";
}
s += "Args:\n";
for (a in r.args) {
s += " arg '" + a + "' is '" + r.args[a] + "'\n";
}
return s;
}
function baz(r) {
r.status = 200;
r.headersOut.foo = 1234;
r.headersOut['Content-Type'] = "text/plain; charset=utf-8";
r.headersOut['Content-Length'] = 15;
r.sendHeader();
r.send("nginx");
r.send("java");
r.send("script");
r.finish();
}
function hello(r) {
r.return(200, "Hello world!");
}
async function fetch(r) {
let results = await Promise.all([ngx.fetch('https://google.com/'),
ngx.fetch('https://google.ru/')]);
r.return(200, JSON.stringify(results, undefined, 4));
}
async function hash(r) {
let hash = await crypto.subtle.digest('SHA-512', r.headersIn.host);
r.setReturnValue(Buffer.from(hash).toString('hex'));
}
export default {foo, summary, baz, hello, fetch, hash};
Diretivas#
js_body_filter#
| |
Padrão | — |
location, if in location, limit_except |
Define uma função njs como filtro do corpo da resposta. A função de filtro é chamada para cada bloco de dados do corpo da resposta com os seguintes argumentos:
| o objeto requisição HTTP |
| o bloco de dados recebido, pode ser uma string ou Buffer dependendo do valor buffer_type, por padrão é uma string. |
| um objeto com as seguintes propriedades:
- |
A função de filtro pode passar sua própria versão modificada do bloco de dados de entrada para o próximo filtro de corpo chamando r.sendBuffer(). Por exemplo, para transformar todas as letras minúsculas no corpo da resposta:
function filter(r, data, flags) {
r.sendBuffer(data.toLowerCase(), flags);
}
Para parar a filtragem (os blocos de dados seguintes serão passados para o cliente sem chamar js_body_filter), r.done() pode ser usado.
Se a função de filtro alterar o comprimento do corpo da resposta, então é necessário limpar o cabeçalho de resposta Content-Length
(se houver) em js_header_filter para forçar a codificação de transferência em blocos.
Nota
Como o manipulador js_body_filter retorna seu resultado imediatamente, ele suporta apenas operações síncronas. Assim, operações assíncronas como r.subrequest() ou setTimeout() não são suportadas.
js_content#
Define uma função njs como manipulador de conteúdo de localização. Funções de módulo podem ser referenciadas.
js_fetch_buffer_size#
Define o tamanho do buffer usado para leitura e escrita com Fetch API.
js_fetch_ciphers#
| |
Padrão |
|
http, server, location |
Especifica as cifras habilitadas para conexões HTTPS com Fetch API. As cifras são especificadas no formato compreendido pela biblioteca OpenSSL.
A lista de cifras depende da versão do OpenSSL instalada.
A lista completa pode ser visualizada usando o comando openssl ciphers
.
js_fetch_max_response_buffer_size#
| |
Padrão |
|
http, server, location |
Define o tamanho máximo da resposta recebida com Fetch API.
js_fetch_protocols#
| |
Padrão |
|
http, server, location |
Habilita os protocolos especificados para conexões HTTPS com Fetch API.
js_fetch_timeout#
Define um timeout para leitura e escrita para Fetch API. O timeout é definido apenas entre duas operações sucessivas de leitura/escrita, não para toda a resposta. Se nenhum dado for transmitido dentro deste tempo, a conexão é fechada.
js_fetch_trusted_certificate#
Especifica um arquivo com certificados CA confiáveis no formato PEM usado para verificar o certificado HTTPS com Fetch API.
js_fetch_verify#
Habilita ou desabilita a verificação do certificado do servidor HTTPS com Fetch API.
js_fetch_verify_depth#
Define a profundidade de verificação na cadeia de certificados do servidor HTTPS com Fetch API.
js_header_filter#
| |
Padrão | — |
location, if in location, limit_except |
Define uma função njs como filtro de cabeçalho de resposta. A diretiva permite alterar campos de cabeçalho arbitrários de um cabeçalho de resposta.
Nota
Como o manipulador js_header_filter retorna seu resultado imediatamente, ele suporta apenas operações síncronas. Assim, operações assíncronas como r.subrequest() ou setTimeout() não são suportadas.
js_import#
Importa um módulo que implementa manipuladores de location e variável em njs. O nome_exportação é usado como namespace para acessar funções do módulo. Se o nome_exportação não for especificado, o nome do módulo será usado como namespace.
js_import http.js;
Aqui, o nome do módulo http
é usado como namespace ao acessar
exportações. Se o módulo importado exporta foo()
, http.foo
é usado
para se referir a ele.
Várias diretivas js_import
podem ser especificadas.
js_path#
Define um caminho adicional para módulos njs.
js_preload_object#
Pré-carrega um objeto imutável no momento da configuração. O nome é usado como nome da variável global através da qual o objeto está disponível no código njs. Se o nome não for especificado, o nome do arquivo será usado em seu lugar.
js_preload_object map.json;
Aqui, o map é usado como nome ao acessar o objeto pré-carregado.
Várias diretivas js_preload_object podem ser especificadas.
js_set#
Define uma função njs para a variável especificada. Funções de módulo podem ser referenciadas.
A função é chamada quando a variável é referenciada pela primeira vez para uma determinada requisição. O momento exato depende de uma fase na qual a variável é referenciada. Isso pode ser usado para executar alguma lógica não relacionada à avaliação de variável. Por exemplo, se a variável é referenciada apenas na diretiva log_format, seu manipulador não será executado até a fase de log. Este manipulador pode ser usado para fazer alguma limpeza logo antes da requisição ser liberada.
Nota
Como o manipulador js_set retorna seu resultado imediatamente, ele suporta apenas callbacks síncronos. Assim, callbacks assíncronos como r.subrequest() ou setTimeout() não são suportados.
js_var#
Declara uma variável gravável. O valor pode conter texto, variáveis e sua combinação. A variável não é sobrescrita após um redirecionamento, diferentemente de variáveis criadas com a diretiva set.
Argumento de Requisição#
Cada manipulador HTTP njs recebe um argumento, um objeto request.