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

Странное поведение с nginx try_files. Что не так в моей конфигурации?

os: debian stable (squeeze) nginx: squeeze-backports 1.2.1-2 ~ bpo60 + 1

try_files для меня просто странно.

это работает, как ожидалось, $ uri проверяется локально, если не найдено -> используется @static location

try_files  $uri $uri/ @static;

просто добавление a = 404 в конец приводит к 404. Разве это не должно работать, если я обращаюсь к существующему файлу, который находится в $ uri или @static, и обслуживаю только 404, если ничего не найдено в месте @static?

try_files  $uri $uri/ @static =404;

поставив = 404 до того, как @static сделает это работай очередной раз. Зачем? если файл находится не в $ uri или $ uri / location, а в @static, это должно привести к 404, потому что = 404 для @static (насколько я понимаю). если я помещаю доступ к файлу, который находится в $ uri, он правильно обслуживается из nginx (не попадает в @static backend или = 404)

try_files  $uri $uri/ =404 @static ;

я очень запутался

изменить: моей целью было бы: проверить, находится ли файл локально, затем проверить все вышестоящие серверы для файла и, если он не найден в этих местах, вернуть 404

config:

upstream domain.com_upstream
{
    server yyy.yyy.yyy.yyy:8000 weight=10 max_fails=3 fail_timeout=3s;
    server zzz.zzz.zzz.zzz:8020 weight=10 max_fails=3 fail_timeout=3s;
}

server 
{
    server_name         www.domain.com;

    listen              xxx.xxx.xxx.xxx:80;

    location @static
    {
        proxy_ignore_client_abort off;
        proxy_intercept_errors    on;
        proxy_next_upstream       http_404 error timeout invalid_header;

        proxy_pass                  http://domain.com_upstream;
        proxy_redirect              off;
        proxy_set_header            Host                $host;
        proxy_set_header            X-Real-IP           $remote_addr;
        proxy_set_header            X-Forwarded-For     $proxy_add_x_forwarded_for;
        client_max_body_size        10m;
        client_body_buffer_size     128k;

        proxy_connect_timeout       10;
        proxy_send_timeout          120;
        proxy_read_timeout          120;

        proxy_buffers 8 16k;
        proxy_buffer_size 32k;
    }

    location ~ ^/test 
    { 
        root /var/www/test;
        try_files $uri @static =404; # exchange with upper try_file examples...
    }

    *** snip ***
}

Ты не понял try_files параметры. Цитата из документы:

Если ни один из файлов не найден, выполняется внутреннее перенаправление на uri, указанный последним параметром.

Только последний параметр - это резервный URI (или именованное местоположение, или код), все остальные параметры - это файлы для тестирования. Т.е.

try_files /file1 /file2 /file3 ... @fallback;

проверит наличие файлов в корне документа (/ file1, / file2, / file3 и т. д.), и, если ничего не найдено, nginx выполнит внутреннее перенаправление на @fallback.

В try_files ... @static =404; на самом деле не имеет смысла, поскольку он будет проверять файл с именем @static в корне документа, и, скорее всего, это не то, что вам нужно. В try_files ... =404 @static; тоже не имеет смысла, поскольку он проверяет наличие файла с именем =404.

Смотрите здесь документы: http://nginx.org/r/try_files.

для полноты (ответ kolbyjack @ irc #nginx):

колбиджек: У вас есть только один запасной вариант. Независимо от того, какое из @static или = 404 будет первым, проверяется на наличие в виде файла. что не удастся, и nginx перейдет к резервному

c33s: я не уверен, что понимаю, если я определю несколько параметров try_file, они не будут проверяться слева направо?

колбиджек: Верно, но все, кроме последнего, проверяются как файлы на диске. Итак, try_files $ uri @static = 404; ищет $ document_root $ uri, затем $ document_root @ static, и, если ни один из них не существует, выдает ошибку 404. try_files $ uri = 404 @static ищет $ document_root $ uri, затем $ document_root = 404, и если ни один из те, что существуют, внутренне перенаправляются на @static

c33s: значит, если @static не находится в локальной файловой системе, это имеет смысл только как последний вариант?

колбиджек: Правильно Все, кроме последнего аргумента, должны быть вещами, которые вы хотите проверить на наличие на диске

c33s: вы хотите ответить на serverfault, чтобы получить репутацию? в противном случае я бы скопировал ваш ответ на serverfault и сам ответил на свой вопрос ...

колбиджек: Давай, я слишком занят