У меня странный сценарий с этим правилом перезаписи:
RewriteCond img/$2/$3/$4/$1 -f
RewriteRule ^img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\.\w+)$ img/$2/$3/$4/$1 [L]
Структура каталогов для этого (упрощенная):
var/
images/
..
www/
.htaccess
img -> /var/images
Другими словами, изображения хранятся вне корневого веб-сайта в общей области хранения данных и связаны с корневым веб-каталогом. img
каталог через символическую ссылку. Имена изображений - это хеши. Для эффективности они хранятся в трехуровневой глубокой иерархии каталогов. Например:
0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg
хранится в
images/0a80/8e34/edaa/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg
Правило перезаписи просто перезаписывает имя файла во вложенной структуре каталогов.
Странно то, что RewriteCond
отлично работает в моих локальных системах, но не работает на тестовом сервере. Журнал отладки Apache явно говорит, что "-f
шаблон не совпадает »для этого условия. Если я просто удалю это условие, правило перезаписи будет работать нормально, и изображение будет отправлено.
Что могло вызвать -f
потерпеть неудачу для файлов, которые явно существуют?
FollowSymLinks
позволено. Apache версии 2.2.22-6ubuntu2 установлен через apt и практически не модифицирован. Работает с локальной установкой Apache 2.2.23 (через homebrew). Не удалось увидеть никаких значительных изменения между двумя версиями, которые должны вызвать это.
Некоторые более важные подробности о фактической структуре каталогов:
$ ls -l /var/www/myapp/current
[snip] /var/www/myapp/current -> /var/www/myapp/releases/20130418090750
$ ls -la /var/www/myapp/current/webroot
[snip]
[snip] .htaccess
[snip] img -> /usr/local/var/myapp/images
Корневой каталог Apache настроен как:
DocumentRoot /var/www/myapp/current/webroot
Если я напишу RewriteCond
так как:
RewriteCond /usr/local/var/myapp/images/$2/$3/$4/$1 -f
оно работает. Я бы предпочел не жестко указывать абсолютные пути, если их вообще можно избежать.
Может ли Apache запутать несколько уровней символических ссылок?
Если он работает на localhost, но не на test.com, я бы предположил, что это проблема с вашей файловой системой или это связано с более общей конфигурацией сайта, которую вы можете принять как должное. Вы установили обе операционные системы, а затем установили одни и те же пакеты, используя одну и ту же процедуру на обеих машинах? Как выглядела каждая из конфигураций по умолчанию, поставляемых с каждым Apache? Как насчет пакетов, которые изменили конфигурацию по умолчанию, прежде чем вы даже взглянули?
Возможно, ваши версии apache примерно одинаковы, но если они были из разных источников, конфигурация по умолчанию могла быть другой и впоследствии могла быть изменена по-другому. Проверьте свою конфигурацию, начиная сверху. Что отличается? Попытка заставить их выглядеть точно так же (не только ваши перезаписи, но и контексты Virtual-Host или Server).
Контекст ваших директив Rewrite, вероятно, поможет (поскольку я вижу, что это проблема области действия). Переписываются ли в контексте VirtualHost, Document-Root, Directory?
Самая большая разница, которую я вижу из ваших сообщений между успехом и неудачей, заключается в следующем:
Родственник
RewriteCond img/$2/$3/$4/$1 -f
Абсолютное
RewriteCond /usr/local/var/myapp/images/$2/$3/$4/$1 -f
Apache может найти файл, поэтому у него не должно быть разрешений или чего-либо подобного. Вы используете какие-либо директивы Alias (localhost vs test.com)? Если нет, возможно, вам стоит попробовать использовать псевдоним именно для этого:
/ var / www / myapp / current -> / var / www / myapp / Release / 20130418090750
Поместите хотя бы один жесткий путь в вашу корневую конфигурацию, для которого не требуется символическая ссылка. Вы можете завершить свои перезаписи в контексте Справочника ...
<Directory /var/www/myapp/current/webroot>
rewrite statements...
</Directory>
Что произойдет, если вы сохраните свою сломанную конфигурацию на test.com, но там, где у вас в настоящее время есть символические ссылки, попробуйте скопировать фактические каталоги (временно), начиная с корня. Просто убедитесь, что в настройках Symlink нет плавающих. Избавьтесь от как можно большего количества символических ссылок и поместите их обратно по порядку.
На самом деле, я еще никогда не видел статьи, в которой есть руководство по RewriteCond
чтобы получить переменную из RewriteRule
под ним .. Однако вы все равно можете попробовать добавить RewriteBase
директива в верхней части вашего .htaccess файл:
RewriteBase /www/
Или это, просто попробуйте оба:
RewriteBase /var/www/
Или вы можете попробовать один из следующих наборов директив, но БЕЗ УЧЕТА любой RewriteBase
директива, указанная выше:
RewriteCond /www/img/$2/$3/$4/$1 -f
RewriteRule ^www/img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\.\w+)$ /www/img/$2/$3/$4/$1 [L]
Или вы даже можете попробовать:
RewriteCond /var/www/img/$2/$3/$4/$1 -f
RewriteRule ^var/www/img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\.\w+)$ /var/www/img/$2/$3/$4/$1 [L]
Прошу прощения за копирование формата вашего условия и правила перезаписи, потому что вы сказали, что «Это работает в вашей местной системе разработки». Но это простое правило, которое я вам рекомендую, если вы просто хотите переписать /$var1.$var2 в /images/0a80/8e34/edaa/$var1.$var2, вы даже можете добавить остальные статически, один за другим:
RewriteRule ^([a-zA-Z0-9_-]+).([a-zA-Z]{3})$ /images/0a80/8e34/edaa/$var1.$var2
Или вы даже можете попробовать это, если хотите переписать /img/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg динамически в /img/0a80/8e34/edaa/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg с условием, если динамический URL-адрес, на который выполняется переназначение, является файлом:
RewriteCond /img/$2/$3/$4/$1\.$5 -f
RewriteRule ^img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28})\.([a-z]{3})$ /img/$2/$3/$4/$1.$5
Помните, что персонажи на "0a80", «8e34» и "edaa" должно быть точно как 4 и символы. в "eeffd973e4138789a4957d6b6a26" должно быть как 28 и в "jpg" должно быть как 3. Надеюсь, что это сработает, но сомневаюсь ..
Обратные ссылки: «вверх» (rewriteCond) на «вниз» (RewriteRule). В примере, который вы публикуете, это похоже на «вниз» на «вверх». И обратные ссылки с%, а не с $.
Обратные ссылки RewriteCond: это обратные ссылки в форме% N (0 <= N <= 9). От% 1 до% 9 обеспечивают доступ к сгруппированным частям (опять же, в скобках) шаблона из последнего совпавшего RewriteCond в текущем наборе условий. % 0 обеспечивает доступ ко всей строке, соответствующей этому шаблону.
Вы можете попробовать это:
RewriteBase /
RewriteCond %{REQUEST_URI} /img/([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{28}\.\w+)$
RewriteCond %{DOCUMENT_ROOT}/test/%1/%2/%3/%4 -f
RewriteRule .* img/%1/%2/%3/%4 [L]
Сначала регулярное выражение для поиска переменных. Создается путь к файлу, содержащему переменные, и проверяется, существует ли файл
Я использую % {DOCUMENT_ROOT} для тестирования на моем локальном сервере. Если у вас нет этих файлов изображений в том же DocumentRoot, вам понадобится ПОЛНЫЙ ПУТЬ лайк:
RewriteCond /var/www/cache_images/test/%1/%2/%3/%4 -f