¿Por qué RewriteRule para "^//(.*)" (comienza con doble barra) no redirige a una sola barra?

Aug 17 2020

Tenga esta regla de reescritura en el contexto de vHost. Pero no reescribe las solicitudes que comienzan con //.*(doble barra). Solo los sirve desde /.*(una sola barra) en lugar de responder con una redirección a/.*

RewriteRule "^//(.*)" "/$1" [R=301,L]

¿Por qué no funciona esto?

Respuestas

2 MrWhite Aug 18 2020 at 06:51
RewriteRule "^//(.*)" "/$1" [R=301,L]

Esto nunca coincidirá porque la ruta URL con la que coincide el RewriteRule patrón ya ha reducido todas las instancias de múltiples barras a una sola barra.

Para redirigir tales solicitudes, puede hacer uso de esta "función" y simplemente redirigir "a sí mismo" y verificar THE_REQUESTla variable del servidor para determinar si había varias barras inclinadas en la solicitud inicial. THE_REQUESTes la primera línea del encabezado de la solicitud y contiene la URL de la solicitud sin procesar (excluyendo el protocolo y el nombre de host, pero incluyendo la cadena de consulta) tal como la envió el cliente.

Por ejemplo, para redirigir todas las instancias de varias barras a una sola barra a lo largo de la ruta de la URL, no solo al principio, puede hacer algo como esto:

RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule (.*) $1 [R=301,L]

La expresión regular \s[^?]*//garantiza que no coincidamos con múltiples barras en la parte de la cadena de consulta de la URL (que de lo contrario daría como resultado un bucle de redirección).


¿ RewriteCond %{THE_REQUEST} ^//Nos permitiría aplicar la regla de reescritura solo a aquellos que comienzan con barras inclinadas dobles, ignorando todas las demás instancias de barras inclinadas dobles?

No del todo, THE_REQUESTla variable del servidor en realidad contiene la primera línea completa del encabezado de la solicitud HTTP. En otras palabras, una cadena de la forma:

GET /foo/bar.html HTTP/1.1

O GET //foo/bar.html HTTP/1.1si hay una doble barra al comienzo de la ruta de la URL, entonces necesitaría algo como esto:

RewriteCond %{THE_REQUEST} \s//[^/]
RewriteRule (.*) $1 [R=301,L]

... para capturar todos los métodos de solicitud. Y específicamente solo una barra doble, no barras triples, etc. al comienzo de la ruta URL solamente.

\s//[^/]- Eso es un espacio (después del método de solicitud ) seguido de 2 barras y algo más que una barra (es decir, un espacio para la raíz del documento o alguna otra ruta URL).