Apache (httpd) VirtualHost RewriteCond Variáveis não funcionam

1

Estou tentando criar uma entrada de host virtual dinâmica com a intenção de redirecionar todo o tráfego para .mydomain.com para / var / www / html / essa parte funciona, mas também o que é uma condição de Rewrite que verifica se o diretório existe se não, então eu quero redirecionar todo o tráfego para a raiz /var/www/html/index.php.

Esta parte não está funcionando porque durante meus testes eu notei que nenhuma das variáveis Rewrite estão funcionando, elas estão em branco e não consigo entender por que aqui está minha configuração de host virtual

# get the server name from the Host: header
UseCanonicalName Off

# this log format can be split per-virtual-host based on the first field
# LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon

<VirtualHost *:80>
    ServerName mydomain.com
    ServerAlias www.mydomain.com
    VirtualDocumentRoot /var/www/html
</VirtualHost>

<VirtualHost *:80>
    ServerName vhosts.mydomain.com
    ServerAlias *
    VirtualDocumentRoot /var/www/html/%1

    RewriteEngine on
    LogLevel warn rewrite:trace4

    # If the request is not for a valid directory
    RewriteCond /var/www/html/%1 !-d
    RewriteCond %{REQUEST_FILENAME} !-d
    # If the request is not for a valid file
    RewriteCond %{REQUEST_FILENAME} !-f
    # If the request is not for a valid link
    RewriteCond %{REQUEST_FILENAME} !-l

    RewriteRule .* /var/www/html/index.php

</VirtualHost>

Você notará que eu tenho vários usos da variável que eu posso usar quando testar e olhar para o meu arquivo de log

[Wed Jul 29 16:56:56.015818 2015] [rewrite:trace2] [pid 23898] mod_rewrite.c(475): [client xx.xx.xx.xx:4863] xx.xx.xx.xx - - [fake.mydomain.com/sid#7f5c89bcf570][rid#7f5c89ed5000/initial] init rewrite engine with requested uri /
[Wed Jul 29 16:56:56.016050 2015] [rewrite:trace3] [pid 23898] mod_rewrite.c(475): [client xx.xx.xx.xx:4863] xx.xx.xx.xx - - [fake.mydomain.com/sid#7f5c89bcf570][rid#7f5c89ed5000/initial] applying pattern '.*' to uri '/'
[Wed Jul 29 16:56:56.018361 2015] [rewrite:trace4] [pid 23898] mod_rewrite.c(475): [client xx.xx.xx.xx:4863] xx.xx.xx.xx - - [fake.mydomain.com/sid#7f5c89bcf570][rid#7f5c89ed5000/initial] RewriteCond: input='/var/www/html/' pattern='!-d' => not-matched
[Wed Jul 29 16:56:56.018411 2015] [rewrite:trace1] [pid 23898] mod_rewrite.c(475): [client xx.xx.xx.xx:4863] xx.xx.xx.xx - - [fake.mydomain.com/sid#7f5c89bcf570][rid#7f5c89ed5000/initial] pass through /

mesmo que% 1 passe pelo diretório virtual muito bem, ele não funciona na regra de reescrita do mod. Todos os outros usos das variáveis produzem os mesmos resultados, qualquer ajuda seria apreciada.

Não tenho certeza se isso faz diferença, mas isso está sendo executado no AWS no Amazon Linux build.

    
por Tom Goetz 30.07.2015 / 01:56

1 resposta

1

% 1 NÃO é um tipo de variável global para toda a configuração do Apache.

Em VirtualDocumentRoot ele corresponde à primeira parte do nome 'Host', e em RewriteCond ou RewriteRule representa referências anteriores aos grupos de captura no anterior RewriteCond . Consulte o documento do Apache para RewriteCond

Jogue fora essa parte:

RewriteCond /var/www/html/%1 !-d

Seu uso de% 1 está errado, você não tem nenhum RewriteCond antes, então% 1 é uma string vazia. Então basicamente você tem uma condição que diz "Se / var / www / html / não é um diretório, faça ..."

Mas obviamente /var/www/html é um diretório, é por isso que sua linha de registro diz

RewriteCond: input='/var/www/html/' pattern='!-d' => not-matched

UPADTE como seguimento do seu comentário:

A coisa a entender é que o Apache é feito de várias partes diferentes que são os módulos. Cada módulo vem com sua própria sintaxe. Isso torna o todo muito poderoso, mas pode ser confuso, como na sua pergunta. Cada módulo poderia definir uma sintaxe com uma variável chamada %1 representando alguma outra coisa em cada módulo.

Pode ser que agora eu tenha entendido melhor o que você quer fazer:

  1. Verifique se uma solicitação tem um diretório correspondente ao seu subdomínio. Caso contrário, envie para /var/www/html/nosubdomain.php
  2. Senão verifique se a solicitação corresponde a um arquivo / diretório / link, se não, envie para /var/www/html/nofile.php

Etapa 1: obtenha o subdomínio

Para obter o subdomínio, você pode usar a habilidade de mod_rewrite para definir e definir variáveis de ambiente (aqui o %1 é o resultado da captura em RewriteCond):

# Setting environment variable SUBDOMAIN = (subdomain).example.com

RewriteCond %{HTTP_HOST} ^([^\.]*)\.example\.com$
RewriteRule . - [E=SUBDOMAIN:%1]
Passo 2: Agora você pode usar a variável SUBDOMAIN em suas regras de reescrita / cond e verificar se o diretório correspondente ao subdomínio existe. Se não você redirecionar para a página definida

# Test if subdomain directory exists, if not, redirect to a 
# standard page (/var/www/html/nosubdomain.php).

RewriteCond /var/www/html/%{ENV:SUBDOMAIN} !-d
RewriteRule .* /var/www/html/nosubdomain.php [L]

Etapa 3: verifique se existe um arquivo solicitado, se não, envie uma página padrão ( /var/www/html/nofile.php ). Para isso, é muito melhor confiar no próprio Apache para verificar e usar um ErrorDocument. Precisamos de um Alias porque você deseja que o arquivo nofile.php esteja fora do VirtualDocumentRoot ( /var/www/html/subdomain/ )

Alias /nofile.php /var/www/html/nofile.php
ErrorDocument 404 /nofile.php

Colocando todas essas etapas juntas logo após a sua diretiva RewriteEngine On lhe trazer uma configuração de trabalho, é claro que você terá que se adaptar ao seu caso de uso exato. Eu testei essa configuração, ela funciona como eu queria, mas em um Apache 2.2.

Você também pode combinar as etapas 1 e 2 juntas se não usar SUBDOMAIN em outro lugar:

RewriteCond %{HTTP_HOST} ^([^\.]*)\.example\.com$
RewriteCond /var/www/html/%1 !-d
RewriteRule .* /var/www/html/nosubdomain.php [L]
    
por 31.07.2015 / 01:03