Traduzindo regras de reescrita de htaccess para regras de virtualhost do Apache2

3

Estou tentando definir um subdomínio curinga RewriteRule combinando algumas regras .htaccess que eu tinha implementado com sucesso antes, sob a crença de que posso usar as mesmas regras para o meu arquivo vhosts do Apache.

Em essência, example.com e www.example.com vão para o caminho da raiz e procuram index.php . Todas as outras solicitações de subdomínio (dinâmico) no nível raiz, como abc.example.com , são reescritas (invisíveis para o navegador) para example.com/process.php?p=abc .

Em segundo lugar, todas as solicitações de arquivos do subdomínio fora de um nível base / raiz precisam ser reescritas para serem obtidas do caminho raiz do domínio padrão sem o subdomínio. Então abc.example.com/css/style.css precisa vir de example.com/css/style.css

Esta é a minha tentativa de fazer isso. Eu recebo um erro do Apache:

You don't have permission to access /index.php on this server.

para qualquer tentativa de subdomínio, diferente de www, que funciona como esperado, bem como o padrão example.com , que ainda funciona bem.

<VirtualHost *:80>

        ServerAdmin [email protected]
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/example.com/public_html

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

<VirtualHost *:80>
        ServerAdmin [email protected]
        ServerName other.example.com
        ServerAlias *.example.com
        DocumentRoot /var/www/example.com/public_html/

        <Directory /var/www/example.com/public_html/>
        Options FollowSymLinks
        AllowOverride all
        Require all granted

        RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
                RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
                RewriteRule ^$ /process.php?p=%2 [QSA,NC]
                RewriteCond %{REQUEST_FILENAME} !^$ [NC]
                RewriteRule ^(.*) http://www.example.com/$1 [P]
        </Directory>
</VirtualHost>

Eu baseei isso com sucesso redirecionando o diretório raiz de um domínio diferente para example.com usando esse arquivo .htaccess , que incorpora process.php e envia todas as outras solicitações para a raiz de example.com .

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

# Check the request isn't an existing file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^$ http://www.example.com/process.php [P]
RewriteCond %{REQUEST_FILENAME} !^$ [NC]
RewriteRule ^(.*) http://www.example.com/$1 [P]

E também deste teste .htaccess que executei para redirecionar um subdomínio como uma variável para process.php com sucesso, embora ele não tenha recebido outras solicitações de arquivo, como o exemplo css acima:

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteRule ^$ /process.php?p=%2 [QSA,NC]

Atualização 1

Eu tive (aparentemente) algum sucesso com o uso do seguinte no lugar da minha segunda entrada virtualhost. A página process.php está sendo produzida se eu usar um subdomínio. Embora a correspondência de padrões pareça funcionar nesse sentido, meu% realprocess.php recebe uma variável vazia, em vez do subdomínio esperado como uma sequência (para: process.php?p=%2 ):

<VirtualHost *:80>
        ServerAdmin [email protected]
        ServerName other.example.com
        ServerAlias *.example.com
        DocumentRoot /var/www/example.com/public_html

        <Directory /var/www/example.com/public_html>
        Options FollowSymLinks
        AllowOverride all
        Require all granted
        RewriteEngine on
        RewriteBase /

        RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
        RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
        RewriteCond %{REQUEST_URI} ^/$
        RewriteRule ^$ /process.php?p=%2 [NC,QSA]
        </Directory>
</VirtualHost>

Atualização 2

Eu resolvi isso de uma forma indireta, mas não tenho certeza se é a maneira mais elegante de fazê-lo.

Usando o código atualização 1 acima, vi que qualquer sequência de consulta ainda estava sendo anexada, mas %2 não estava sendo recebido por GET na minha página process.php . Eu posso ter assumido erroneamente que, embora o URL não exiba a variável p=abc na URL para o navegador, de acordo com as instruções do meu código, a URL interna ainda as transmitiu. No entanto, percebi que process.php ainda poderia determinar o subdomínio como uma string usando $_SERVER['HTTP_X_FORWARDED_HOST'] em PHP e usá-lo como uma variável na página de maneira semelhante à minha ideia inicial.

    
por biscuitstack 23.03.2017 / 12:09

1 resposta

1
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^$ /process.php?p=%2 [NC,QSA]

O %2 backreference não estava sendo definido porque essa é uma referência anterior ao segundo grupo capturado do último correspondido CondPattern ( RewriteCond pattern). A última CondPattern correspondente é ^/$ , que não possui nenhum grupo capturado, por isso %2 está sempre vazio.

Essa terceira diretiva RewriteCond parece supérflua mesmo assim. Isso já está sendo verificado pelo RewriteRule padrão ^$ (em um contexto por diretório, o prefixo de diretório é removido - portanto, isso está correto).

A primeira diretiva RewriteCond também parece supérflua. Qualquer pedido para www.example.com seria capturado pelo primeiro VirtualHost, então o hostname dentro deste VirtualHost nunca é www.example.com , então esta diretiva sempre é avaliada como verdadeira.

Eu reescreveria isso como:

RewriteCond %{HTTP_HOST} ^(?:www\.)?([^.]+)\.example\.com$ [NC]
RewriteRule ^$ process.php?p=%1 [QSA]

Eu fiz o primeiro grupo sem captura, isto é. (?:www\.) - o ?: faz com que não seja capturado. Então, nós só recebemos %1 para o subdomínio real. Além disso, não há necessidade de escapar do ponto (para corresponder a um ponto literal) em uma classe de caractere. O sinal NC no RewriteRule é supérfluo aqui.

Eu também removi o prefixo barra na RewriteRule substituição desde que você especificou o caminho da URL na diretiva RewriteBase .

Isso só reescreve abc.example.com/ , isto é. uma solicitação para a raiz do documento.

Secondly, any requests for files from the subdomain outside of a base/root level need to be rewritten to be obtained from the root path of the standard domain without the subdomain. So abc.example.com/css/style.css needs to come from example.com/css/style.css.

Como abc.example.com/ e example.com/ apontam para o mesmo local no sistema de arquivos, não vejo como você precisa fazer alguma coisa aqui? example.com/css/style.css deve apontar para o mesmo arquivo que abc.example.com/css/style.css .

E os outros arquivos na raiz do documento? por exemplo. %código%. No momento, isso simplesmente passa inalterado como nos arquivos CSS.

    
por 24.03.2017 / 01:06