Die Überprüfung der vorhandenen RewriteCond-Datei schlägt für vorhandene Dateien fehl


7

Ich habe ein seltsames Szenario mit dieser Umschreiberegel:

RewriteCond img/$2/$3/$4/$1 -f
RewriteRule ^img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\.\w+)$ img/$2/$3/$4/$1 [L]

Die Verzeichnisstruktur hierfür ist (vereinfacht):

var/
  images/
    ..
  www/
    .htaccess
    img -> /var/images

Mit anderen Worten, Bilder werden außerhalb der Webroot in einem allgemeinen Datenspeicherbereich gespeichert und imgüber eine symbolische Verknüpfung mit dem Webroot- Verzeichnis verknüpft. Bildnamen sind Hashes. Aus Effizienzgründen werden sie in einer dreistufigen tiefen Verzeichnishierarchie gespeichert. Zum Beispiel:

0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg

gespeichert ist bei

images/0a80/8e34/edaa/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg

Die Umschreiberegel schreibt einfach den Dateinamen in die verschachtelte Verzeichnisstruktur.

Das Seltsame ist, dass das RewriteCondauf meinen lokalen Systemen gut funktioniert, aber auf einem Testserver fehlschlägt. Das Apache-Debug-Protokoll sagt ausdrücklich, dass das " -fMuster nicht übereinstimmt" für diese Bedingung. Wenn ich diese Bedingung einfach entferne, funktioniert die Umschreiberegel einwandfrei und das Bild wird bereitgestellt.

Was kann -fbei eindeutig vorhandenen Dateien zum Fehlschlagen führen?

FollowSymLinksist erlaubt. Apache Version 2.2.22-6ubuntu2 über apt installiert und kaum verändert. Funktioniert mit einer lokalen Installation von Apache 2.2.23 (über Homebrew). Es konnten keine signifikanten Änderungen zwischen den beiden Versionen festgestellt werden, die dies verursachen sollten.


Einige weitere möglicherweise wichtige Details zur tatsächlichen Verzeichnisstruktur:

$ ls -l /var/www/myapp/current
[snip] /var/www/myapp/current -> /var/www/myapp/releases/20130418090750

$ ls -la /var/www/myapp/current/webroot
[snip]
[snip] .htaccess
[snip] img -> /usr/local/var/myapp/images

Die Apache-Webroot ist wie folgt konfiguriert:

DocumentRoot /var/www/myapp/current/webroot

Wenn ich das schreibe RewriteCondals:

RewriteCond /usr/local/var/myapp/images/$2/$3/$4/$1 -f

Es klappt. Ich würde es jedoch vorziehen, absolute Pfade nicht fest zu codieren, wenn dies überhaupt vermeidbar ist.

Darf Apache durch die verschiedenen Ebenen von Symlinks verwirrt sein?


Was ist mit MultiViews?
Felipe Alameda A

MultiViews sind aktiviert. Könnte das die Ursache sein? Wie das?
Täuschung

Interessant. Ich werde prüfen, ob das einen Unterschied macht.
Täuschung

Nein, tut mir leid zu berichten, dass es nichts geändert hat.
Täuschung

1
@Servant Was ist bitte nicht klar? Die RewriteCond -fRegel sieht die umgeschriebene Datei nicht, obwohl dies der RewriteRuleFall ist. Die Frage ist warum?
Täuschung

Antworten:


1

Eigentlich habe ich noch nie einen Artikel gesehen, der ein Tutorial RewriteCondzum Abrufen einer Variablen enthält RewriteRule. Sie können jedoch weiterhin versuchen, eine RewriteBaseDirektive oben in Ihre .htaccess- Datei einzufügen :

RewriteBase /www/

Oder probieren Sie einfach beide aus:

RewriteBase /var/www/

Oder Sie können unter einer dieser Sätze von Richtlinien versuchen , aber Unzeit jede RewriteBaseRichtlinie , dass der oben aufgeführt ist :

RewriteCond /www/img/$2/$3/$4/$1 -f
RewriteRule ^www/img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\.\w+)$ /www/img/$2/$3/$4/$1 [L]

Oder Sie können es sogar versuchen:

RewriteCond /var/www/img/$2/$3/$4/$1 -f
RewriteRule ^var/www/img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\.\w+)$ /var/www/img/$2/$3/$4/$1 [L]

Es tut mir leid, dass ich das Format Ihrer Umschreibbedingung und -regel kopiert habe, weil Sie gesagt haben, dass "es auf Ihrem lokalen Entwicklungssystem funktioniert". Dies ist jedoch die einfache Regel, die ich Ihnen empfehle, wenn Sie /$var1.$var2 nur in /images/0a80/8e34/edaa/$var1.$var2 umschreiben möchten . Sie können die anderen sogar einzeln statisch hinzufügen ::

RewriteRule ^([a-zA-Z0-9_-]+).([a-zA-Z]{3})$ /images/0a80/8e34/edaa/$var1.$var2

Oder Sie können dies auch versuchen , wenn Sie neu zu schreiben wollen /img/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg dynamisch in /img/0a80/8e34/edaa/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg mit Bedingung , wenn die dynamische URL , wo es eine Datei ist Remapping:

RewriteCond /img/$2/$3/$4/$1\.$5 -f
RewriteRule ^img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28})\.([a-z]{3})$ /img/$2/$3/$4/$1.$5

Denken Sie daran, dass die Zeichen auf "0a80" , "8e34" und "edaa" genau 4 und die Zeichen sein müssen. in "eeffd973e4138789a4957d6b6a26" muss 28 sein und in "jpg" muss 3 sein. Ich hoffe, dass dies funktioniert, aber ich bezweifle ..


