<-
Apache > HTTP-Server > Dokumentation > Version 2.5 > Rewrite

Verwendung von RewriteMap

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Dieses Dokument ergänzt die mod_rewrite Referenzdokumentation. Es beschreibt die Verwendung der RewriteMap-Direktive und bietet Beispiele für jeden der verschiedenen RewriteMap-Typen.

Beachten Sie, dass viele dieser Beispiele nicht unverändert in Ihrer speziellen Serverkonfiguration funktionieren werden. Es ist daher wichtig, dass Sie sie verstehen, anstatt die Beispiele einfach auszuschneiden und in Ihre Konfiguration einzufügen.

Siehe auch

top

Einführung

Die RewriteMap-Direktive definiert eine externe Funktion, die im Kontext von RewriteRule- oder RewriteCond-Direktiven aufgerufen werden kann, um Umschreibungen durchzuführen, die zu kompliziert oder zu spezialisiert sind, um allein mit regulären Ausdrücken durchgeführt zu werden. Die Quelle für diese Nachschlagung kann einer der in den folgenden Abschnitten aufgeführten Typen sein, die auch in der RewriteMap-Referenzdokumentation aufgezählt sind.

Die Syntax der RewriteMap-Direktive lautet wie folgt:

RewriteMap MapName MapType:MapSource

Der MapName ist ein beliebiger Name, den Sie der Map zuweisen und den Sie später in Direktiven verwenden. Argumente werden der Map über die folgende Syntax übergeben:

${ MapName : LookupKey }
${ MapName : LookupKey | DefaultValue }

Wenn ein solches Konstrukt auftritt, wird die Map MapName konsultiert und der Schlüssel LookupKey nachgeschlagen. Wenn der Schlüssel gefunden wird, wird das Map-Funktions-Konstrukt durch SubstValue ersetzt. Wenn der Schlüssel nicht gefunden wird, wird es durch DefaultValue oder durch den leeren String ersetzt, falls kein DefaultValue angegeben wurde.

Sie können beispielsweise eine RewriteMap wie folgt definieren:

RewriteMap examplemap "txt:/path/to/file/map.txt"

Sie können diese Map dann in einer RewriteRule wie folgt verwenden:

RewriteRule "^/ex/(.*)" "${examplemap:$1}"

Ein Standardwert kann für den Fall angegeben werden, dass nichts in der Map gefunden wird:

RewriteRule "^/ex/(.*)" "${examplemap:$1|/not_found.html}"

Verzeichniskontext und .htaccess-Kontext

Die RewriteMap-Direktive darf nicht in <Directory>-Abschnitten oder .htaccess-Dateien verwendet werden. Sie müssen die Map im Server- oder VirtualHost-Kontext deklarieren. Sie können die Map, einmal erstellt, in Ihren RewriteRule- und RewriteCond-Direktiven in diesen Geltungsbereichen verwenden. Sie können sie nur nicht in diesen Geltungsbereichen deklarieren.

Die folgenden Abschnitte beschreiben die verschiedenen MapTypes, die verwendet werden können, und geben Beispiele für jeden.

top

int: Interne Funktion

Wenn ein MapType von int verwendet wird, ist die MapSource eine der verfügbaren internen RewriteMap-Funktionen. Modulautoren können zusätzliche interne Funktionen bereitstellen, indem sie diese mit der ap_register_rewrite_mapfunc-API registrieren. Die standardmäßig bereitgestellten Funktionen sind:

Um eine dieser Funktionen zu verwenden, erstellen Sie eine RewriteMap, die auf die int-Funktion verweist, und verwenden Sie diese dann in Ihrer RewriteRule:

Eine URI auf eine komplett kleingeschriebene Version umleiten

RewriteMap lc int:tolower
RewriteRule "(.*)" "${lc:$1}" [R]

Bitte beachten Sie, dass das hier angebotene Beispiel nur zur Veranschaulichung dient und keine Empfehlung ist. Wenn Sie URLs unabhängig von der Groß-/Kleinschreibung machen möchten, ziehen Sie stattdessen die Verwendung von mod_speling in Betracht.

top

txt: Klartext-Maps

Wenn ein MapType von txt verwendet wird, ist die MapSource ein Dateisystempfad zu einer Klartext-Zuordnungsdatei, die ein durch Leerzeichen getrenntes Schlüssel/Wert-Paar pro Zeile enthält. Optional kann eine Zeile einen Kommentar enthalten, der mit einem '#'-Zeichen beginnt.

Eine gültige Text-Rewrite-Map-Datei hat die folgende Syntax:

# Kommentarzeile
MatchingKey SubstValue
MatchingKey SubstValue # Kommentar

Wenn die RewriteMap aufgerufen wird, wird das Argument im ersten Argument einer Zeile gesucht und, falls gefunden, der Ersetzungswert zurückgegeben.

Beispielsweise können wir eine Map-Datei verwenden, um Produktnamen in Produkt-IDs für leichter zu merkende URLs zu übersetzen, mit dem folgenden Rezept:

Produkt-zu-ID-Konfiguration

RewriteMap product2id "txt:/etc/apache2/productmap.txt"
RewriteRule "^/product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]

Wir nehmen hier an, dass das prods.php-Skript weiß, was zu tun ist, wenn es ein Argument von id=NOTFOUND erhält, wenn ein Produkt nicht in der Nachschlagetabelle gefunden wird.

Die Datei /etc/apache2/productmap.txt enthält dann Folgendes:

Produkt-zu-ID-Map

##
## productmap.txt - Produkt-zu-ID-Map-Datei
##

television 993
stereo 198
fishingrod 043
basketball 418
telephone 328

Wenn also http://example.com/product/television angefordert wird, wird die RewriteRule angewendet und die Anfrage intern auf /prods.php?id=993 abgebildet.

Hinweis: .htaccess-Dateien

Das gegebene Beispiel ist für die Verwendung im Server- oder VirtualHost-Kontext konzipiert. Wenn Sie dies in einer .htaccess-Datei verwenden möchten, müssen Sie den führenden Schrägstrich aus dem Umschreibungsmuster entfernen, damit es übereinstimmt:
RewriteRule "^product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]

Zwischengespeicherte Nachschlagungen

Die nachgeschlagenen Schlüssel werden von httpd zwischengespeichert, bis sich die mtime (Änderungszeit) der Map-Datei ändert oder der httpd-Server neu gestartet wird. Dies gewährleistet eine bessere Leistung bei Maps, die von vielen Anfragen aufgerufen werden.

top

rnd: Zufälliger Klartext

Wenn ein MapType von rnd verwendet wird, ist die MapSource ein Dateisystempfad zu einer Klartext-Zuordnungsdatei, wobei jede Zeile einen Schlüssel und einen oder mehrere durch | getrennte Werte enthält. Einer dieser Werte wird zufällig ausgewählt, wenn der Schlüssel übereinstimmt.

Sie können beispielsweise die folgende Map-Datei und Direktiven verwenden, um eine zufällige Lastverteilung zwischen mehreren Backend-Servern über einen Reverse-Proxy bereitzustellen. Bilder werden an einen der Server im 'static'-Pool gesendet, während alles andere an einen der Server im 'dynamic'-Pool gesendet wird.

Rewrite-Map-Datei

##
## map.txt -- Umschreibungs-Map
##

static www1|www2|www3|www4
dynamic www5|www6

Konfigurationsdirektiven

RewriteMap servers "rnd:/path/to/file/map.txt"

RewriteRule "^/(.*\.(png|gif|jpg))" "http://${servers:static}/$1"  [NC,P,L]
RewriteRule "^/(.*)"                "http://${servers:dynamic}/$1" [P,L]

Wenn also ein Bild angefordert wird und die erste dieser Regeln übereinstimmt, schlägt RewriteMap den String static in der Map-Datei nach, die einen der angegebenen Hostnamen zufällig zurückgibt, der dann im RewriteRule-Ziel verwendet wird.

Wenn Sie möchten, dass einer der Server häufiger ausgewählt wird (zum Beispiel, wenn einer der Server mehr Speicher hat und daher mehr Anfragen verarbeiten kann), listen Sie ihn einfach häufiger in der Map-Datei auf.

static www1|www1|www2|www3|www4

top

dbm: DBM-Hash-Datei

Wenn ein MapType von dbm verwendet wird, ist die MapSource ein Dateisystempfad zu einer DBM-Datenbankdatei, die Schlüssel/Wert-Paare für die Zuordnung enthält. Dies funktioniert genau wie die txt-Map, ist aber viel schneller, da eine DBM indiziert ist, während eine Textdatei dies nicht ist. Dies ermöglicht einen schnelleren Zugriff auf den gewünschten Schlüssel.

Sie können optional einen bestimmten DBM-Typ angeben:

RewriteMap examplemap "dbm=sdbm:/etc/apache/mapfile.dbm"

Der Typ kann sdbm, gdbm, ndbm oder db sein. Es wird jedoch empfohlen, einfach das mit dem Apache HTTP Server mitgelieferte Dienstprogramm httxt2dbm zu verwenden, da es die korrekte DBM-Bibliothek verwendet, die mit der beim Bau von httpd selbst verwendeten übereinstimmt.

Um eine DBM-Datei zu erstellen, erstellen Sie zunächst eine Text-Map-Datei wie im Abschnitt txt beschrieben. Führen Sie dann httxt2dbm aus:

$ httxt2dbm -i mapfile.txt -o mapfile.map

Sie können dann die resultierende Datei in Ihrer RewriteMap-Direktive referenzieren:

RewriteMap mapname "dbm:/etc/apache/mapfile.map"

Beachten Sie, dass bei einigen DBM-Typen mehr als eine Datei mit einem gemeinsamen Basisnamen erzeugt wird. Beispielsweise können zwei Dateien namens mapfile.map.dir und mapfile.map.pag vorhanden sein. Dies ist normal, und Sie müssen nur den Basisnamen mapfile.map in Ihrer RewriteMap-Direktive verwenden.

Zwischengespeicherte Nachschlagungen

Die nachgeschlagenen Schlüssel werden von httpd zwischengespeichert, bis sich die mtime (Änderungszeit) der Map-Datei ändert oder der httpd-Server neu gestartet wird. Dies gewährleistet eine bessere Leistung bei Maps, die von vielen Anfragen aufgerufen werden.

top

prg: Externes Umschreibungsprogramm

Wenn ein MapType von prg verwendet wird, ist die MapSource ein Dateisystempfad zu einem ausführbaren Programm, das das Zuordnungsverhalten bereitstellt. Dies kann eine kompilierte Binärdatei oder ein Programm in einer interpretierten Sprache wie Python oder Perl sein.

Dieses Programm wird einmal beim Start des Apache HTTP Servers gestartet und kommuniziert dann mit der Umschreibungs-Engine über STDIN und STDOUT. Für jede Map-Funktions-Nachschlagung wird der Schlüssel auf das STDIN des Programms geschrieben, gefolgt von einem Zeilenumbruch. Das Programm sollte eine Zeile von STDIN lesen (bis einschließlich des Zeilenumbruchs) und seine Antwort als einzelne durch einen Zeilenumbruch abgeschlossene Zeile auf STDOUT schreiben. Schlüssel enthalten niemals Zeilenumbrüche; wenn ein Schlüssel mit einem Zeilenumbruch angetroffen wird, schlägt die Nachschlagung fehl.

Wenn es keinen entsprechenden Nachschlagewert gibt, sollte das Map-Programm den vierstelligen String "NULL" zurückgeben, um dies anzuzeigen. Beachten Sie, dass dieser Vergleich Groß-/Kleinschreibung ignoriert, sodass "null", "Null" usw. ebenfalls als fehlgeschlagene Nachschlagung behandelt werden. Folglich ist es nicht möglich, dass ein Zuordnungsprogramm den literalen String "NULL" als zugeordneten Wert zurückgibt.

Das STDERR des Programms wird vom httpd-Elternprozess geerbt, sodass alles, was das Programm auf STDERR schreibt, an derselben Stelle wie die eigene Fehlerausgabe von httpd erscheint (typischerweise das ErrorLog).

Externe Umschreibungsprogramme werden nicht gestartet, wenn sie in einem Kontext definiert sind, der RewriteEngine nicht auf on gesetzt hat.

