Назад | Перейти на главную страницу

Как я могу настроить Apache для перенаправления подкаталога в репозиторий Subversion?

У меня есть старый репозиторий 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