2012-03-06 11 views
12

La documentazione di nginx indica che lo server_name directive supporta le espressioni regolari. Ho sbattuto la testa contro il muro cercando di far funzionare anche una regex banale.Reindirizzamento di un sottodominio con un'espressione regolare in nginx

voglio http://subdomain.mydomain.com per reindirizzare http://mydomain.com/subdomain

Ecco il mio codice.

server { 
    server_name "~^subdomain\.mydomain\.com$"; 
    rewrite^http://mydomain.com/subdomain; 
} 

Inoltre, potenzialmente degno di nota. Più avanti nel file di configurazione di nginx c'è una regola:

server { 
    server_name *.mydomain.com 
    ... 
} 

Cosa sto facendo male?

UPDATE:

E 'stato suggerito che io non uso regex per questo ... per offrire un po' più di chiarezza: l'espressione regolare banale era semplicemente a scopo di risoluzione dei problemi. La vera espressione regolare sarà più simile a ...

server { 
    server_name "~^.*(cvg|cincinnati)\.fakeairport(app)?\.(org|com)$"; 
    rewrite^http://fakeairport.com/cincinnati; 
} 

server { 
    server_name "~^.*(lex|lexington)\.fakeairport(app)?\.(org|com)$"; 
    rewrite^http://fakeairport.com/lexington; 
} 

quindi sarebbe preferibile usare espressioni regolari.

+0

clueless su nginx, ma perché c'è una tilde all'inizio della regex? – sweaver2112

+0

La tilde iniziale indica a nginx che questa è un'espressione regolare. – danott

risposta

26

per rispondere a una vecchia questione di aiutare gli altri

usando nginx 1.1.19 è possibile effettuare le seguenti operazioni:

server { 
    server_name  ~^(?<subdomain>\w+)\.domainA\.com$; 

    location/{ 
      rewrite^https://$subdomain.domainB.com$request_uri permanent; 
    } 
} 

Il sottodominio prima domainA.com è abbinato e memorizzato nella variabile $ sottodominio che poi può essere usato nella riscrittura. Questo riscrive l'url come xxx.domainA.com a xxx.domainB.com con una sola direttiva server.

+0

Grazie amico, mi ha aiutato. –

0

So che tutti dicono se è malvagio nei file di configurazione di nginx, ma a volte non si può andare in giro in nessun altro modo.

server { 
     server_name .mydomain.com; 

     if ($host ~ subdomain.mydomain.com) { 
       rewrite ^(.*) http://mydomain.com/subdomain$1; 
     } 
} 
+2

Non dovresti MAI usare un se quando non è necessario. Questo è solo chiedere dei problemi. – MTeck

+1

Corretto ma, come si intuisce, ci sono situazioni in cui è necessario e se configurato correttamente (solo con i comandi del modulo di riscrittura) è perfettamente sicuro da usare. Il problema con "se" non è che NON dovrebbe essere usato, ma che sia usato con comprensione. – Dayo

+5

Mi sto davvero stancando di molte persone che dicono "MAI UTILIZZO SE". Perché nel mondo è persino implementato, se è proibito utilizzarlo ?! – petermolnar

3

Se leggete il server_name matching rules, vedrai che prefisso e suffisso server_names vengono controllati prima nomi regex, ma dopo i nomi degli host esatte. Poiché * .mydomain.com corrisponde, la regex non è testata. Il fatto che sia elencato in precedenza nella configurazione non fa alcuna differenza. Dal momento che stai solo cercando di abbinare un singolo hostname con la tua espressione regolare, un semplice:

server { 
    server_name subdomain.mydomain.com; 
    rewrite^http://mydomain.com/subdomain$request_uri?; 
} 

server { 
    server_name *.mydomain.com; 

    # stuff 
} 

funzionerà per voi.

+0

L'espressione regolare triviale era semplicemente a scopo di risoluzione dei problemi. Alcuni ulteriori dettagli sul perché ho bisogno di usare un'espressione regolare sono stati aggiunti alla domanda originale. – danott

+0

Ah, avrei dovuto rendermene conto. Per cosa stai usando il dominio suffisso? Finché ce l'hai, nessun server regex corrisponderà a quel suffisso. – kolbyjack

+0

L'architettura della nostra applicazione utilizzata per utilizzare una tonnellata di sottodomini, quindi è usata come un catch-all per reindirizzare qualsiasi sottodominio aggiuntivo che non ha un reindirizzamento specifico. – danott

9

Devo fare l'enigma con NGINX!

Dato che lavoro spesso con più nomi di domini e mi piace mantenere le mie configurazioni il più pulite e solide possibile, quasi sempre uso regex con nginx.

In questo caso ho risolto con la seguente espressione regolare:

server { 
    listen 80; 
    server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$; 
    return 301 $scheme://${domain}.${tld}; 
} 

Quello che fa è il seguente: ogni subdomain.domain-name.tld che punta a questo server (indirizzo IP) viene automaticamente reindirizzato domain-name.tld.

Quindi, ad esempio, www.myexampledomain.com viene reindirizzato a myexampledomain.com.

Per rispondere alla domanda, che cosa si potrebbe anche fare è la seguente:

server { 
    listen 80; 
    server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$; 
    return 301 $scheme://${domain}.${tld}/${subdomain}; 
} 

Ora mysubdomain.myexampledomain.com viene convertito in myexampledomain.com/mysubdomain.

La regex è eccezionale in quanto è possibile lanciare qualsiasi cosa che ti piace e la convertirà per te.

+1

Gli esempi di RegEx in "nome_server" nei tuoi esempi sono incredibilmente utili! Un fantastico vantaggio era che ero in grado di definire dinamicamente un percorso 'root' condiviso tagliando il sottodominio in questo modo:' root \t /home/www-data/$domain.$tld/; 'La tua risposta utilizza tecniche molto più moderne e dovrebbe essere aggiornato alla risposta accettata. – FactoryAidan

0

Proprio come un commento. Se si desidera reindirizzare tutti i livelli sottodominio primo livello di sottodominio, util quando si utilizza un certificato SSL jolly, ad esempio, è possibile utilizzare:

server { 
    listen 80; 
    server_name ~^(.*)\.(?<subdomain>\w+).mydomain\.com$; 
    return   301 https://$subdomain.mydomain.com$request_uri; 
} 

server { 
    listen 80; 
    server_name ~^(?<subdomain>\w+).mydomain\.com$; 
    return   301 https://$subdomain.mydomain.com$request_uri; 
} 

Il primo è per il rinvio di un http multipla livello di sottodominio al primo livello sottodominio in https. E il prossimo è per reindirizzare il sottodominio di primo livello in http allo stesso sottodominio in https.

Problemi correlati