mod_rewrite RewriteCond на основе Last-modified? (.htaccess)

Я знаю, что мы можем легко создать RewriteCond на основе любого заголовка http request. Но можем ли мы проверить (некоторые) заголовки response, которые будут отправлены? В частности, Последнее изменение?

Я хочу переписать URL-адрес только тогда, когда дата последнего изменения старше 30 минут, и я пытаюсь избежать накладных расходов на делегирование этой проверки файлу php каждый раз, когда запрашивается файл из этого каталога.

Заранее спасибо!


person Lea Verou    schedule 23.08.2009    source источник


Ответы (3)


Исходящие заголовки не существуют до тех пор, пока не будет действовать much позже, чем mod_rewrite. Также в mod_rewrite нет встроенной функции проверки времени модификации файла, поэтому самый близкий способ ее использования — создание RewriteMap из различных программ внешней перезаписи, чтобы узнать, был ли изменен рассматриваемый файл.

Если я правильно понимаю ваше приложение, вы также можете подумать о том, чтобы задание cron удаляло файлы в этом каталоге старше 30 минут, а затем перезаписывало условие отсутствия файла.

person chaos    schedule 23.08.2009
comment
Ага, очевидно. Но заголовок Last-modified в то время действительно существовал, поэтому я подумал, что, возможно, для этого что-то есть. Я думаю, что нет :-( Что касается cron, это именно то, чего я пытаюсь избежать. - person Lea Verou; 23.08.2009

Нет, это невозможно. Но вы можете использовать карту перезаписи, чтобы получить эту информацию из программа с меньшими накладными расходами, чем PHP, возможно, сценарий оболочки.

Вот пример bash-скрипта:

#!/usr/bin/env bash
while read line; do
    max_age=${line%%:*}
    filename=${line#*:}
    if [[ -f $filename ]]; then
        lm=$(stat -f %m "$filename")
        if [[ $(date +%s)-$lm -le $max_age ]]; then
            echo yes
        else
            echo no
        fi
    else
        echo no
    fi
done

Объявление карты перезаписи необходимо поместить в файл конфигурации вашего сервера или виртуального хоста, поскольку программа запускается только один раз, а затем ожидает ввода:

RewriteMap last-modified-within prg:/absolute/file/system/path/to/last-modified-within.sh

И затем вы можете использовать эту карту перезаписи следующим образом (пример .htaccess):

RewriteCond %{last-modified-within:30:%{REQUEST_FILENAME}} =yes
RewriteRule ^foo/bar$ - [L]
RewriteRule ^foo/bar$ script.php [L]
person Gumbo    schedule 23.08.2009
comment
Поскольку PHP уже загружен и работает внутри процесса Apache, совсем не ясно, будет ли создание нового bash — по одному на запрос — быстрее. Я предполагаю, что это не так. - person derobert; 23.08.2009
comment
Вау, это умно! Большое спасибо за ваше время. Однако как насчет возражения Дероберта выше? - person Lea Verou; 23.08.2009
comment
@derobert: Ах, извини, забыл об этом. Программа просто запускается один раз, а затем ожидает ввода в SDTIN. - person Gumbo; 23.08.2009
comment
Я должен признать, что это не сработало для меня. Но вот как это будет сделано. - person Gumbo; 23.08.2009
comment
Даже если ваш bash-скрипт продолжает работать, вы все равно создаете как минимум stat и date для каждого запроса. Кстати: разве это не должно быть [ ... ], а не [[ ... ]]? - person derobert; 23.08.2009

Рассматривали ли вы возможность использования mod_proxy, mod_cache и/или squid? Похоже, вы пытаетесь запустить собственное кэширование...

person derobert    schedule 23.08.2009
comment
Да, я пытаюсь кэшировать некоторые сгенерированные php/gd изображения и воссоздавать их каждые 30 минут, если это необходимо (= если кто-то действительно их запрашивает). Думаете, mod_proxy, mod_cache или squid могут помочь? Честно говоря, я никогда в них не вникал. Я всегда думал, что они для более сложных вещей. - person Lea Verou; 23.08.2009
comment
Да, вы выполняете веб-кеширование, и это именно то, для чего они предназначены. Естественно, вам следует заморачиваться с этой оптимизацией только в том случае, если она имеет значение (например, у вас есть необходимый объем трафика). - person derobert; 23.08.2009