1
RewriteBasedient zur Angabe einer URL , dies gilt in diesem Fall nicht wirklich. Die Verwendung des absoluten Pfads in RewriteCondfunktioniert zwar, aber um systemspezifische .htaccess-Dateien zu vermeiden, möchte ich dies vermeiden. Ich bin auch einfach an einer Erklärung interessiert, warum es nicht funktioniert, da ich das überhaupt nicht brauche RewriteCond.
Täuschung

1

Wenn es auf localhost funktioniert, aber nicht auf test.com, ist es vermutlich ein Problem mit Ihrem Dateisystem oder es hängt mit einer allgemeineren Site-Konfiguration zusammen, die Sie möglicherweise für selbstverständlich halten. Haben Sie beide Betriebssysteme installiert und dann dieselben Pakete mit demselben Verfahren auf beiden Computern installiert? Wie sah jede der Standardkonfigurationen aus, die mit jedem Apache geliefert wurden? Was ist mit Paketen, die die Standardkonfiguration geändert haben, bevor Sie überhaupt einen Blick darauf geworfen haben?

Möglicherweise sind Ihre Apache-Versionen nahezu ähnlich, aber wenn sie aus unterschiedlichen Quellen stammen, war die Standardkonfiguration möglicherweise anders und wurde möglicherweise später anders geändert. Überprüfen Sie Ihre Konfiguration von oben. Was ist anders? Versuchen Sie, sie genau gleich aussehen zu lassen (nicht nur Ihre Umschreibungen, sondern auch Virtual-Host- oder Server-Kontexte).

Der Kontext Ihrer Rewrite-Anweisungen würde wahrscheinlich helfen (da ich sehe, dass dies eine Frage des Geltungsbereichs ist). Befinden sich die Umschreibungen im Kontext von VirtualHost, Document-Root, Directory?

Der größte Unterschied, den ich in Ihren Beiträgen zwischen Erfolg und Misserfolg sehe, ist folgender:

Relativ

RewriteCond img/$2/$3/$4/$1 -f

Absolut

RewriteCond /usr/local/var/myapp/images/$2/$3/$4/$1 -f

Apache ist in der Lage, die Datei zu finden, daher sollten es keine Berechtigungen oder ähnliches sein. Verwenden Sie Alias-Direktiven (localhost vs test.com)? Wenn nicht, sollten Sie vielleicht versuchen, dies speziell zu aliasen:

/ var / www / myapp / current -> / var / www / myapp / release / 20130418090750

Fügen Sie mindestens einen festen Pfad in Ihre Stammkonfiguration ein, für den kein Symlink erforderlich ist. Sie können Ihre Umschreibungen in einem Verzeichniskontext abschließen ...

<Directory /var/www/myapp/current/webroot>
    rewrite statements...
</Directory>

Was passiert, wenn Sie Ihre fehlerhafte Konfiguration auf test.com beibehalten, aber derzeit Symlinks haben, versuchen Sie, die tatsächlichen Verzeichnisse (vorübergehend) ab dem Stammverzeichnis zu kopieren. Stellen Sie einfach sicher, dass keine losen Symlink-Einstellungen schweben. Entfernen Sie so viele Symlinks wie möglich und setzen Sie sie 1 zu 1 zurück.


-1

Die Rückreferenzen sind "up" (rewriteCond) bis "down" (RewriteRule). In dem Beispiel, das Sie veröffentlichen, ist "down" bis "up". Und die Rückreferenzen sind mit% nicht mit $.

RewriteCond-Rückreferenzen: Dies sind Rückreferenzen der Form% N (0 <= N <= 9). % 1 bis% 9 bieten Zugriff auf die gruppierten Teile (ebenfalls in Klammern) des Musters ab der letzten übereinstimmenden RewriteCond in den aktuellen Bedingungen. % 0 bietet Zugriff auf die gesamte Zeichenfolge, die mit diesem Muster übereinstimmt.

Sie könnten dies versuchen:

RewriteBase /
RewriteCond %{REQUEST_URI} /img/([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{28}\.\w+)$
RewriteCond %{DOCUMENT_ROOT}/test/%1/%2/%3/%4 -f
RewriteRule .* img/%1/%2/%3/%4 [L]

Zuerst den regulären Ausdruck, um die Variablen zu finden. Der Pfad zu der Datei mit den Variablen wird erstellt und überprüft, wenn die Datei vorhanden ist

Ich verwende % {DOCUMENT_ROOT} zum Testen auf meinem lokalen Server. Wenn Sie diese Bilddateien nicht in demselben DocumentRoot haben, benötigen Sie den vollständigen Pfad wie folgt :

RewriteCond /var/www/cache_images/test/%1/%2/%3/%4 -f

Umschreibungen werden in der Reihenfolge RewriteRule-Übereinstimmung, RewriteCond-Übereinstimmung, RewriteRule-Umschreibung ausgewertet . "Down to up" funktioniert also. Auf RewriteRule-Rückverweise wird von verwiesen, $nund auf RewriteCond-Rückverweise wird von verwiesen %n. Es funktioniert tatsächlich.
Täuschung

Du hast recht. Sie können Ihre Frage bearbeiten, um die endgültige Version Ihrer Einstellungen zu platzieren, sodass die Lösung klar ist. Ich werde meine Antwort bearbeiten, um den Fehler zu beheben (auf und ab), und auf jeden Fall funktioniert mein Beispiel auch :)
Gabriel Pérez S.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.