NGINX converte solicitações HEAD em GET


10

Devido a algumas péssimas decisões de design, temos um aplicativo incapaz de responder às solicitações HTTP HEAD (Retorna 'Método não permitido'). Modificar o software para retornar solicitações HEAD corretamente seria complicado, não impossível, mas um trabalho extra. O aplicativo fica atrás de um proxy NGINX. Fiquei imaginando se havia uma maneira de o NGINX converter as solicitações HEAD recebidas dos clientes em solicitações GET para o back-end, depois descarte a resposta, exceto os cabeçalhos, e envie-a de volta ao cliente como se nossos servidores de aplicativos pudessem responder às solicitações HEAD.

Configuração atual (razoavelmente padrão)

upstream ourupstream{
    server unix:/var/apps/sockets/ourapp.socket.thread1
    server unix:/var/apps/sockets/ourapp.socket.thread2
    server unix:/var/apps/sockets/ourapp.socket.thread3
    [like 20 of these]
}

server {
    listen       1.2.3.4:80;
    server_name  ourapp;

    access_log  /var/apps/logs/ourapp.nginx.plog    proxy;
    error_log   /var/apps/logs/ourapp.nginx.elog    info;

    gzip on;

    gzip_types  text/plain text/html;

    proxy_intercept_errors on;
    proxy_connect_timeout 10;
    proxy_send_timeout 10;
    proxy_read_timeout 10;
    proxy_next_upstream error timeout;
    client_max_body_size 2m;

    error_page 404 /static/404.html;
    error_page 500 501 502 503 504 =500 /static/500.html;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://ourupstream/;
    }

    location /static/ {
        root /var/apps/global/;
    }
}

Como você está passando a solicitação para o back-end? proxy_pass? fastcgi_pass? Você pode colar sua configuração atual? Qual versão do nginx você está executando?
kolbyjack

@kolbyjack proxy_pass utilizando sockets Unix, NGINX 1.1.12 e 1.0.11 em dev, 1.0.11 na produção (Estamos transferindo a produção para 1.1.12 breve)
Smudge

Respostas:


5

Como você está usando proxy_pass, acho que você precisará usar alguns abusos de error_page (e como você já está usando error_pages, também precisará habilitar páginas de erro recursivas). Eu acho que isso funcionará para você:

upstream ourupstream{
    server unix:/var/apps/sockets/ourapp.socket.thread1
    server unix:/var/apps/sockets/ourapp.socket.thread2
    server unix:/var/apps/sockets/ourapp.socket.thread3
    [like 20 of these]
}

server {
    listen       1.2.3.4:80;
    server_name  ourapp;

    access_log  /var/apps/logs/ourapp.nginx.plog    proxy;
    error_log   /var/apps/logs/ourapp.nginx.elog    info;

    gzip on;

    gzip_types  text/plain text/html;

    proxy_intercept_errors on;
    proxy_connect_timeout 10;
    proxy_send_timeout 10;
    proxy_read_timeout 10;
    proxy_next_upstream error timeout;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 2m;

    error_page 404 /static/404.html;
    error_page 500 501 502 503 504 =500 /static/500.html;

    location @force_get {
        recursive_error_pages on;
        proxy_method GET;
        proxy_pass http://ourupstream;
    }

    location / {
        error_page 550 = @force_get;
        if ($request_method = HEAD) { return 550; }
        proxy_pass http://ourupstream;
    }

    location /static/ {
        root /var/apps/global/;
    }
}

Isso ainda parece devolver o corpo ao cliente, mesmo quando solicitado com a cabeça. Existe alguma maneira de remover / ignorar o conteúdo do corpo?
Borrar

Eu esperava que ele lembrasse que o pedido original era HEAD e largou o corpo. Não consigo pensar em outra maneira de fazer isso acontecer, desculpe.
kolbyjack

Oh bem, não perto o suficiente para o que precisamos de qualquer maneira
Smudge
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.