Se eu preciso escapar da barra '/' em RewriteCond?
Atualmente escrevo a seguinte regra em .htaccess:
RewriteCond %{QUERY_STRING} rp=/knowledgebase/
RewriteRule ^index\.php$ https://www.datanumen.com/knowledgebase/ [QSD,R=301,L,NC]
No entanto, isso só funciona para URL como https://www.datanumen.com/fi/customer/index.php?rp=/knowledgebase/7/How-to-order-the-full-version-of-DataNumen-Access -Repair.html&language=swedish , mas não funciona para URL como https://www.datanumen.com/fi/customer/index.php?rp=%2Fknowledgebase%2F7%2FHow-to-order-the-full-version- of-DataNumen-Access-Repair.html&language=swedish
Então, eu tenho que modificar a regra, conforme abaixo:
RewriteCond %{QUERY_STRING} rp=/knowledgebase/ [OR]
RewriteCond %{QUERY_STRING} rp=%2Fknowledgebase%2F
RewriteRule ^index\.php$ https://www.datanumen.com/knowledgebase/ [QSD,R=301,L,NC]
Mas eu verifiquei https://serverfault.com/a/968916/280923 e disse " A barra (/) não precisa ser escapada ". Então estou confuso.
Se eu precisar levar todas as situações em consideração, ou seja, a versão com escape e a versão sem escape de '/', então deve haver uma combinação totalmente 4, devo adicionar todas elas como o RewriteCond:
rp=/knowledgebase/
rp=%2Fknowledgebase%2F
rp=%2Fknowledgebase/
rp=/knowledgebase%2F
Por "escape the slash", você realmente quer dizer "devo corresponder a uma barra codificada de URL ou não?". Isso depende inteiramente da solicitação HTTP feita ao seu servidor.
A pergunta/resposta vinculada não está relacionada ao problema atual. Essa questão está lidando com escapes de barra invertida em diretivas/regex do Apache, não URLs codificados por URL (ou % codificados) com os quais você está lidando aqui. Estes são dois tipos muito diferentes de métodos de "escape" para propósitos diferentes.
Você está lidando com URLs codificados em %. Como a URL aparece na solicitação HTTP. Diferentes partes de um URL (principalmente o "caminho" e a "sequência de consulta") têm requisitos de codificação diferentes. Se um caractere específico precisa ser codificado em % depende se ele teria um significado especial nesse contexto.
Conforme definido na RFC3986 , a barra (
/
) não precisa ser estritamente codificada em % na parte da string de consulta da URL. No entanto, as funções de codificação de URL (como em PHP e JavaScript) geralmente codificam % esse caractere. (Acho que isso é amplamente histórico, pois algumas implementações antigas supostamente não lidavam com uma barra não codificada corretamente - referência RFC3986 .)No entanto, independentemente de um caractere precisar ser codificado em URL (para negar seu significado especial), qualquer caractere pode ser codificado em % e isso deve ser tratado da mesma forma que o caractere literal (não codificado).
Se você precisa ou não corresponder
/
(decodificado) ou%2F
(codificado) depende se esse caractere está ou não codificado em % na solicitação.Seu problema é que a
QUERY_STRING
variável do servidor não é % decodificada, ao contrário do caminho de URL que corresponde aoRewriteRule
padrão .Mas... você precisa verificar tanto o %-decoded
/
quanto o %-encoded%2F
? Presumivelmente, você está vinculando consistentemente a apenas um ou outro URL (canônico). Portanto, quaisquer solicitações para a URL não canônica teriam que ser digitadas manualmente ou vinculadas erroneamente por terceiros. Você está recebendo pedidos para ambos? Quais são as consequências de não redirecionar o URL não canônico?Caso contrário, sim, você precisaria verificar ambos (e potencialmente todas as variações/casos de). Embora isso provavelmente seja apenas
/knowledgebase/
ou%2Fknowledgebase%2F
. Mas observe que pode ser%2F
(maiúsculas) ou%2f
(minúsculas). Maiúsculas é apenas uma convenção. Ter que verificar uma codificação mista, como%2Fknowledgebase/
deve ser muito rara. Mas levado ao extremo, isso também é o mesmo que%2f%6b%6e%6f%77%6c%65%64%67%65%62%61%73%65%2f
. A necessidade de lidar com todas essas variações depende da probabilidade de obter tal solicitação e da gravidade da não correspondência da regra.Portanto, para corresponder a
/knowledgebase/
e%2Fknowledgebase%2F
(não diferencia maiúsculas de minúsculas), você pode usar algo como:Você pode evitar a classe de caracteres
[Ff]
e usar oNC
sinalizador para tornar toda a comparação insensível a maiúsculas e minúsculas. Por exemplo:No Apache 2.4, você pode usar a
unescape()
função em uma expressão do Apache com aRewriteCond
diretiva para decodificar a URLQUERY_STRING
antes de fazer a comparação. No entanto, isso realmente não ajuda você, pois não decodifica% as barras, ou seja.%2F
ou%2f
permanece conforme a solicitação (mas quaisquer outros caracteres são % decodificados). Por exemplo:Isso permitiria que você combinasse
rp=%2f%6b%6e%6f%77%6c%65%64%67%65%62%61%73%65%2f
.Ou, se você não estiver esperando nenhum caractere codificado de URL na string de consulta, poderá simplesmente bloquear qualquer solicitação que envie algum! Por exemplo, o seguinte precisaria ir no topo da sua configuração: