Caracteres cirílicos en las reglas de reescritura causan errores 404 Not Found
Tengo una regla de reescritura que incluye el URI de una página:
(<page-uri>)/someaction/(\d+)
Si el URI de la página incluye caracteres cirílicos, como доска-объявлений
, la regla se almacena como:
(%d0%b4%d0%be%d1%81%d0%ba%d0%b0-%d0%be%d0%b1%d1%8a%d1%8f%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9)/someaction/(\d+)
Si vas a una página que incluye un enlace a una URL que coincide con la regla y haces clic en el enlace, el navegador cargará la página de destino sin problemas y WordPress puede hacer coincidir la regla con la URL solicitada.
En Safari (Mac), sin embargo, si copias la URL con Clic Derecho > Copiar Enlace y luego intentas cargar la página de destino pegando la URL copiada en una nueva pestaña, obtendrás un error 404 Not Found.
Cuando copias la URL en Safari, la URL se almacena con codificación porcentual donde los caracteres que representan los octetos para los caracteres cirílicos están todos en mayúsculas:
%D0%B4%D0%BE%D1%81%D0%BA%D0%B0-%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9/someaction/1
No he podido reproducir el problema en Chrome o Firefox (ambos en Mac) porque ambos almacenan la URL usando caracteres en minúsculas para representar los octetos.
Esa URL con codificación porcentual es lo que WordPress recibe a través de la variable $_SERVER['REQUEST_URI']
. El problema es que el código responsable de hacer coincidir la URI solicitada con las reglas de reescritura hace una comparación sensible a mayúsculas/minúsculas (ver método parse_request
en /wp-includes/class-wp.php
), lo que hace imposible que WordPress reconozca mi regla, a pesar de que
%D0%B4%D0%BE%D1%81%D0%BA%D0%B0-%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9
y
%d0%b4%d0%be%d1%81%d0%ba%d0%b0-%d0%be%d0%b1%d1%8a%d1%8f%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9
representan la misma secuencia de caracteres.
- ¿Alguien sabe cómo prevenir los errores 404 Not Found cuando los navegadores envían la solicitud usando octetos con diferente capitalización?
- ¿Es esto algo que WordPress debería soportar? ¿O debería intentar eliminar los URI de página de mis reglas de reescritura para evitar el problema?

Terminé siguiendo el consejo de @Kolya Korobochkin y agregué versiones en mayúsculas y minúsculas de las reglas de reescritura que incluyen octetos escapados.
$regular_page_uri = get_page_uri( $page->ID );
$uppercase_page_uri = preg_replace_callback(
'/%[0-9a-zA-Z]{2}/',
create_function( '$x', 'return strtoupper( $x[0] );' ),
$regular_page_uri
);
El plugin Percent Encode Capital Letter utiliza un enfoque similar para convertir los octetos en cada URL a su versión en mayúsculas. Sin embargo, el plugin está desactualizado y puede que no realice la conversión en todos los lugares necesarios. Además, creo que la mayoría de los usuarios del plugin en el que estoy trabajando no tendrán URLs con octetos codificados, por lo que ejecutar preg_replace_callback
para todas las URLs es un esfuerzo innecesario.
Usar caracteres en mayúsculas para representar octetos es la forma recomendada de hacer el codificado porcentual (Ver RFC3986, Sección 2.1). Por lo tanto, una mejor solución sería que WordPress actualice su función utf8_uri_encode
para escapar los octetos usándolos. La mayoría de los navegadores que probé parecen mantener el caso original, mientras que otros, como Safari, lo convierten a mayúsculas si tienen la oportunidad.
