
Ich habe Folgendes in meinem virtuellen Host für SSL-Verbindungen (mein virtueller Host ohne SSL sieht gleich aus, aber ohne den ersten Regelsatz für die Umleitung).
DocumentRoot /var/www/example.com/public/
<Directory "/var/www/example.com/public/">
#only mod_rewrite configuration is shown here
RewriteEngine on
RewriteBase /
RewriteCond $1 !=signup
RewriteCond $1 !=login
RewriteCond $1 !=welcome
RewriteCond $1 !=thankyou
RewriteRule ^(.*)$ http://example.com/$1 [L,R,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.+)$ index.php?q=$1 [L,QSA]
</Directory>
Meine Absicht besteht darin, dass alle nicht übereinstimmenden Seitenanforderungen (Anmelden|Einloggen|Willkommen|Danke) ohne weitere Verarbeitung an den virtuellen Host ohne SSL umgeleitet werden, andernfalls erfolgt keine Umleitung, sondern die Anforderung wird innerhalb des virtuellen SSL-Hosts verarbeitet.
Der erste RewriteRule-Satz kümmert sich um die Weiterleitung, während der zweite RewriteRule-Satz sich um die normale Seitenverarbeitung kümmert.
Ohne den ersten Regelsatz werden alle Anforderungen unter dem virtuellen SSL-Host korrekt geladen.
Mit dem ersten Regelsatz funktionieren Weiterleitungen, die nicht mit den aufgelisteten Ressourcen übereinstimmen, problemlos. Beispielsweise eine Anfrage für
https://example.com/about
Weiterleitungen zu
http://example.com/about
Aber wenn die Seiten „Anmeldung“, „Login“, „Willkommen“ und „Danke“ angefordert werden, tritt das Problem auf. Diese Anfragen werden ebenfalls auf die Nicht-SSL-Site umgeleitet, allerdings auf fehlerhafte Weise. Eine Anfrage für
https://example.com/signup
Weiterleitungen zu
http://example.com/index.php?q=signup
Es scheint, dass der erste Regelsatz nicht angeglichen wird (wie erwartet). Nachdem der zweite Regelsatz verarbeitet wurde, wird der erste Regelsatz erneut angewendet (nicht erwartet).
Ich kann dieses unerwartete Verhalten keiner dokumentierten Funktionalität zuordnen.
Irgendwelche Ideen?
Bearbeiten
Ich habe in der Dokumentation einige obskure Hinweise darauf gefunden, dass Apache die Regeln erneut ausführt, wenn eine Regelübereinstimmung in einem „Verzeichniskontext“ auftritt. Der Hinweis bezog sich jedoch auf .htaccess. Meine Neuschreibung erfolgt innerhalb eines <Directory>-Tags innerhalb meines <VirtualHost>-Tags. Ich teste derzeit, die Neuschreibung außerhalb des <Directory>-Kontexts zu verschieben – dies scheint das Verhalten sicherlich zu ändern, aber ich habe es noch nicht so hinbekommen, wie ich es brauche.
Bearbeiten
Das Problem wird sicherlich dadurch verursacht, dass Apache die Umschreibeverarbeitung neu startet, wenn die Regelverarbeitung in einem Verzeichniskontext erfolgt. Ich habe die Regelverarbeitung außerhalb des <Directory>-Tags verschoben. Jetzt funktionieren die RewriteCond-Zeilen jedoch nicht mehr ... z. B.
RewriteCond %{REQUEST_FILENAME} -f
weil Apache die angeforderte Ressource noch nicht in eine Dateizuordnung unter Verwendung des DocumentRoot aufgelöst hat. Was für ein Durcheinander.
Also stelle ich den Wert, den ich in DocumentRoot angebe, manuell vor RewriteCond. Das scheint jedoch ein schlechter Hack zu sein. Beispiel:
RewriteCond /var/www/example.com/public%{REQUEST_FILENAME} -f
Daher suche ich jetzt nach einer Möglichkeit, Apache daran zu hindern, den Umschreibvorgang in einem Verzeichniskontext neu zu starten. Oder, am zweitbesten, nach einer besseren Möglichkeit, die erforderlichen RewriteConds auf der Ebene <VirtualHost> anzugeben.
Antwort1
Ich schlage vor, Ihrer Konfiguration Folgendes hinzuzufügen. Dadurch erhalten Sie ein detailliertes Protokoll darüber, was mod_rewrite tut und warum. Das kann helfen, zu klären, warum Sie dieses Verhalten haben:
RewriteLog /tmp/rewrite.log RewriteLogLevel 9
Wenn Sie mit der Analyse fertig sind, entfernen Sie diese Zeilen unbedingt, da sie die Leistung beeinträchtigen.
Antwort2
Ich habe mich für die folgende Lösung entschieden und die Umschreibungen außerhalb aller <Directory ...>-Abschnitte platziert. Dadurch kann ich alle Anfragen, die nicht SSL sein sollten, auf die Nicht-SSL-Site umleiten und gleichzeitig alle statischen Inhalte über SSL bereitstellen (Bilder, CSS, JS usw.).
<VirtualHost ...>
...
RewriteEngine on
RewriteCond $1 !=signup
RewriteCond $1 !=login
RewriteCond $1 !=welcome
RewriteCond $1 !=thankyou
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^/(.*)$ http://example.com/$1 [R=303,QSA,L]
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteCond %{REQUEST_URI} !=/robots.txt
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^/(.+)$ /index.php?q=$1 [QSA,L]
...
</VirtualHost>