Standardmäßig werden externe Umschreibungsprogramme als der Benutzer:Gruppe ausgeführt, der httpd gestartet hat. Auf UNIX-Systemen kann dies geändert werden, indem Benutzername und Gruppenname als drittes Argument an RewriteMap im Format username:groupname übergeben werden.

Diese Funktion nutzt den rewrite-map-Mutex, der für eine zuverlässige Kommunikation mit dem Programm erforderlich ist. Der Mutex-Mechanismus und die Sperrdatei können mit der Mutex-Direktive konfiguriert werden.

Hier wird ein einfaches Beispiel gezeigt, das alle Bindestriche in einem Anfrage-URI durch Unterstriche ersetzt.

Umschreibungskonfiguration

RewriteMap d2u "prg:/www/bin/dash2under.py" apache:apache
RewriteRule "-" "${d2u:%{REQUEST_URI}}"

dash2under.py

#!/usr/bin/env python3
import sys

for line in sys.stdin:
    print(line.strip().replace('-', '_'), flush=True)

Vorsicht!

  • Halten Sie Ihr Rewrite-Map-Programm so einfach wie möglich. Wenn das Programm hängt, wartet httpd unbegrenzt auf eine Antwort von der Map, was wiederum dazu führt, dass httpd nicht mehr auf Anfragen reagiert.
  • Stellen Sie sicher, dass Sie die Pufferung in Ihrem Programm deaktivieren. Im obigen Python-Beispiel geschieht dies durch Übergabe von flush=True an print(). Gepufferte I/O bewirkt, dass httpd auf die Ausgabe wartet und daher hängen bleibt.
  • Denken Sie daran, dass nur eine Kopie des Programms existiert, die beim Serverstart gestartet wird. Alle Anfragen müssen durch diesen einen Engpass gehen. Dies kann bei vielen Anfragen oder bei einem sehr langsamen Skript zu erheblichen Verlangsamungen führen.
  • Wenn das Zuordnungsprogramm beendet wird, wird es nicht automatisch neu gestartet. Nachfolgende Nachschlagungen werden fehlschlagen, bis der Server neu gestartet wird.
  • Das Zuordnungsprogramm wird bei jedem Server-Neustart (ob graceful oder nicht) beendet und neu gestartet, unabhängig davon, ob sich die zugehörigen Konfigurationsdirektiven geändert haben. Beim Herunterfahren wird dem Programm SIGTERM gesendet; wenn es nicht innerhalb von 3 Sekunden beendet wird, wird SIGKILL gesendet.
top

dbd oder fastdbd: SQL-Abfrage

Wenn ein MapType von dbd oder fastdbd verwendet wird, ist die MapSource eine SQL-SELECT-Anweisung, die ein einzelnes Argument entgegennimmt und einen einzelnen Wert zurückgibt.

mod_dbd muss so konfiguriert werden, dass es auf die richtige Datenbank zeigt, damit diese Anweisung ausgeführt werden kann.

Es gibt zwei Formen dieses MapType. Bei Verwendung eines MapType von dbd wird die Abfrage bei jeder Map-Anfrage ausgeführt, während bei fastdbd die Datenbank-Nachschlagungen intern zwischengespeichert werden. Obwohl fastdbd effizienter und daher schneller ist, werden Änderungen an der Datenbank erst nach einem Neustart des Servers übernommen.

Wenn eine Abfrage mehr als eine Zeile zurückgibt, wird eine zufällige Zeile aus der Ergebnismenge verwendet.

Beispiel

RewriteMap myquery "fastdbd:SELECT destination FROM rewrite WHERE source = %s"

Hinweis

Der Abfragename wird als Label für eine vorbereitete SQL-Anweisung an den Datenbanktreiber übergeben und muss daher alle Regeln (wie Groß-/Kleinschreibung) einhalten, die Ihre Datenbank erfordert.

top

Zusammenfassung

Die RewriteMap-Direktive kann mehrfach vorkommen. Verwenden Sie für jede Zuordnungsfunktion eine RewriteMap-Direktive, um ihre Umschreibungs-Map-Datei zu deklarieren.

Obwohl Sie eine Map nicht im Verzeichniskontext (.htaccess-Dateien oder <Directory>-Blöcke) deklarieren können, ist es möglich, diese Map im Verzeichniskontext zu verwenden.

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn