Então, estou tendo esse problema maluco acontecendo no apache 2.4 / CentOS7 com um aplicativo da web.
Desejo redirecionar todas as URLs não seguras no domínio do aplicativo para proteger versões, EXCETO para um uri (um ponto de extremidade do webhook para um modo de sandbox do fornecedor - nenhum certificado SSL válido, pois isso não é produção, portanto devemos permitir http). Além do domínio do aplicativo, existem domínios do site do cliente que também são executados por meio dele, portanto, NÃO queremos que eles sejam redirecionados, pois nenhum deles tem SSL, portanto, correspondemos explicitamente ao HTTP_HOST.
Esse é um padrão de front controller, queremos que index.php manipule todas essas solicitações para não-arquivos e não-diretórios para todos os domínios e sobre SSL apenas para o domínio do aplicativo.
Parece tão fácil:
RewriteEngine on
RewriteBase "/"
# Redirect all app domain urls to ssl
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} "^app\.example\.com$" [NC]
RewriteCond %{REQUEST_URI} "!^/AllowThisUri/Http"
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# I had to split this -d rule off of the -f rule to account for custom
# domain homepages from not being routed to the front controller when
# transitioning from centos6/apache2.2 for some reason
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} "!^/$"
RewriteRule "^(.*)$" index.php [L]
# Redirect non-files to entry script
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule "^(.*)$" index.php [L]
Mas o que está acontecendo é quando eu testo com
curl http://app.example.com/AllowThisUri/Http
A última regra a ser passada para index.php está sendo usada, mas ao invés de ser processada pelo index.php, ela está redirecionando para lá ... curl returns (shortened response)
<title>301 Moved Permanently</title>
<p>The document has moved <a href="https://app.example.com/index.php">here</a>.</p>
Então, se eu comentar esta nova exclusão RewriteCond:
#RewriteCond %{REQUEST_URI} "!^/AllowThisUri/Http"
Acontece o esperado, ele redireciona para o mesmo URL, exceto com https:
<title>301 Moved Permanently</title>
<p>The document has moved <a href="https://app.example.com/AllowThisUri/Http">here</a>.</p>
Se eu remover completamente o redirecionamento para a lógica https, recebo a resposta do front controller que espero (apenas imprime oi para teste).
#RewriteCond %{HTTPS} off
#RewriteCond %{HTTP_HOST} "^app\.example\.com$" [NC]
#RewriteCond %{REQUEST_URI} "!^/AllowThisUri/Http"
#RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Então eu coloquei tudo de volta - exatamente como começamos, e eu posso modificar o R = 301 para 302 da seguinte forma:
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
e com certeza muda a resposta de redirecionamento inesperada:
<title>302 Found</title>
<p>The document has moved <a href="https://app.example.com/index.php">here</a>.</p>
Espero que isso faça sentido. É prolixo explicar, peço desculpas.
O que eu vejo é que a condição! ^ / AllowThisUri / Http está combinando e nós pulamos a regra de redirecionamento https, e as regras continuam a processar, no momento em que ela chega na última regra enviando-a para index.php, é como se a parte de redirecionamento da REGRA ELE SALTADA parecesse estar de alguma forma e afetando o resultado. Não faz absolutamente nenhum sentido para mim.
Para reiterar, sem excluir o uri com um RewriteCond, os redirecionamentos não ssl para ssl funcionarão conforme o esperado. Para remover completamente toda essa lógica de redirecionamento, o controlador frontal index.php responde com a resposta esperada. É quando adicionamos esse RewriteCond adicional para excluir o uri, que ele se comporta de maneira incorreta / inesperada e retorna um redirecionamento TO index.php ao invés de ser processado e retornar a resposta esperada do front controller.
Talvez alguém saiba de algumas configurações obscuras ou talvez uma coisa do apache 2.4 que causaria isso?
Obrigado pelo seu tempo.