NGINX конвертирует HEAD в GET запросы

10

Из-за некоторых ужасных дизайнерских решений у нас есть приложение, которое не может отвечать на запросы HTTP HEAD (возвращает «Метод не разрешен»). Модификация программного обеспечения для правильного возврата запросов HEAD была бы сложной, не невозможной, но дополнительной работой. Приложение находится за прокси-сервером NGINX, мне было интересно, есть ли способ заставить NGINX преобразовывать запросы HEAD, полученные от клиентов, в запросы GET на серверную часть, затем отбрасывать ответ, за исключением заголовков, и отправлять его обратно клиент, как если бы наши серверы приложений могли отвечать на запросы HEAD.

Текущий конфиг (довольно стандартный)

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/;
    }
}
мазаться
источник
Как вы передаете запрос в бэкэнд? proxy_pass? fastcgi_pass? Можете ли вы вставить свой текущий конфиг? Какую версию nginx вы используете?
kolbyjack
@kolbyjack proxy_pass с использованием сокетов Unix, NGINX 1.1.12 и 1.0.11 в dev, 1.0.11 в производстве (Мы скоро переходим на 1.1.12)
Smudge

Ответы:

5

Так как вы используете proxy_pass, я думаю, что вам придется использовать некоторое злоупотребление error_page (и так как вы уже используете error_pages, вам также необходимо включить рекурсивные страницы ошибок). Я думаю, что это будет работать для вас:

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
источник
Это все еще, кажется, возвращает тело клиенту, даже когда запрос с головой. Есть ли способ раздеть / игнорировать содержимое тела?
Пятно
Я надеялся, что он запомнит, что первоначальный запрос был HEAD и сбросил тело. Я не могу придумать другой способ сделать это, извини.
kolbyjack
Ну да ладно, все равно достаточно близко к тому, что нам нужно
Smudge