[apache] .htaccess 재 작성 규칙 디버깅을위한 팁

많은 포스터는 .htaccess파일 내에서 RewriteRule 및 RewriteCond 문을 디버깅하는 데 문제가 있습니다. 이들 중 대부분은 공유 호스팅 서비스를 사용하고 있으므로 루트 서버 구성에 액세스 할 수 없습니다. 많은 응답자들이 제안한대로 .htaccess파일 재 작성을 피할 수 없으며 RewriteLogLevel “을 활성화 할 수 없습니다 . 또한 많은 .htaccess특정 함정과 제약 조건이 잘 설명되어 있지 않습니다. 로컬 테스트 LAMP 스택 설정에는 대부분의 학습 곡선이 너무 많습니다. .

그래서 내 Q는 규칙을 스스로 디버깅 하는 방법을 권장합니다 . 아래에 몇 가지 제안을 제공합니다. 다른 제안을 부탁드립니다.

  1. mod_rewrite 엔진이 .htaccess파일을 순환한다는 것을 이해 하십시오 . 엔진은 다음 루프를 실행합니다.

    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
    

    따라서 규칙이 반복적으로 실행되며 URI 경로를 변경하면 다른 .htaccess파일이 있으면 실행될 수 있습니다. 따라서 필요한 경우 RewriteCond규칙 실행을 중지하기 위해 추가를 추가하여이 루프를 종료하십시오 . .htaccess다중 레벨 규칙 세트를 명시 적으로 사용하지 않는 한 하위 레벨 재 작성 규칙 세트를 삭제하십시오 .

  2. 테스트 패턴 세트에 대해 테스트하여 각 Regexp의 구문이 올바른지 확인하고 이것이 유효한 구문인지 확인하고 전체 범위의 테스트 URI로 의도 한 작업을 수행하는지 확인하십시오. 자세한 내용은 아래 답변 을 참조하십시오.

  3. 테스트 디렉토리에서 규칙을 점진적으로 빌드하십시오. .htaccess경로 에서 가장 깊은 파일 실행 “을 사용하여 기본 규칙을 망치거나 사이트 작동을 중지하지 않고 여기에서 별도의 테스트 디렉토리 (트리) 및 디버그 규칙 세트를 설정할 수 있습니다. 개별 규칙에 실패를 현지화하는 유일한 방법이므로 한 번에 하나씩 추가해야합니다.

  4. 더미 스크립트 스텁을 사용하여 서버 및 환경 변수를 덤프하십시오 . (참조 Listing 2는 앱 사용이 말할 경우), blog/index.php당신은이 점을 복사 할 수 test/blog/index.php와 귀하의 블로그 규칙을 테스트하는 데 사용할 test하위 디렉토리. 또한 환경 변수를 사용하여 대체 문자열을 올바르게 해석하는 데 다시 쓰기 엔진이 있는지 확인할 수 있습니다 (예 :

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

    phpinfo 덤프에서 REDIRECT_ * 변수를 찾으십시오 . BTW, 나는 이것을 사용했고 내 사이트에서 %{ENV:DOCUMENT_ROOT_REAL}대신 사용해야한다는 것을 발견했습니다 . 리디렉터 루핑의 경우 REDIRECT_REDIRECT_ * 변수는 이전 패스를 나열합니다. 기타..

  5. 브라우저가 잘못된 301 리디렉션을 캐싱하여 물리지 않도록하십시오 . 아래 답변을 참조하십시오 . 덕분에Ulrich Palha 에게 .

  6. 다시 쓰기 엔진은 내부 하위 요청 (1) 과 버그가 있고 종종 PATH_INFO 처리가 잘못되어 .htaccess컨텍스트 내에서 계단식 규칙에 민감하게 보입니다 (즉, RewriteRule결과는 대체로 이어지고 추가 규칙에는 영향을 미칩니다 ) [NS], [L] 및 [PT] 플래그를 사용하여 방지하십시오.

더 이상의 의견이나 제안?

Listing 1-phpinfo

<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);



답변

다음은 공유 호스팅에서 사용자의 디버깅을 용이하게 할 수있는 규칙 테스트에 대한 추가 팁입니다.

1. 가짜 사용자 에이전트 사용

새 규칙을 테스트 할 때는 fake요청에 사용할 사용자 에이전트 로만 실행하도록 조건을 추가 하십시오. 이렇게하면 사이트의 다른 사람에게는 영향을 미치지 않습니다.

예 :

#protect with a fake user agent
RewriteCond %{HTTP_USER_AGENT}  ^my-fake-user-agent$
#Here is the actual rule I am testing
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteRule ^ http://www.domain.com%{REQUEST_URI} [L,R=302]

Firefox를 사용하는 경우 User Agent Switcher 를 사용하여 가짜 사용자 에이전트 문자열을 작성하고 테스트 할 수 있습니다.

2. 테스트가 끝날 때까지 301을 사용하지 마십시오

사람들이 여전히 규칙을 테스트하고 301을 사용하는 게시물이 너무 많습니다. 하지 마십시오 .

귀하의 사이트에서 제안 1을 사용하지 않을 경우 귀하뿐만 아니라 당시 귀하의 사이트를 방문한 모든 사람이 301의 영향을받습니다.

그것들은 영구적이며 브라우저에 의해 적극적으로 캐시됩니다. 확실해질 때까지 302를 사용하고 301로 변경하십시오.

3. 301은 브라우저에 적극적으로 캐시됩니다

규칙이 작동하지 않고 올바른 것으로 보이며 제안 1 및 2를 사용하지 않은 경우 브라우저 캐시를 지우거나 개인 탐색 중에 다시 테스트하십시오.

4. HTTP 캡처 도구 사용

피들러 와 같은 HTTP 캡처 도구 사용 하여 브라우저와 서버 간의 실제 HTTP 트래픽을보십시오.

다른 사람들이 귀하의이라고 말할 수도 있지만 site does not look right대신all of the images, css and js are returning 404 errors 문제를 범위를 좁히고 있습니다.

다른 사람들이 당신을보고하는 동안 started at URL A and ended at URL C, 당신은 그들이 시작한 것을 볼 수 있습니다URL A, were 302 redirected to URL B and 301 redirected to URL C 입니다. URL C가 궁극적 인 목표 일지라도 이것이 SEO에 나쁘고 수정해야한다는 것을 알게 될 것입니다.

서버 측에 설정된 캐시 헤더를보고, 요청을 재생하고, 테스트 할 요청 헤더를 수정할 수 있습니다.



답변

온라인 .htaccess 재 작성 테스트

RegEx 도움말에 대한 인터넷 검색을 찾았 으므로 .htaccess작은 수정 을 할 때마다 새 파일 을 업로드하지 않아도 많은 시간이 절약되었습니다 .

사이트에서 :

htaccess 테스터

htaccess 재 작성 규칙을 테스트하려면 규칙을 적용 할 URL을 채우고 htaccess 내용을 더 큰 입력 영역에 놓고 “지금 확인”단추를 누르십시오.


답변

.htaccess 파일에서 일치하는 상대 URL임을 잊지 마십시오.

.htaccess 파일에서 다음 RewriteRule은 절대 일치하지 않습니다.

RewriteRule ^/(.*)     /something/$s


답변

각 Regexp의 구문이 올바른지 확인하십시오

테스트 패턴 세트에 대해 테스트하여 유효한 구문인지 확인하고 전체 테스트 URI로 의도 한대로 수행하는지 확인하십시오.

이를 위해 사이트의 개인 / 테스트 디렉토리에 추가 할 수있는 간단한 스크립트는 아래 regexpCheck.php를 참조하십시오 . 예쁘지 않고 간략하게 설명했습니다. 이것을 regexpCheck.php웹 사이트에서 사용하기 위해 테스트 디렉토리 의 파일 에 붙여 넣으십시오. 이렇게하면 정규 표현식을 작성하고 테스트 사례 목록과 비교하여 테스트 할 수 있습니다. 여기에서 PHP PCRE 엔진을 사용하고 있지만 Apache 소스를 살펴본 결과 기본적으로 Apache에서 사용되는 것과 동일합니다. 템플릿을 제공하고 정규 표현식 기술을 구축하는 데 도움이되는 많은 방법과 자습서가 있습니다.

Listing 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>


답변

달러 기호가 아닌 변수 앞에 백분율 기호를 사용해야합니다.

그것은이다 %{HTTP_HOST}, 하지 ${HTTP_HOST} . error_log에는 아무것도 없으며 내부 서버 오류는 없으며 정규 표현식이 여전히 정확하며 규칙이 일치하지 않습니다. django / genshi 템플릿으로 많은 작업을 ${}하고 근육 메모리에서 변수를 대체 하면 정말 무시 무시합니다 .


답변

내가 낭비한 두 시간 중 하나 :

이 모든 팁을 적용하고 서버 오류 로그에 액세스 할 수 없기 때문에 500 개의 오류 만 발생하는 경우 .htaccess가 아니라 리디렉션되는 파일에 문제가있을 수 있습니다.

.htaccess- 문제를 해결 한 후에는 일부 권한에 대해 잊어 버린 경우에도 2 시간 더 더 문제를 해결하려고했습니다.


답변

환경 변수를 설정하고 헤더를 사용하여 수신하십시오.

OP에서 언급 한 것처럼 RewriteRule 줄을 사용하여 새 환경 변수를 만들 수 있습니다.

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

그러나 서버 측 스크립트가 작동하지 않으면이 환경 변수를 어떻게 읽을 수 있습니까? 한 가지 해결책은 헤더를 설정하는 것입니다.

Header set TEST_FOOBAR "%{REDIRECT_TEST0}e"

이 값 %{NAME}e 환경 변수 지정자를 포함하여 형식 지정자를 허용합니다 (소문자 e를 잊지 마십시오). 때로는 REDIRECT_접두사 를 추가해야 하지만 접두사가 추가 될 때와 접두사가 추가되지 않을 때는 해결하지 못했습니다.