Pular para conteúdo

upload: módulo NGINX para manipulação de uploads de arquivos

Instalação

Você pode instalar este módulo em qualquer distribuição baseada em RHEL, incluindo, mas não se limitando a:

  • RedHat Enterprise Linux 7, 8, 9 e 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 e Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-upload
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-upload

Ative o módulo adicionando o seguinte no topo de /etc/nginx/nginx.conf:

load_module modules/ngx_http_upload_module.so;

Este documento descreve o nginx-module-upload v2.3.0 lançado em 02 de agosto de 2018.


Um módulo para nginx para manipulação de uploads de arquivos usando codificação multipart/form-data (RFC 1867) e uploads recuperáveis de acordo com este protocolo.

Descrição

O módulo analisa o corpo da requisição armazenando todos os arquivos que estão sendo enviados em um diretório especificado pela diretiva upload_store. Os arquivos são então removidos do corpo e a requisição alterada é passada para uma localização especificada pela diretiva upload_pass, permitindo assim o manuseio arbitrário dos arquivos enviados. Cada um dos campos de arquivo é substituído por um conjunto de campos especificados pela diretiva upload_set_form_field. O conteúdo de cada arquivo enviado pode ser lido de um arquivo especificado pela variável $upload_tmp_path ou o arquivo pode ser simplesmente movido para o destino final. A remoção dos arquivos de saída é controlada pela diretiva upload_cleanup. Se uma requisição tiver um método diferente de POST, o módulo retorna o erro 405 (Método não permitido). Requisições com tais métodos podem ser processadas em uma localização alternativa via diretiva error_page.

Diretivas

upload_pass

Sintaxe: upload_pass location
Padrão:
Contexto: server,location

Especifica a localização para passar o corpo da requisição. Os campos de arquivo serão removidos e substituídos por campos que contêm as informações necessárias para manipular os arquivos enviados.

upload_resumable

Sintaxe: upload_resumable on | off
Padrão: upload_resumable off
Contexto: main,server,location

Habilita uploads recuperáveis.

upload_store

Sintaxe: upload_store directory [level1 [level2]] ...
Padrão:
Contexto: server,location

Especifica um diretório onde os arquivos de saída serão salvos. O diretório pode ser hashado. Nesse caso, todos os subdiretórios devem existir antes de iniciar o nginx.

upload_state_store

Sintaxe: upload_state_store directory [level1 [level2]] ...
Padrão:
Contexto: server,location

Especifica um diretório que conterá arquivos de estado para uploads recuperáveis. O diretório pode ser hashado. Nesse caso, todos os subdiretórios devem existir antes de iniciar o nginx.

upload_store_access

Sintaxe: upload_store_access mode
Padrão: upload_store_access user:rw
Contexto: server,location

Especifica o modo de acesso que será usado para criar arquivos de saída.

upload_set_form_field

Sintaxe: upload_set_form_field name value
Padrão:
Contexto: server,location

Especifica um ou mais campos de formulário a serem gerados para cada arquivo enviado no corpo da requisição passado para o backend. Tanto name quanto value podem conter as seguintes variáveis especiais:

  • $upload_field_name: o nome do campo de arquivo original
  • $upload_content_type: o tipo de conteúdo do arquivo enviado
  • $upload_file_name: o nome original do arquivo sendo enviado, com os elementos de caminho em notação DOS e UNIX removidos. Ou seja, "D:\Documents And Settings\My Dcouments\My Pictures\Picture.jpg" será convertido para "Picture.jpg" e "/etc/passwd" será convertido para "passwd".
  • $upload_tmp_path: o caminho onde o conteúdo do arquivo original está sendo armazenado. O nome do arquivo de saída consiste em 10 dígitos e é gerado com o mesmo algoritmo que na diretiva proxy_temp_path.

Essas variáveis são válidas apenas durante o processamento de uma parte do corpo da requisição original.

Exemplo de uso:

upload_set_form_field $upload_field_name.name "$upload_file_name";
upload_set_form_field $upload_field_name.content_type "$upload_content_type";
upload_set_form_field $upload_field_name.path "$upload_tmp_path";

upload_aggregate_form_field

Sintaxe: upload_aggregate_form_field name value
Padrão:
Contexto: server,location

Especifica um ou mais campos de formulário contendo atributos agregados a serem gerados para cada arquivo enviado no corpo da requisição passado para o backend. Tanto name quanto value podem conter variáveis padrão do nginx, variáveis da diretiva upload_set_form_field e as seguintes variáveis especiais adicionais:

  • $upload_file_md5: checksum MD5 do arquivo
  • $upload_file_md5_uc: checksum MD5 do arquivo em letras maiúsculas
  • $upload_file_sha1: checksum SHA1 do arquivo
  • $upload_file_sha1_uc: checksum SHA1 do arquivo em letras maiúsculas
  • $upload_file_crc32: valor hexadecimal de CRC32 do arquivo
  • $upload_file_size: tamanho do arquivo em bytes
  • $upload_file_number: número ordinal do arquivo no corpo da requisição

O valor de um campo especificado por esta diretiva é avaliado após o upload bem-sucedido do arquivo, portanto, essas variáveis são válidas apenas no final do processamento de uma parte do corpo da requisição original.

Aviso:: as variáveis $upload_file_md5, $upload_file_md5_uc, $upload_file_sha1 e $upload_file_sha1_uc usam recursos adicionais para calcular checksums MD5 e SHA1.

Exemplo de uso:

upload_aggregate_form_field $upload_field_name.md5 "$upload_file_md5";
upload_aggregate_form_field $upload_field_name.size "$upload_file_size";

