[Apache] Consejos para depurar reglas de reescritura de .htaccess


Answers

Prueba de reescritura en .htaccess en línea

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

desde el sitio:

probador htaccess

Para probar las reglas de reescritura 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".

Question

Muchos carteles tienen problemas para depurar sus declaraciones RewriteRule y RewriteCond dentro de sus archivos .htaccess . La mayoría de estos están utilizando 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 muchas dificultades y limitaciones específicas de .htaccess no se cubren bien. Configuración de una prueba local La pila LAMP implica una gran cantidad de 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 ciclo:

    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 del URI, puede terminar ejecutando otros archivos .htaccess si existen. Así que asegúrese de finalizar este ciclo, si es necesario agregando RewriteCond adicional para detener la activación de las reglas. Además, elimine los niveles de .htaccess reescriban los conjuntos de reglas a menos que explícitamente intenten usar conjuntos de reglas de varios niveles.

  2. Asegúrese de que la sintaxis de cada Regexp sea correcta al realizar pruebas en 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. Desarrolle sus reglas de forma incremental en un directorio de prueba. Puede utilizar el "ejecutar el archivo .htaccess más profundo en la característica de ruta" para configurar un directorio de prueba (árbol) separado y depurar conjuntos de reglas aquí sin atornillar sus reglas principales y detener el funcionamiento de su sitio. Debe agregarlos de uno en uno porque esta es la única manera de localizar fallas en reglas individuales.

  4. Use un stub de script ficticio para volcar las variables de servidor y de entorno . (Consulte el Listado 2 ) Si su aplicación usa, digamos, blog/index.php , 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 interprete las cadenas de sustitución correctamente, 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 del bucle de redireccionamiento, las variables REDIRECT_REDIRECT_ * enumeran el pase anterior. Etc ..

  5. Asegúrese de no ser mordido por el caché de su navegador al redireccionar 301 incorrectamente . Ver la respuesta a continuación . Mi agradecimiento a Ulrich Palha por esto.

  6. El motor de reescritura parece sensible a las reglas en cascada dentro de un contexto .htaccess (que es donde una RewriteRule da RewriteRule resultado una sustitución y esto cae en otras reglas), ya que encontré errores con sub-solicitudes internas (1) y un procesamiento PATH_INFO incorrecto que a menudo puede evitarse mediante el uso de los indicadores [NS], [L] y [PT].

¿Algún comentario o sugerencia?

Listado 1 - phpinfo

<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);



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

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



Uno de un par de horas que desperdicié:

Si ha aplicado todos estos consejos y solo tiene 500 errores porque no tiene acceso al registro de errores del servidor, tal vez el problema no esté en .htaccess, sino en los archivos a los que redirecciona.

Después de haber arreglado mi problema de .htaccess, pasé dos horas más tratando de arreglarlo un poco más, aunque simplemente había olvidado algunos permisos.




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

He perdido días en establecer múltiples reglas sin comentarios de los LOG, solo para finalmente darme por vencido en uno.
Apagué Apache en mi PC, copié todo el sitio a la unidad de disco duro, y tuve todo el conjunto de reglas resuelto 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 diferente.

Hay tantas caídas de pozo en las reglas de reescritura, no es una cosa de lógica directa en absoluto.
Puede ejecutar Apache y ejecutarlo en diez minutos, es 10MB, buena licencia, * NIX / WIN / MAC listo, 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 anterior. Mi OP todavía está en 2.0, muchas cosas no son compatibles.




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

probando contra un conjunto de patrones de prueba para asegurarse de que es una sintaxis válida y hace lo que usted pretende con una gama completa de URI de prueba.

Consulte regexpCheck.php a continuación para obtener un script simple que puede agregar a un directorio privado / de prueba en su sitio para ayudarlo a hacer esto. He mantenido este breve en lugar de bonito. Simplemente regexpCheck.php esto en un archivo regexpCheck.php en un directorio de prueba para usarlo en su sitio web. Esto lo ayudará a construir cualquier expresión regular y probarla contra una lista de casos de prueba a medida que lo haga. Estoy usando el motor PHP PCRE aquí, pero después de echar un vistazo a la fuente Apache, esto es básicamente idéntico al usado 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>



Si está creando redirecciones, pruebe con curl para evitar problemas de caché del navegador. Use -I para buscar encabezados http solamente. Use -L para seguir todas las redirecciones.




En cuanto a 4., aún debes asegurarte de que tu "stug de script ficticio" sea en realidad el URL objetivo después de que se haya completado la reescritura, ¡o no verás 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 la inserta en el conjunto de reglas, más bien como un punto de interrupción en un depurador.

Si usa Apache <2.3.9, necesitará usar [L] lugar de [END] , y es posible que deba agregar:

RewriteRule ^show.php$ - [L]

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