2009-07-22 13 views
6

Sto provando a scrivere un set di regole mod_rewrite che consentono ai miei utenti di utilizzare una singola cartella per eseguire lo sviluppo su progetti diversi, e non si deve confondere con l'aggiunta di vhosts per ogni singolo progetto.Apache mod_rewrite un sottodominio in una sottocartella (tramite reindirizzamento interno)

La mia idea di realizzare questo, è di impostare un "Global VHost" per ogni singolo utente che ha bisogno di questa capacità (solo 3-4), il vhost sarebbe qualcosa del tipo: .my-domain.com. Da lì, voglio promuovere i miei utenti a scrivere codice come se si trovasse su un dominio e non in una sottocartella. Ad esempio, se bob stava lavorando su un progetto chiamato 'gnome', mi piacerebbe che l'URL bob (e chiunque altro sulla nostra rete interna) carichi per arrivare a questo progetto fosse: http://gnome.bob.my-domain.com. Ma, quello che vorrei fare Apache, è riconoscere che "gnome" è un "progetto" e quindi mappare la richiesta, internamente, a bob.my-domain.com/gnome/.

Ho quello che pensavo avrebbe funzionato, ed è abbastanza semplice, ma..it non funziona! La richiesta entra in un ciclo infinito e mantiene il prefisso del dominio secondario sull'URI della richiesta riscritta.

Il codice mod rewrite che ho è:

RewriteEngine On 

RewriteCond %{HTTP_HOST} ^([^.]+)\.bob\.my-domain\.com 
RewriteCond %{REQUEST_URI} !^/%1.* 
RewriteRule ^(.*)$  /%1/$1 [L] 

