Apache htaccess várias condições de reescrita para várias regras

Nov 23 2017

Eu assumi o controle de um site e notei que o desenvolvedor anterior tinha várias .htaccessregras de reescrita, este é um pequeno exemplo:

RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing$ landing.php?page=$1

A condição de reescrita é sempre a mesma para todas as regras. Existe uma maneira de combinar as regras de reescrita para que as condições tenham que ser escritas apenas uma vez?

Eu olhei para a bandeira de pular, mas ela não tem referência anterior possível. Pelo que vejo, não preciso de referências anteriores com essas condições, no entanto, ignorar é a melhor abordagem? Ou existe uma prática recomendada sobre como conseguir isso? (Alguém me sugeriu usar o sinalizador QSA, no entanto, durante a pesquisa, não acho que isso tenha algo a ver com o que desejo realizar.)

Respostas

3 MrWhite Nov 23 2017 at 23:23
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$

Este bloco confuso de condições é injetado automaticamente pelo cPanel antes de cada RewriteRulediretiva quando ele renova automaticamente um certificado de segurança SSL (Let's Encrypt?). Essas condições garantem que o arquivo de validação (necessário para renovar o certificado SSL) esteja acessível.

Infelizmente, não consegui descobrir por que o cPanel faz isso dessa maneira - pode ser um pesadelo de manutenção e eu encontrei diretivas que foram quebradas por essas condições (reconhecidamente as diretivas eram menos do que perfeitas para começar ) (Eu tentei perguntar nos fóruns cPanel, mas nunca tive uma boa resposta.)

... existe uma maneira de combinar as regras de reescrita para que as condições tenham que ser escritas apenas uma vez?

Sim. Você pode mover essas condições para seu próprio bloco no início do .htaccessarquivo e reverter seu significado, então, em vez de apenas disparar o RewriteRulequando uma solicitação não corresponder ao padrão (usando uma regex negada ). Você pode evitar novas regravações quando uma solicitação corresponder ao padrão. Por exemplo:

# BEGIN cPanel SSL CERT RENEWAL
RewriteCond %{REQUEST_URI} ^/[0-9]+\..+\.cpaneldcv$ [OR]
RewriteCond %{REQUEST_URI} ^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$ [OR]
RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$ [OR]
RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^ - [L]
# END cPanel SSL CERT RENEWAL

Observe a remoção do !prefixo (negação) no CondPattern e o ORsinalizador adicional nas três primeiras condições. O RewriteRuleentão impede que outras diretivas mod_rewrite sejam processadas caso a solicitação corresponda.

(No Apache 2.4.8+, essas diretivas podem ser movidas inteiramente para a configuração do servidor. Com a ajuda de RewriteOptions InheritDownBefore.)

Em seguida, seguido por apenas as RewriteRulediretivas que você tinha antes (embora eu tenha adicionado o Lsinalizador):

RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3 [L]
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2 [L]
RewriteRule ^(.*)/landing$ landing.php?page=$1 [L]

Você provavelmente deve incluir Lsinalizadores nas reescritas restantes.

Você também pode combinar essas 3 regravações em uma única diretiva, se quiser, mas isso dependeria se seu aplicativo lida com parâmetros de URL vazios.

(Alguém me sugeriu usar o sinalizador QSA, no entanto, durante a pesquisa, não acho que isso tenha algo a ver com o que desejo realizar.)

Sim, isso realmente não tem nada a ver com esse problema específico. O QSAsinalizador (Query String Append) permitiria a você mesclar qualquer string de consulta presente na solicitação com a string de consulta que você está escrevendo na RewriteRule substituição .