apache Consejos para depurar reglas de reescritura .htaccess




7 Answers

Prueba de reescritura .htaccess en línea

Encontré this ayuda de Google GoBlog para RegEx, me ahorró mucho tiempo al tener que cargar nuevos archivos .htaccess cada vez que hago una pequeña modificación.

desde el sitio:

probador htaccess

Para probar sus reglas de reescritura de htaccess, simplemente complete la url a la que está aplicando las reglas, coloque el contenido de su htaccess en el área de entrada más grande y presione el botón "Comprobar ahora".

apache .htaccess mod-rewrite

Muchos carteles tienen problemas para depurar sus declaraciones RewriteRule y RewriteCond dentro de sus archivos .htaccess . La mayoría de estos utilizan un servicio de alojamiento compartido y, por lo tanto, no tienen acceso a la configuración del servidor raíz. No pueden evitar el uso de archivos .htaccess para la reescritura y no pueden habilitar un RewriteLogLevel ", como sugieren muchos encuestados. También hay muchos errores y limitaciones específicas de .htaccess no se cubren bien. La configuración de una pila de LAMP de prueba local implica demasiado curva de aprendizaje para la mayoría.

Así que mi Q aquí es cómo recomendaríamos que depuren sus reglas ellos mismos . Proporciono algunas sugerencias a continuación. Otras sugerencias serían apreciadas.

  1. Comprenda que el motor mod_rewrite recorre los archivos .htaccess . El motor ejecuta este bucle:

    do
      execute server and vhost rewrites (in the Apache Virtual Host Config)
      find the lowest "Per Dir" .htaccess file on the file path with rewrites enabled
      if found(.htaccess)
         execute .htaccess rewrites (in the user's directory)
    while rewrite occurred
    

    Por lo tanto, sus reglas se ejecutarán repetidamente y si cambia la ruta de URI, entonces puede terminar ejecutando otros archivos .htaccess si existen. Así que asegúrese de terminar este bucle, si es necesario, agregando RewriteCond adicional para detener el encendido de las reglas. También elimine cualquier conjunto de reglas de reescritura .htaccess nivel inferior a menos que intente explícitamente usar conjuntos de reglas de múltiples niveles.

  2. Asegúrese de que la sintaxis de cada Regexp sea correcta al realizar pruebas contra un conjunto de patrones de prueba para asegurarse de que sea una sintaxis válida y haga lo que pretende con un rango completo de URI de prueba. Vea la respuesta a continuación para más detalles.

  3. Construye tus reglas de forma incremental en un directorio de prueba. Puede usar "ejecutar el archivo .htaccess más profundo en la función de la ruta" para configurar un directorio de prueba (árbol) por separado y depurar los conjuntos de reglas aquí sin arruinar sus reglas principales y dejar de funcionar su sitio. Debe agregarlos uno por uno, ya que esta es la única manera de localizar fallas en reglas individuales.

  4. Utilice un código auxiliar de prueba ficticio para volcar las variables de entorno y servidor . (Consulte el Listado 2 ) Si su aplicación usa, digamos, blog/index.php entonces puede copiar esto en test/blog/index.php y usarlo para probar las reglas de su blog en el subdirectorio de test . También puede usar variables de entorno para asegurarse de que el motor de reescritura interpreta correctamente las cadenas de sustitución, por ejemplo

    RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]
    

    y busque estas variables REDIRECT_ * en el volcado phpinfo. Por cierto, utilicé este y descubrí en mi sitio que tenía que usar %{ENV:DOCUMENT_ROOT_REAL} lugar. En el caso de redireccionamiento en bucle, las variables REDIRECT_REDIRECT_ * listan el pase anterior. Etc.

  5. Asegúrese de no ser mordido por el navegador que almacena en caché las redirecciones 301 incorrectas . Ver respuesta a continuación . Mi agradecimiento a Ulrich Palha por esto.

  6. El motor de reescritura parece ser sensible a las reglas en cascada dentro de un contexto .htaccess , (es decir, cuando RewriteRule produce una sustitución y esto se RewriteRule a otras reglas), ya que encontré errores con las solicitudes internas (1) y el procesamiento incorrecto de PATH_INFO. que a menudo se puede evitar mediante el uso de las banderas [NS], [L] y [PT].

¿Algún comentario o sugerencia más?

Listado 1 - phpinfo

<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);



Asegúrese de que la sintaxis de cada Regexp es correcta

realizando pruebas contra un conjunto de patrones de prueba para asegurarse de que sea una sintaxis válida y que cumpla con su objetivo con un rango completo de URI de prueba.

Vea regexpCheck.php a continuación para ver un script simple que puede agregar a un directorio privado / de prueba en su sitio para ayudarlo a hacer esto. He mantenido esto breve en lugar de bonito. Simplemente regexpCheck.php esto a un archivo regexpCheck.php en un directorio de prueba para usarlo en su sitio web. Esto le ayudará a construir cualquier expresión regular y a probarla en una lista de casos de prueba a medida que lo haga. Estoy usando el motor PHP PCRE aquí, pero después de haber visto la fuente de Apache, esto es básicamente idéntico al utilizado en Apache. Hay muchos HowTos y tutoriales que proporcionan plantillas y pueden ayudarlo a desarrollar sus habilidades de expresión regular.