Googled intorno a un po 'di questo, ma ho ancora trovare eventuali soluzioni reali che funzionano. Qualcuno ha provato questo - o forse, qualcuno ha un'idea migliore? Uno che non implica la creazione di un host virtuale per ogni progetto (ho designer ... Credo che tutti sarebbero d'accordo sul fatto che un designer non dovrebbe creare host virtuali ..)

Grazie!

Ecco un frammento della rewrite_log:

[rid#838dc88/initial] (3) [perdir /home/bob/http/] strip per-dir prefix: /home/bob/http/index.html -> index.html 
[rid#838dc88/initial] (3) [perdir /home/bob/http/] applying pattern '^(.*)$' to uri 'index.html' 
[rid#838dc88/initial] (4) [perdir /home/bob/http/] RewriteCond: input='gnome.bob.my-domain.com' pattern='^([^.]+)\.bob\.my-domain\.com' => matched 
[rid#838dc88/initial] (4) [perdir /home/bob/http/] RewriteCond: input='/index.html' pattern='!^/%1.*' => matched 
[rid#838dc88/initial] (2) [perdir /home/bob/http/] rewrite 'index.html' -> '/gnome/index.html' 
[rid#838dc88/initial] (1) [perdir /home/bob/http/] internal redirect with /gnome/index.html [INTERNAL REDIRECT] 
[rid#8392f30/initial/redir#1] (3) [perdir /home/bob/http/] strip per-dir prefix: /home/bob/http/gnome/index.html -> gnome/index.html 
[rid#8392f30/initial/redir#1] (3) [perdir /home/bob/http/] applying pattern '^(.*)$' to uri 'gnome/index.html' 
[rid#8392f30/initial/redir#1] (4) [perdir /home/bob/http/] RewriteCond: input='gnome.bob.my-domain.com' pattern='^([^\.]+)\.bob\.my-domain\.com' => matched 
[rid#8392f30/initial/redir#1] (4) [perdir /home/bob/http/] RewriteCond: input='/gnome/index.html' pattern='!^/%1.*' => matched 
[rid#8392f30/initial/redir#1] (2) [perdir /home/bob/http/] rewrite 'gnome/index.html' -> '/gnome/gnome/index.html' 
[rid#8392f30/initial/redir#1] (1) [perdir /home/bob/http/] internal redirect with /gnome/gnome/index.html [INTERNAL REDIRECT] 
[rid#8397970/initial/redir#2] (3) [perdir /home/bob/http/] add path info postfix: /home/bob/http/gnome/gnome -> /home/bob/http/gnome/gnome/index.html 

Questo è solo un frammento, ci sono un paio di 10s o 100 o giù di lì le linee di apache fondamentalmente riscrittura /gnome/index.html a/gnome/gnome /gnome/gnome/gnome/index.html, ecc prima di apache raggiunge il limite di riscrittura, si arrende, e getta errore 500

+0

Aggiunte ulteriori informazioni dai registri di riscrittura, si spera che qualcuno abbia già provato questo o abbia qualche input su come posso ottenere questo risultato! Grazie ragazzi (e ragazze) –

risposta

5

Dopo alcuni anni di ignorare questo problema e tornare a in vari punti, ho finalmente trovato una soluzione praticabile.

RewriteEngine on 
RewriteCond %{HTTP_HOST} ^([^.]+)\.bob\.my-domain\.com 
RewriteCond %1::%{REQUEST_URI} !^(.*?)::/\1/ 
RewriteRule ^(.*)$ /%1/$1 [L] 

Quello che ho trovato era che back-riferimenti per precedenti RewriteCond direzioni non sono disponibili nel parametro ConditionPattern di RewriteConditions future. Se si desidera utilizzare un riferimento di ritorno da una precedente direttiva RewriteCond, è possibile utilizzarlo solo nel parametro TestString.

Le direttive precedenti precedono il sottodominio corrispondente nella 1a direttiva RewriteCond al RequestURI, delimitata da ::. Quello che poi facciamo nella stringa di prova RewriteCond (regex) è catturare nuovamente il nome del sottodominio, quindi verificare che il nostro RequestURI effettivo non inizi con quel sottodominio come una cartella usando un riferimento posteriore all'interno della stessa espressione regolare .

Questo suona molto più confuso di quanto sia in realtà, e non posso prendermi il merito di aver scoperto la risposta. Ho trovato la risposta come risposta a un'altra domanda qui, %N backreference inside RewriteCond. Grazie a Jon Lin per aver risposto a questa domanda, e a lui sconosciuta, anche la mia domanda!

+0

Solo una nota che ho dovuto rimuovere il trailing/sul secondo RewriteCond per farlo funzionare correttamente per me. Sono stato in grado di caricare il mio URL con esso (un'installazione gallery3), ma le risorse CSS non venivano caricate correttamente. Togliendo la barra finale lo sistemò. Sembrava che finisse con // nell'URL con esso lì dentro. – stuckj

0

alcune domande:

Hai detto "mappa interna" - non è vero vuoi usare un reindirizzamento?

Si sta utilizzando la stessa VirtualHost per gnome.bob.mysite.com e bob.mysite.com

Vi siete ricordati di creare un ServerAlias ​​per *.bob.mysite.com?


Ecco una versione approssimativa che è possibile modificare per funzionare. Catturerà il sottodominio e l'URL richiesto e eseguirà un reindirizzamento al dominio principale con il sottodominio come prima parte del percorso, seguito dal percorso richiesto, seguito dalla stringa di query.

ServerName www.mysite.com 
ServerAlias *.mysite.com 

RewriteCond %{HTTP_HOST} ^([a-zA-Z0-9-]+)\\.mysite.com$ 
RewriteRule ^/(.*)  http://www.mysite.com/%1/$1  [R=301,L]',  
+0

Voglio decisamente un reindirizzamento interno. l'intero scopo di questo è di essere in grado di utilizzare percorsi assoluti su link, css, img srcs, ecc. C'è/ci sarà un host virtuale per .my-site.com con un alias per *. .my-site.com, quindi qualsiasi dominio richiesto di .my-site.com o successivo verrà prelevato da quel vhost –

0

Hai provato a utilizzare un'altra regola di riscrittura per elaborare quella precedente?

RewriteEngine On 

RewriteCond %{HTTP_HOST}      ^([^.]+)\.bob\.my-domain\.com 
RewriteCond %{REQUEST_URI}      !^/%1.* 
RewriteRule ^(.*)$        /%1/$1 [C]  
RewriteRule ^/(.*)\.bob\.my-domain\.com/(.*) /$1/$2 [L] 

Ma penso che il tuo problema più grande è il fatto che il tuo server non capisce che viene servito con un nome diverso.

Pensa che sia in esecuzione nella directory/gnome/mentre il browser sta eseguendo nella directory /. Quindi qualsiasi URL relativo che hai intenzione di causare problemi.

Quello che ti serve è un filtro che eseguirà tutti gli URL nella tua pagina attraverso un processore e li cambierà da/gnome/a /.

+0

l'idea è di scoraggiare gli url relativi, ma in questa struttura, dovrebbero anche funzionare. –

+0

Inoltre, sono abbastanza sicuro che l'host HTTP non viene utilizzato nel RewriteRule, solo l'URI –

Problemi correlati