Мод переписать правило для кэшированных страниц - PullRequest
0 голосов
/ 15 декабря 2010

Я кеширую страницы в моем приложении (Rails) на основе поддоменов. Страницы для определенных действий кэшируются в / public / cache / (поддомен) /. Приложение работает под Apache с Phusion Passenger. Кеширование работает нормально. Проблема в том, что Apache не собирает кэшированные страницы и обходит Rails, как должно быть. Мои правила переписывания неверны, и мне нужна помощь в их исправлении.

В качестве одного из примеров я использовал предложение, расположенное по адресу: https://github.com/yeah/page_cache_fu#readme,, которое выглядит следующим образом:

RewriteMap uri_escape int:escape
<Directory /var/www/example.com/current/public>

  RewriteEngine On
  RewriteCond %{REQUEST_METHOD} GET [NC]
  RewriteCond %{DOCUMENT_ROOT}/cache/%{HTTP_HOST}%{REQUEST_URI}%{QUERY_STRING}.html -f
  RewriteRule ^([^.]+)$ cache/%{HTTP_HOST}/$1${uri_escape:%{QUERY_STRING}}.html [L]

  RewriteCond %{REQUEST_METHOD} GET [NC]
  RewriteCond %{DOCUMENT_ROOT}/cache/%{HTTP_HOST}/index.html -f
  RewriteRule ^$ cache/%{HTTP_HOST}/index.html

Проблема с этим в том, что он, похоже, ожидает, что каталог будет полным http-хостом (т.е. он ищет в cache / subdomain.example.com, а не просто cache / subdomain).

Редактировать: Даже когда я изменяю приложение Rails для кэширования на cache / subdomain.example.com, Apache по-прежнему не использует их, поэтому кажется, что здесь есть нечто большее, чем просто аспект субдомена.

Может ли кто-нибудь помочь мне придумать правильное правило?

Edit (2):

Я упростил свое переписывание до следующего (просто чтобы попытаться добраться до рабочей отправной точки):

RewriteEngine On
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$ [NC]
RewriteCond ^stats$ cache/%1/stats.html [L]

Я думаю, что это приведет к тому, что http://abc.example.com/stats будет переписано в http://abc.example.com/cache/abc/stats.html

Это не так. Я также добавил запись RewriteLog, и то, что я вижу там, заставляет меня думать, что она пытается перенаправить на http://abc.example.com/var/www/example.com/current/public/cache/abc/stats.html. Это еще раз подтверждается тем, что если я добавлю опцию 'R' вместе с 'L', которую я вижу в моем браузер http://abc.example.com/var/www/....etc. т.е. кажется, что он добавляет полный корень документа, а не просто публичную часть.

Конечно, результатом вышеизложенного является то, что в браузер возвращается ошибка 404.

Вы видите, что все еще не так с моим правилом?

Редактировать: На самом деле это ошибка.

http://code.google.com/p/phusion-passenger/issues/detail?id=563

1 Ответ

1 голос
/ 15 декабря 2010

Хорошо, это выглядит так, как будто оно должно работать, но это не так. Я провел много испытаний с этим, и похоже, что проблема в ^([^.]+)$ в RewriteRule. Я сделал это в Google, и кажется, что это достаточно распространенная модель, поэтому я не понимаю, в чем проблема. Я просто знаю, что когда я использую этот шаблон в RewriteRule, правило не выполняется. Если я изменю его на ^([^.]+), то, похоже, будет работать.

Надеюсь, кто-то с большим опытом работы с mod_rewrite может прийти и объяснить us , в чем может быть проблема с этим шаблоном.

Редактировать: Я только что понял проблему с ^([^.]+)$:

Поскольку вы создаете кеш, то «обычный» файл будет существовать на своем обычном месте. Это означает, что если вы спросите у сервера /file, то, в зависимости от вашей конфигурации, он скажет: «Эй, file не существует, поэтому давайте попробуем расширение по умолчанию .html!» и так он уходит и находит file.html. Теперь, когда вы попадете в RewriteRule, регулярное выражение ^([^.]+)$ будет сопоставлено с file.html NOT file.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10, ^([^.]+)$ говорит 'начало строки, за которым следует столько непериодических символов, сколько вы можете захватить, а затем конец строки', что отлично работает против file, потому что оно не содержит точек. Он не работает против file.html, потому что ^[^.]+ будет совпадать с file, но когда регулярное выражение ожидает найти конец строки (то есть $), он вместо этого находит .html и завершается неудачей.

Причина, по которой работает ^(.*)$, заключается в том, что гарантируется, что только .* будет всей строкой, поскольку .* соответствует «какому-либо из любого символа», поэтому между * не может существовать символ, который может существовать 1037 * и $ частей регулярного выражения. Это не относится к [^.]+.


Чтобы извлечь поддомен, вам нужно будет сослаться на RewriteCond. По сути, если вы перехватываете ссылку (то есть инкапсулируете что-то внутри паренов) в RewriteCond, эти ссылки доступны для RewriteRule, который следует сразу за ним.

Например, если я написал это:

 RewriteCond %{HTTP_HOST} ^([^.]+)\.example.com

Тогда в скобках будет указан поддомен - обратите внимание на () вокруг [^.]+

Если бы тогда я написал RewriteRule на следующей строке, захваченный выше текст стал бы доступен как %1.

Итак, ваш RewriteRule будет выглядеть так:

 RewriteRule ^([^.]+) cache/%1/$1${uri_escape:%{QUERY_STRING}}.html [L]

Надеюсь, это поможет.

...