Mr.KTO blog


  • Рубрики

  • Поиск

  •  
      
  • Поиск
  • реклама на mrkto.com





Что можно сделать с Mod_Rewrite

Здесь:

  1. HTTP-аутентификация в PHP-CGI (а не только как модуль Apache)
  2. Поддомен на папку (автоматические VirtualHost'ы-субдомены)
  3. Редирект на главный домен (с host.com на www.host.com или наоборот)
  4. (по теме) как создать файл .htaccess в Windows


1. HTTP-аутентификация для PHP-CGI

«HTTP-аутентификация в PHP возможна только при запуске РНР как Apache-модуля» - так написано в документации по PHP.

Итак, если в <apache_dir>/conf/httpd.conf включён модуль Mod_Rewrite (LoadModule...),
то создаём файл .htaccess в папке сайта и добавляем следующие строки:

<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine On
  RewriteCond %{HTTP:Authorization} !^$
  RewriteRule ^file\.php$ file.php?HTTP_AUTH=%{HTTP:Authorization} [QSA,L]
</IfModule>

Первая строка (Options) может быть не нужна в зависимости от настроек хостинга.
Далее - мы проверяем, что есть непустой хидер Authorization и при запросе к file.php добавляем к нему GET-параметр HTTP_AUTH, при этом сохраняя другие параметры (QSA).

P.S: Также можно установить переменную окружения (environment valiable):

  RewriteEngine on
  RewriteRule .* - [E=HTTP_AUTH:%{HTTP:Authorization},L]

Она будет доступна через $_SERVER['HTTP_AUTH'], но скорее всего $_SERVER['REDIRECT_HTTP_AUTH'] - этот префикс добавляет апач.

Ещё информация об этом способе: http://joseph.randomnetworks.com/archives/...

После этого надо добавить в начало file.php:

if (isset($_GET['HTTP_AUTH'])) {
    preg_match('/^Basic\s+(.*)$/i', $_GET['HTTP_AUTH'], $mHA) or exit("Not supported HTTP_AUTH");
    list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = split(":", base64_decode($mHA[1]));
}

Теперь пример из документации по php будет работать!

2. Поддомен на папку (автоматические VirtualHost'ы-субдомены)


Хорошая документация по Apache Mod_Rewrite находится по адресу: http://www.pcre.ru/docs/apache/, особое внимание советую обратить на статью Преобразование ссылок с помощью Apache.
Также можно почитать перевод официального дока на на OpenNET [1, 2].

Если в httpd.conf для VirtualHost site.com настроен ServerAlias *.host.com, то по адресу host.com, www.host.com, sub.host.com будут открываться файлы из директории сайта (из DocumentRoot).
Задача в том, чтобы была возможность создавать субдомены без редактирования конфига сервера. Например, чтобы по адресу site1.host.com/* выводились странички из папки /subdomains/site1/* (относительно DocumentRoot).

По запросу "subdomains Mod_Rewrite" по первой ссылке сразу предлагается решение.
Но после добавления данных строк в .htaccess мы видим HTTP 500 Internal Server Error.

Если в конфиге апача указан LogLevel debug, то в <apache_dir>/logs/error.log будут строки:

Request exceeded the limit of 10 internal redirects due to probable configuration error.
Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
..........
..........
redirected from r->uri = /subdomains/site1/subdomains/site1/path/file.htm
redirected from r->uri = /subdomains/site1/path/file.htm
redirected from r->uri = /path/file.htm

Мы делали запрос к site1.host.com/path/file.htm
Как видим - Mod_Rewrite делает внутренние редиректы по описанным нами правилам, здесь заметно зацикливание, точнее - рекурсия :)

Спасибо Maus-у с форума на dklab: http://forum.dklab.ru/viewtopic.php?p=91591#91591.

Финальная версия .htaccess'а выглядит так:

<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine On
  RewriteBase /
  RewriteCond %{ENV:REDIRECT_RDR} ^$
  RewriteCond %{HTTP_HOST} ^(.+\.)?([^\.]+)\.[^\.]+\.[^\.]+\.?$
  RewriteCond %2 !^www$
  RewriteRule ^(.*)$ subdomains/%2/$1 [L,E=RDR:1]
</IfModule>

%2 - это обратная ссылка из RewriteCond CondPattern, а
$1 - обратная ссылка из RewriteRule шаблона.

[UPDATE: Можно вместо строк с RDR добавить условие:

RewriteCond %{REQUEST_URI} !^/subdomains/

]

Здесь есть ещё одна проблемка. Если вы захотите запустить *.php файл с одного из созданных таким способом поддоменов, то получите ошибку: HTTP 404 - Не удается найти веб-страницу.
А если вы в IE/Сервис/Свойства_обозревателя/Дополнительно/ отключили "Выводить подробные сообщения об ошибках http", то: No input file specified.

Скорее всего это из-за того, что веб-сервер не устанавливает переменную окружения SCRIPT_FILENAME.

Чтобы решить эту задачу, придётся прописать отдельно, в явном виде условия для файлов *.php (настолько явно, что ^.*\.php$ - не пойдёт):

<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine On
  RewriteBase /

  RewriteCond %{ENV:REDIRECT_RDR} ^$
  RewriteCond %{HTTP_HOST} ^(.+\.)?([^\.]+)\.[^\.]+\.[^\.]+\.?$
  RewriteCond %2 !^www$
  RewriteRule ^([a-zA-Z0-9`~!@#$%^&()\-+";=\\/|]*)\.php$ subdomains/%2/$1.php [L,E=RDR:1]

  RewriteCond %{ENV:REDIRECT_RDR} ^$
  RewriteCond %{HTTP_HOST} ^(.+\.)?([^\.]+)\.[^\.]+\.[^\.]+\.?$
  RewriteCond %2 !^www$
  RewriteCond %{REQUEST_URI} !\.php$
  RewriteRule ^(.*)$ subdomains/%2/$1 [L,E=RDR:1]

</IfModule>

Если вы хотите запретить дотуп к *.php файлам, - то НЕ рекомендую писать «RewriteRule \.php$ - [F]» (т.к. тогда по адресу host.com/subdomains/site1/file.php файл будет доступен).
Лучше в папке /subdomains/ создать .htaccess с:

<Files ~ "\.php$">
  Order allow,deny
  Deny from All
</Files>


3. Редирект на главный домен

Добавьте в .htaccess следующее:

<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine On
  RewriteBase /
  RewriteCond %{HTTP_HOST} !^(www\.host\.com|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|0x[0-9a-f]{8})$ [NC]
  RewriteCond %{HTTP_HOST} !^$
  RewriteRule ^(.*)$ http://www.host.com/$1 [R=301,L]
</IfModule>

Переводится, как: Если хост не www.host.com или ip (82.146.52.138) или ip в hex (0x5292348A),
и если хост не пустой (вроде в протоколе HTTP/1.0 не всегда поддерживается хидер Host)
То редирект 301 Moved Permanently на http://www.host.com/*

Можно убрать альтернативы из первого условия, тогда:

  RewriteCond %{HTTP_HOST} !^www\.host\.com$ [NC]

Редирект можно сделать временным, если заменить R=301 на просто R.


4. Как создать файл .htaccess в Windows

Дело в том, что Windows не позволяет переименовать файл в файл без имени.

Вот решение:
Пуск/Выполнить или WinKey + R

cmd /C q > С:\путь-к-файлу\.htaccess

«cmd /C» - это выполнение указанной команды (строки) с последующим завершением.
«команда > имя_файла» - это оператор для записи результата команды в файл,
Предполагается, что команда "q" (q.exe, q.com, q.bat) не существует.
Можно и записать пустую строку в файл:

cmd /C echo; > С:\путь-к-файлу\.htaccess
habrahabr.ru google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru rumarkz.ru memori.ru moemesto.ru moikrug.ru myscoop.ru mister-wong.ru rucity.com vaau.ru

Комментарии (3) на “Что можно сделать с Mod_Rewrite”

  1. JCP пишет:

    А вот и неправда! Винда позволяет переименовывать файл в файл без имени. Проверено в XP.

  2. mrkto пишет:

    Можно в блокноте "Сохранить как" .htaccess
    Или в консоле (Win+R, cmd): ren c:\file.ext .ext

    Но стандартное "Переименовать" в контекстном меню, или "два клика с задержкой" на имени файла приведут к: "Следует ввести имя файла".

    В конце концов, мой блог бы тогда не находили по запросам "как создать .htaccess под windows".

  3. grang пишет:

    JCP, нельзя переименовывать файл.
    Это только визуальное изменение будет, а свойства останутся.

Оставить комментарий