NGINX convierte solicitudes HEAD a GET

10

Debido a algunas decisiones terribles de diseño, tenemos una aplicación que no puede responder a las solicitudes HTTP HEAD (Devuelve 'Método no permitido'). Modificar el software para que devuelva solicitudes HEAD correctamente sería complicado, no imposible pero un trabajo extra. La aplicación se encuentra detrás de un proxy NGINX, me preguntaba si había una manera de hacer que NGINX convirtiera las solicitudes HEAD que recibió de los clientes en solicitudes GET al back-end, luego descarte la respuesta, excepto los encabezados y la envíe de vuelta al cliente como si nuestros servidores de aplicaciones pudieran responder a las solicitudes de HEAD.

Configuración actual (bastante estándar)

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/;
    }
}
Mancha
fuente
¿Cómo pasa la solicitud al backend? proxy_pass? fastcgi_pass? ¿Puedes pegar tu configuración actual? ¿Qué versión de nginx estás ejecutando?
kolbyjack
@kolbyjack PROXY_PASS usando sockets UNIX, Nginx 1.1.12 y 1.0.11 en dev, 1.0.11 de la producción (Nos estamos moviendo a la producción 1.1.12 pronto)
Dedo

Respuestas:

5

Como está usando proxy_pass, creo que tendrá que usar algunos errores de error de página (y como ya está usando error_pages, también deberá habilitar páginas de error recursivas). Creo que esto funcionará para ti:

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/;
    }
}
kolbyjack
fuente
Esto todavía parece devolver el cuerpo al cliente, incluso cuando se solicita con la cabeza. ¿Hay alguna forma de despojar / ignorar el contenido del cuerpo?
Mancha el
Esperaba que recordara que la solicitud original era CABEZA y dejara caer el cuerpo. No puedo pensar en otra forma de hacer que eso suceda, lo siento.
kolbyjack
Bueno, lo suficientemente cerca de lo que necesitamos de todos modos
mancha el