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

Nginx try_files gotcha

Хорошо, я уже давно пользуюсь этим правилом

location ~* /(?:abc12345|12abcdef)/(.*\.(jpe?g|gif|png)) {
    alias /usr/local/image/$1;
    error_page 404 /handler.php;
}

где, если файл изображения существует, он обслуживается - если файл не существует, пользовательская страница ошибки 404 с именем /handler.php работает для доставки товаров. если бы изображение не изменилось, оно вернуло бы 304 - новые изображения вернули бы 200. Почти идеально.

Проблема в том, что возвращать 404 с изображением неуместно - я должен принять запрос, определить, существует ли файл, а если не запустить обработчик и вернуть изображение - а не показывать 404.

Я попытался заменить error_page на try_files, но не получил желаемого результата:

 location ~* /(?:abc12345|12abcdef)/(.*\.(jpe?g|gif|png)) {
     alias /usr/local/image/$1;
     try_files $uri $uri/ /handler.php;
 }

Кажется, что в try_files ничего не совпадает, поэтому все запросы попадают в handler.php. Я понимаю, что псевдоним - это особый шаблон соответствия, но если я попытаюсь ввести

try_files "" /handler.php;

Что работает, но "" возвращает неверный тип содержимого (Content-Type: · application / octet-stream), а handler.php возвращает правильный (Content-Type: · image / jpeg)

конечно, я мог бы добавить "default_type image / jpeg;" чтобы установить значение по умолчанию, но я рискую вернуть тип содержимого jpeg, когда фактическое изображение может быть gif или png.

Я использую debian 6 - nginx-1.0.6-1 ~ dotdeb.2

Есть идеи, как это сделать?

Прежде всего, вы можете заставить Nginx возвращать код состояния из вашего скрипта при использовании error_page:

location ~* /(?:abc12345|12abcdef)/(.*\.(jpe?g|gif|png)) {
    alias /usr/local/image/$1;
    error_page 404 = /handler.php;
}

Этот знак равенства сообщает Nginx о необходимости вернуть код состояния из handler.php вместо того 404.

По состоянию на try_files, попробуйте эту конфигурацию:

location ~* /(?:abc12345|12abcdef)/(.*\.(jpe?g|gif|png)) {
    root /usr/local/image;
    try_files /$1 /handler.php;
}