Listado 1 - regexpCheck.php

<html><head><title>Regexp checker</title></head><body>
<?php 
    $a_pattern= isset($_POST['pattern']) ? $_POST['pattern'] : "";
    $a_ntests = isset($_POST['ntests']) ? $_POST['ntests'] : 1;
    $a_test   = isset($_POST['test']) ? $_POST['test'] : array();

    $res = array(); $maxM=-1; 
    foreach($a_test as $t ){
        $rtn = @preg_match('#'.$a_pattern.'#',$t,$m);
        if($rtn == 1){
            $maxM=max($maxM,count($m));
            $res[]=array_merge( array('matched'),  $m );
        } else {
            $res[]=array(($rtn === FALSE ? 'invalid' : 'non-matched'));
        }
    } 
?> <p>&nbsp; </p>
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME'];?>">
    <label for="pl">Regexp Pattern: </label>
    <input id="p" name="pattern" size="50" value="<?php echo htmlentities($a_pattern,ENT_QUOTES,"UTF-8");;?>" />
    <label for="n">&nbsp; &nbsp; Number of test vectors: </label>
    <input id="n" name="ntests"  size="3" value="<?php echo $a_ntests;?>"/>
    <input type="submit" name="go" value="OK"/><hr/><p>&nbsp;</p>
    <table><thead><tr><td><b>Test Vector</b></td><td>&nbsp; &nbsp; <b>Result</b></td>
<?php 
    for ( $i=0; $i<$maxM; $i++ ) echo "<td>&nbsp; &nbsp; <b>\$$i</b></td>";
    echo "</tr><tbody>\n";
    for( $i=0; $i<$a_ntests; $i++ ){
        echo '<tr><td>&nbsp;<input name="test[]" value="', 
            htmlentities($a_test[$i], ENT_QUOTES,"UTF-8"),'" /></td>';
        foreach ($res[$i] as $v) { echo '<td>&nbsp; &nbsp; ',htmlentities($v, ENT_QUOTES,"UTF-8"),'&nbsp; &nbsp; </td>';}
        echo "</tr>\n";
    }
?> </table></form></body></html>



Establece variables de entorno y usa encabezados para recibirlas:

Puede crear nuevas variables de entorno con líneas RewriteRule, como lo menciona OP:

RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]

Pero si no puede hacer que funcione un script del lado del servidor, ¿cómo puede leer esta variable de entorno? Una solución es establecer un encabezado:

Header set TEST_FOOBAR "%{REDIRECT_TEST0}e"

El valor acepta especificadores de formato , incluido el especificador %{NAME}e para las variables de entorno (no olvide la minúscula e). A veces, tendrá que agregar el prefijo REDIRECT_ , pero no he averiguado cuándo se agrega el prefijo y cuándo no.




Si está creando redirecciones, pruebe con curl para evitar problemas de almacenamiento en caché del navegador. Utilice -I para obtener los encabezados http solamente. Usa -L para seguir todas las redirecciones.




Con respecto a 4., aún debe asegurarse de que su "talón de script ficticio" sea realmente la URL de destino después de que haya terminado la reescritura, ¡o no verá nada!

Un truco similar / relacionado (vea esta pregunta ) es insertar una regla temporal como:

RewriteRule (.*) /show.php?url=$1 [END]

Donde show.php es un script muy simple que solo muestra sus parámetros $_GET (también puede mostrar variables de entorno, si lo desea).

Esto detendrá la reescritura en el punto en que lo inserte en el conjunto de reglas, más bien como un punto de interrupción en un depurador.

Si está utilizando Apache <2.3.9, deberá usar [L] lugar de [END] , y luego deberá agregar:

RewriteRule ^show.php$ - [L]

En la parte superior de su conjunto de reglas, si la URL /show.php se está reescribiendo.




Si planea escribir más de una línea de reglas en .htacesss,
ni siquiera pienses en probar uno de esos métodos de corrección para depurarlo.

He perdido días en establecer múltiples reglas sin comentarios de los REGISTROS, solo para finalmente renunciar a una.
Conseguí Apache en mi PC, copié todo el sitio a HDD y ordené que todo el conjunto de reglas se resolviera usando registros muy rápido.
Luego revisé mis viejas reglas que funcionaban, vi que realmente no están haciendo lo que se deseaba. Una bomba de tiempo para una dirección un poco diferente.

Hay tantas caídas en boxes en las reglas de reescritura, no es una lógica directa.
Puede poner a Apache en funcionamiento en diez minutos, tiene 10 MB, buena licencia, * listo para NIX / WIN / MAC, incluso sin instalación.
Además, verifique las líneas de encabezado de su servidor y obtenga la misma versión de Apache del archivo si es antiguo. Mi OP todavía está en 2.0, muchas cosas no son compatibles.




Dejaré esto aquí, tal vez con detalles obvios, pero me golpeé la cabeza durante horas: tenga cuidado al usar %{REQUEST_URI} porque lo que @Krist van Besien dice en su respuesta es totalmente correcto, pero no para la cadena REQUEST_URI , porque fuera de este TestString comienza con un / . Así que ten cuidado:

RewriteCond %{REQUEST_URI} ^/assets/$  
                            ^
                            | check this pesky fella right here if missing



Related