У меня есть старый репозиторий Subversion, который был настроен как единственный репозиторий на машине. Мы получили доступ к таким URL-адресам:
http://myserver.com/svn/trunk/...
http://myserver.com/svn/branches/...
Мы переезжаем на новый сервер, где у нас есть несколько репозиториев, настроенных при установке dav-svn под apache2, поэтому по умолчанию мы получаем к ним доступ следующим образом:
http://myserver.com/svn/repo/trunk/
http://myserver.com/svn/repo/branches/
or
http://192.168.0.1/svn/repo/trunk/
http://192.168.0.1/svn/repo/branches/
Мне нужно переместить старое репо на новый компьютер без изменения URL-адресов, поэтому я хочу настроить репо, а затем перенаправить его в apache в зависимости от URL-адреса, поэтому:
http://myserver.com/svn/trunk
перенаправляет на
http://myserver.com/svn/repo/trunk
прозрачно. Я могу заставить его перенаправить на URL-адрес на основе IP, но когда я пытаюсь перенаправить его с использованием самого доменного имени, он выдает запрещенные сообщения или «Не удалось открыть запрошенную файловую систему SVN»:
<VirtualHost *:80>
ServerName myserver.com
ServerAlias www.myserver.com
DocumentRoot /var/www/vhosts/myserver.com/html
CustomLog /var/www/vhosts/myserver.com/logs/access_log combined
ErrorLog /var/www/vhosts/myserver.com/logs/error_log
RewriteEngine On
RewriteRule ^/svn(.*)$ /svn/myrepo$1 [L,QSA]
# THE FOLLOWING WORKS, BUT IS NOT TRANSPARENT
# RewriteRule ^/svn(.*)$ http://192.168.0.1/svn/myrepo$1 [L,QSA]
<Directory /var/www/vhosts/myserver.com/html>
AllowOverride All
</Directory>
</VirtualHost>
И файл subversion.conf:
<Location /svn>
DAV svn
SVNParentPath /var/svn/repository
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /var/svn/repository/.htpasswd
Require valid-user
</Location>
Идеи как решить проблему?
Краткий ответ: используйте PT
в вашем RewriteRule.
Во-первых, небольшая предыстория Apache. Когда Apache получает запрос, он выполняет процесс сопоставления этого запроса с локальным хранилищем. После этого у Apache фактически есть две части данных о том, что вы запрашивали. URL-адрес запроса и путь к файлу. Итак, просьба о /svn/blah
переводится на /var/www/vhosts/myserver.com/html/svn/blah
и этот путь хранится отдельно. mod_rewrite позволяет настроить это поведение для маршрутизации URL-адресов туда, куда вы хотите.
Теперь два RewriteRule, которые у вас есть, неявно делают разные вещи.
Первый у вас там переписать. Требуется URL-адрес вроде /svn/blah
и вместо того, чтобы использовать поведение выше, он отображает его так, как если бы вы действительно запросили /svn/myrepo/blah
, поэтому результирующий путь к файлу будет /var/www/vhosts/myserver.com/html/svn/myrepo/blah
. Однако вот и каменный вопрос: он не изменяет запрошенный URL. URL-адрес запроса все еще /svn/blah
, apache только что считает, что файл находится по адресу .../svn/myrepo/blah
скорее, чем .../svn/blah
.
Почему это так важно, спросите вы? Поскольку модуль Subversion не использует путь к файлу. Он смотрит на URL-адрес запроса. Таким образом, apache и mod_rewrite просто зря потратили время на все это, потому что mod_dav_svn просто игнорирует это. Что вам нужно, так это для mod_rewrite изменить URL-адрес запроса. И вот что PT
делает. Он изменяет как URL-адрес запроса, так и путь к файлу, поэтому позже, когда он доберется до mod_dav_svn, он увидит измененный URL-адрес.
Второй - перенаправление. Поскольку замена начинается с http://
и apache не имеет виртуального хоста с именем 192.168.0.1
, предполагается, что вы действительно хотели поставить R
в ваших флагах, так как он не может перевести это в путь к файлу. Это отправляет обратно сообщение «Привет, это здесь» клиенту Subversion, и он делает еще один запрос для этого.
Теперь, сказав все это, у вас никогда не будет больше одного репозитория с этой настройкой, если вы не сделаете что-нибудь, чтобы заставить mod_rewrite пропускать URL-адреса других репозиториев. mod_rewrite весело поменяет /svn/bignewproject/blah
в /svn/myrepo/bignewproject/blah
для тебя каждый раз. Вы можете добавить правило перед RewriteRule, которое у вас есть, например:
RewriteRule ^/svn/(myrepo|myotherrepo|coolproject|stuff|etc)/ - [S=1]
Это заставит его пропустить следующее правило. Однако с этого момента вы собираетесь обновлять его вручную. Возможно, вам удастся реализовать что-то автоматизированное с помощью магии RewriteCond, но это, вероятно, будет непросто. Я не очень знаком с этим, так что кто-то другой должен был бы вам помочь.
Если это используется только небольшой группой людей, тогда вам может быть лучше полностью пропустить этот переписывающий материал и просто обновить все рабочие копии. svn switch --relocate
предназначен специально для ситуаций, когда репозиторий перемещается, и вы просто хотите обновить свою рабочую копию, не проверяя ее снова. Я понимаю, что есть ситуации, когда это просто невозможно.
К сожалению, Subversion использует больше, чем просто команды GET и POST, поэтому я думаю, что лучший способ перенаправления - это использовать Apache mod_proxy для обратного прокси-сервера запросов. Я не уверен, что есть способ лучше
Обратный прокси Apache / Subversion, описанный на этой странице http://silmor.de/49