upload_pass_form_field

Sintaxe: upload_pass_form_field regex
Padrão:
Contexto: server,location

Especifica um padrão regex para os nomes dos campos que serão passados para o backend a partir do corpo da requisição original. Esta diretiva pode ser especificada várias vezes por localização. O campo será passado para o backend assim que o primeiro padrão corresponder. Para ambientes que não reconhecem PCRE, esta diretiva especifica o nome exato de um campo a ser passado para o backend. Se a diretiva for omitida, nenhum campo será passado para o backend a partir do cliente.

Exemplo de uso:

upload_pass_form_field "^submit$|^description$";

Para ambientes que não reconhecem PCRE:

upload_pass_form_field "submit";
upload_pass_form_field "description";

upload_cleanup

Sintaxe: upload_cleanup status/range ...
Padrão:
Contexto: server,location

Especifica os status HTTP após os quais todos os arquivos enviados com sucesso na requisição atual serão removidos. Usado para limpeza após falha do backend ou do servidor. O backend também pode sinalizar explicitamente um status de erro se não precisar dos arquivos enviados por algum motivo. O status HTTP deve ser um valor numérico na faixa de 400-599, sem zeros à esquerda permitidos. Faixas de status podem ser especificadas com um hífen.

Exemplo de uso:

upload_cleanup 400 404 499 500-505;

upload_buffer_size

Sintaxe: upload_buffer_size size
Padrão: tamanho da página de memória em bytes
Contexto: server,location

Tamanho em bytes do buffer de gravação que será usado para acumular dados de arquivo e gravá-los no disco. Esta diretiva é destinada a ser usada para comprometer o uso de memória em relação à taxa de chamadas de sistema.

upload_max_part_header_len

Sintaxe: upload_max_part_header_len size
Padrão: 512
Contexto: server,location

Especifica o comprimento máximo do cabeçalho da parte em bytes. Determina o tamanho do buffer que será usado para acumular cabeçalhos de partes.

upload_max_file_size

Sintaxe: upload_max_file_size size
Padrão: 0
Contexto: main,server,location

Especifica o tamanho máximo do arquivo. Arquivos maiores que o valor desta diretiva serão omitidos. Esta diretiva especifica um limite "suave", no sentido de que, após encontrar um arquivo maior que o limite especificado, o nginx continuará a processar o corpo da requisição, tentando receber os arquivos restantes. Para um limite "rígido", a diretiva client_max_body_size deve ser usada. O valor zero para esta diretiva especifica que nenhuma restrição no tamanho do arquivo deve ser aplicada.

upload_limit_rate

Sintaxe: upload_limit_rate rate
Padrão: 0
Contexto: main,server,location

Especifica o limite de taxa de upload em bytes por segundo. Zero significa que a taxa é ilimitada.

upload_max_output_body_len

Sintaxe: upload_max_output_body_len size
Padrão: 100k
Contexto: main,server,location

Especifica o comprimento máximo do corpo de saída. Isso evita o acúmulo de campos de formulário não relacionados a arquivos na memória. Sempre que o corpo de saída ultrapassar o limite especificado, o erro 413 (Entidade da requisição muito grande) será gerado. O valor zero para esta diretiva especifica que nenhuma restrição no comprimento do corpo de saída deve ser aplicada.

upload_tame_arrays

Sintaxe: upload_tame_arrays on | off
Padrão: off
Contexto: main,server,location

Especifica se os colchetes nos nomes dos campos de arquivo devem ser removidos (necessário para arrays PHP).

upload_pass_args

Sintaxe: upload_pass_args on | off
Padrão: off
Contexto: main,server,location

Habilita o encaminhamento de argumentos de consulta para a localização especificada por upload_pass. Ineficaz com locais nomeados. Exemplo:

<form action="/upload/?id=5">
<!-- ... -->
location /upload/ {
    upload_pass /internal_upload/;
    upload_pass_args on;
}

## ...

location /internal_upload/ {
    # ...
    proxy_pass http://backend;
}

Neste exemplo, o backend recebe a URI da requisição "/upload?id=5". No caso de upload_pass_args off, o backend recebe "/upload".

Exemplo de configuração

server {
    client_max_body_size 100m;
    listen 80;

    # O formulário de upload deve ser enviado para esta localização
    location /upload/ {
        # Passar o corpo da requisição alterado para esta localização
        upload_pass @test;

        # Armazenar arquivos neste diretório
        # O diretório é hashado, subdiretórios 0 1 2 3 4 5 6 7 8 9 devem existir
        upload_store /tmp 1;

        # Permitir que arquivos enviados sejam lidos apenas pelo usuário
        upload_store_access user:r;

        # Definir campos especificados no corpo da requisição
        upload_set_form_field $upload_field_name.name "$upload_file_name";
        upload_set_form_field $upload_field_name.content_type "$upload_content_type";
        upload_set_form_field $upload_field_name.path "$upload_tmp_path";

        # Informar ao backend sobre o hash e o tamanho de um arquivo
        upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
        upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";

        upload_pass_form_field "^submit$|^description$";

        upload_cleanup 400 404 499 500-505;
    }

    # Passar o corpo da requisição alterado para um backend
    location @test {
        proxy_pass http://localhost:8080;
    }
}
<form name="upload" method="POST" enctype="multipart/form-data" action="/upload/">
<input type="file" name="file1">
<input type="file" name="file2">
<input type="hidden" name="test" value="value">
<input type="submit" name="submit" value="Upload">
</form>

GitHub

Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório do GitHub para nginx-module-upload.