Назад | Перейти на главную страницу

Обратный прокси-сервер nginx с именованным расположением: как переопределить бэкэнд-заголовок?

Мне трудно получить add_header работать, когда try_files используется для отправки запросов в указанное место, которое указывает серверную часть с proxy_pass.

В принципе, я хочу переопределить Content-Type для определенного набора URI, но не хочу использовать map чтобы установить для него переменную (так как я бы хотел types и mime.types механизм для продолжения работы как есть), а также для установки расширения для URI и добавления дополнительных types декларации.

Вот упрощенная версия моего nginx.conf:

http {
    include       mime.types;
    default_type  text/html;
    charset       utf-8;

    server {
        listen 80;

        location @backend {
            rewrite ^ /proxy$uri break;
            proxy_pass https://backend;
            proxy_intercept_errors on;

            aws_access_key ***;
            aws_secret_key ***;
            s3_bucket ***;
            chop_prefix /proxy;

            proxy_set_header Authorization $s3_auth_token;
            proxy_set_header x-amz-date $aws_date;
            proxy_hide_header Content-Type;
        }

        location / {
            try_files false @backend;
        }

        location ~ /(textfile|anothertextfile)$ {
            try_files false @backend;
            add_header Content-Type 'text/plain' always;
            # This has no effect either
            # default_type text/plain;
        }
    }
}

я использую ngx_aws_auth здесь, но я не думаю, что это должно иметь значение.

Поведение, которое я видел с nginx 1.16.0, заключается в том, что Content-Type вообще не возвращается; не для /textfile место, где я ожидаю text/plain, ни для любого другого URL, где я ожидаю text/html из-за default_type на http уровень. Если я удалю proxy_hide_header Content-Type line, то я просто получаю заголовок серверной части, который я хочу переопределить.

Я понимаю откровенно не интуитивное поведение add_header где заголовки не наследуются от более высокого уровня, если add_header указан на текущем уровне, что, по-моему, здесь не происходит, но я также попытался переместить все директивы заголовков в отдельный файл .conf и включить его повсюду, и я по-прежнему получаю такое же поведение.

Я также пробовал использовать заголовки-больше модуль, без разницы.

Что мне не хватает, сбой сервера?

Спасибо!

Решение состоит в том, чтобы использовать дополнительный именованный блок, чтобы иметь настраиваемый заголовок для всех запросов, проходящих через него. Код в исходном вопросе не работал, потому что add_header действует только в последнем совпавшем блоке местоположения. Если запрос проходит через несколько блоков местоположения, он не принимает add_header директива на переданные блоки местоположения. Nginx только рассматривает или ищет add_header в последнем совпавшем блоке местоположения. В этом случае названный блок местоположения является последним совпадающим блоком местоположения. Надеюсь, это проясняет, почему исходный код не работал должным образом.

http {
    include       mime.types;
    default_type  text/html;
    charset       utf-8;

    server {
        listen 80;

        location @backend {
            rewrite ^ /proxy$uri break;
            proxy_pass https://backend;
            proxy_intercept_errors on;

            aws_access_key ***;
            aws_secret_key ***;
            s3_bucket ***;
            chop_prefix /proxy;

            proxy_set_header Authorization $s3_auth_token;
            proxy_set_header x-amz-date $aws_date;
            proxy_hide_header Content-Type;
        }

        location @plain_backend {
            rewrite ^ /proxy$uri break;
            proxy_pass https://backend;
            proxy_intercept_errors on;

            aws_access_key ***;
            aws_secret_key ***;
            s3_bucket ***;
            chop_prefix /proxy;

            proxy_set_header Authorization $s3_auth_token;
            proxy_set_header x-amz-date $aws_date;
            proxy_hide_header Content-Type;

            add_header Content-Type 'text/plain' always;
        }

        location / {
            try_files false @backend;
        }

        location ~ /(textfile|anothertextfile)$ {
            try_files false @plain_backend;
        }
    }
}