programing

Apache RewriteRule 명령어로 환경변수를 설정할 때 변수 이름 앞에 "REDIRECT_"가 붙는 원인은 무엇입니까?

goodsources 2022. 9. 6. 22:36
반응형

Apache RewriteRule 명령어로 환경변수를 설정할 때 변수 이름 앞에 "REDIRECT_"가 붙는 원인은 무엇입니까?

Apache 환경변수(PHP에서 사용)를 설정하려고 합니다.[E=VAR:VAL].htaccess 파일의 RewriteRule 규칙에 플래그를 지정합니다.

PHP에서 변수가 서버 변수로 액세스되는 것을 이미 발견했습니다.$_SERVER보다는$_ENV(그건 어느 정도 말이 돼요)하지만, 내 문제는 몇 가지 규칙 때문에[E=VAR:VAL]플래그가 예상대로 작동하여 변수가 됩니다.$_SERVER['VAR']하지만 다른 규칙에서는 변수로 끝납니다.$_SERVER['REDIRECT_VAR']또는$_SERVER['REDIRECT_REDIRECT_VAR'],기타

A. Apache에서 환경변수를 설정하는 원인[E=VAR:VAL]변수 이름 앞에 "REDIRECT_"를 추가하여 이름을 변경하는 플래그

B. 이름이 변경되지 않은 환경변수로 끝나도록 하려면 어떻게 해야 합니까? 그러면 PHP에서 환경변수에 액세스할 수 있습니다.$_SERVER['VAR']변수 이름 앞에 REDIRECT_ 인스턴스가 하나 이상 추가되어 있는지 확인할 필요가 없습니다.

부분 솔루션이 발견되었습니다.개서 규칙의 선두에 다음 항목을 추가하면 원래 ENV가 다시 생성됩니다.각 리다이렉트 상의 VAR(필요한 경우 REDIRECT_VAR 버전도 그대로)

RewriteCond %{ENV:REDIRECT_VAR} !^$
RewriteRule .* - [E=VAR:%{ENV:REDIRECT_VAR}]

이 동작은 유감이며 문서화되어 있지 않은 것 같습니다.

.htaccess per-s

에서 일어나는 일은 다음과 같습니다..htaccess디렉토리 단위(패키지 단위) 컨텍스트:

Apache가 처리한다고 가정합니다..htaccess파일에는 개서 지시가 포함되어 있습니다.

  1. Apache는 표준 CGI/Apache 변수를 모두 사용하여 환경 변수 맵을 채웁니다.

  2. 개서 개시

  3. 환경변수는 다음과 같이 설정됩니다.RewriteRule지시.

  4. Apache가 다음 작업을 중지하는 경우RewriteRule지시(이유)Lflag 또는 규칙 집합의 끝) 및 URL이 에 의해 변경되었습니다.RewriteRuleApache는 요청 처리를 재시작합니다.

    이 부품이 익숙하지 않은 경우 플래그 설명서를 참조하십시오.

    따라서 규칙 집합은 처음부터 다시 실행될 수 있습니다.일반적으로 이 문제는 규칙 중 하나가 내부 또는 외부로 리다이렉트하여 요청 프로세스를 다시 시작할 때 발생합니다.
  5. 제가 관찰한 바로는, 4번, 1번 반복이 되면, 그 다음에 환경변수가 설정된다고 생각합니다.RewriteRule지시문은 앞에 붙는다REDIRECT_환경 변수 맵에 추가(순서는 아니지만 해당 조합으로 구성된 최종 결과).

    이 단계에서는 선택한 변수 이름이 지워집니다. 잠시 후에 이것이 왜 중요하고 불편한지에 대해 설명하겠습니다.

변수 이름 복원

처음 이 문제에 부딪혔을 때, 저는 다음과 같은 일을 하고 있었습니다..htaccess(증명):

RewriteCond %{HTTP_HOST} (.+)\.projects\.

RewriteRule (.*) subdomains/%1/docroot/$1

RewriteRule (.+/docroot)/ - [L,E=EFFECTIVE_DOCUMENT_ROOT:$1]

처음에 환경변수를 설정했을 경우RewriteRuleApache는 재작성 프로세스를 재시작하고 변수 앞에REDIRECT_(위의 4단계와 5단계) 따라서 할당한 이름으로 액세스 할 수 없게 됩니다.

이 경우, 첫 번째RewriteRuleURL 을 변경하기 때문에, 양쪽 모두RewriteRule가 처리되고 Apache가 절차를 재시작하여 처리한다..htaccess두 번째, 두 번째, 첫 번째RewriteRule에 의해 건너뜁니다.RewriteCond지시적인데, 두 번째는RewriteRule일치시키고 환경변수를 다시 설정하며 URL을 변경하지 않습니다.따라서 요청/재작성 프로세스가 다시 시작되지 않고 선택한 변수 이름이 그대로 유지됩니다.이 경우엔 사실 둘 다 가지고 있어요REDIRECT_EFFECTIVE_DOCUMENT_ROOT그리고.EFFECTIVE_DOCUMENT_ROOT를 사용하면,L선두에 서다RewriteRule, 나는 단지EFFECTIVE_DOCUMENT_ROOT.

@trowel의 부분 솔루션도 마찬가지로 동작합니다.재작성 지시어는 다시 처리되고 이름이 변경된 변수는 원래 이름으로 다시 할당되며 URL이 변경되지 않으면 프로세스가 종료되고 할당된 변수 이름이 고정됩니다.

왜 그 기술들이 불충분한가

이 두 기술 모두 중대한 결함이 있습니다.즉, 개서 규칙이 다음과 같습니다..htaccess환경변수를 설정하는 파일은 URL을 보다 깊이 중첩된 디렉토리로 고쳐 씁니다..htaccess파일을 다시 작성하면 할당된 변수 이름이 다시 지워집니다.

다음과 같은 디렉토리 레이아웃이 있다고 가정합니다.

docroot/
        .htaccess
        A.php
        B.php
        sub/
                .htaccess
                A.php
                B.php

그리고...docroot/.htaccess다음과 같습니다.

RewriteRule ^A\.php sub/B.php [L]

RewriteRule .* - [E=MAJOR:flaw]

그래서 네가 부탁하는 거야/A.php, 그리고 그것은 로 고쳐졌습니다.sub/B.php넌 아직 네 능력을 가지고 있어MAJOR변수.

다만, 에 개서 지시가 있는 경우는,docroot/sub/.htaccess(단순히RewriteEngine Off또는RewriteEngine On), 고객님의MAJOR변수는 사라집니다.그 이유는 URL이 다음 주소로 다시 작성되면sub/B.php,docroot/sub/.htaccess처리되며, 개서 지시가 포함되어 있는 경우는, 에서 개서 지령을 개서합니다.docroot/.htaccess다시 처리되지 않습니다.를 가지고 있는 경우REDIRECT_MAJOR끝나고docroot/.htaccess처리되었습니다(예를 들어, 를 생략했을 경우).L처음부터 깃발RewriteRule)는 아직 사용할 수 있지만 선택한 변수 이름을 설정하기 위해 이러한 지시어가 다시 실행되지 않습니다.

상속

예를 들어 다음과 같습니다.

  1. 환경 변수를 설정하다RewriteRule디렉토리 트리의 특정 레벨에서의 지시(예:docroot/.htaccess)

  2. 보다 상세한 레벨의 스크립트로 사용할 수 있도록 한다.

  3. 그것들을 할당된 이름으로 이용할 수 있게 하다

  4. 보다 깊이 내포된 명령어를 다시 쓸 수 있다.htaccess파일

가능한 해결책은 다음과 같습니다.RewriteOptions inherit보다 깊이 내포된 지시..htaccess이를 통해 깊이 중첩되지 않은 파일에서 다시 쓰기 명령을 실행하고 위에서 설명한 기술을 사용하여 선택한 이름으로 변수를 설정할 수 있습니다.단, 보다 깊이 중첩된 디렉토리에서 다시 실행할 때 문제가 발생하지 않도록 덜 중첩된 파일에서 다시 쓰기 지시어를 작성하려면 더 신중해야 하기 때문에 복잡성이 증가합니다.Apache는 보다 깊이 중첩된 디렉토리의 dir 단위 접두사를 삭제하고 해당 값에 대해 덜 중첩된 파일에서 다시 쓰기 명령을 실행한다고 생각합니다.

@trowel의 기술

제가 보기엔 다음과 같은 구조를 사용할 수 있습니다.%{ENV:REDIRECT_VAR}가치 요소에서RewriteRule E플래그(예:[E=VAR:%{ENV:REDIRECT_VAR}])은 문서화되어 있지 않은 것 같습니다.

VAL은 전개되는 백레퍼런스($N 또는 %N)를 포함할 수 있습니다.

정상적으로 동작하고 있는 것 같습니다만, 문서화되어 있지 않은 것에 의존하는 것을 피하고 싶은 경우(잘못하고 있는 경우는 정정해 주세요)는, 다음의 방법으로 간단하게 실시할 수 있습니다.

RewriteCond %{ENV:REDIRECT_VAR} (.+)
RewriteRule .* - [E=VAR:%1]

EnvIf 설정

이것은 문서화된 동작(아래 참조)과 일치하지 않는 것 같기 때문에 이것을 사용하는 것을 권장하지 않습니다.docroot/.htaccess(Apache 2.2.20)을 사용하면 다음과 같습니다.

SetEnvIf REDIRECT_VAR (.+) VAR=$1

이 방법으로 테스트할 수 있는 것은 이전의 SetEnvIf [NoCase]지침에서 정의된 환경변수뿐입니다.

왜요?

이 이름들에 접두사를 붙이는 이유가 뭔지 모르겠어요REDIRECT_mod_rewrite 지시어, 플래그 또는 환경변수에 대해서는 Apache 문서 섹션에 기재되어 있지 않은 것 같기 때문에 그다지 놀랄 일도 아닙니다.

지금으로서는, 지정명을 그대로 두는 것보다 왜 그것이 좋은지에 대한 설명이 없는 것은, 나에게 있어서 큰 폐가 되는 것 같습니다.문서화의 부족은 그것에 대한 나의 회의감을 조장할 뿐이다.

환경변수를 개서규칙으로 할당할 수 있는 것은 편리합니다.적어도 편리합니다.그러나 이러한 이름 바꾸기 행태로 인해 그 유용성은 크게 감소한다.이 투고의 복잡성은 이 행동과 그것을 극복하기 위해 뛰어넘어야 하는 후프가 얼마나 미친 것인지 보여준다.

나는 이것을 전혀 테스트하지 않았고 그것이 A나 B 포인트를 다루지 않는다는 것을 알지만, PHP 문서의 코멘트 및 이러한 변수에 액세스하기 위한 몇 가지 가능한 해결책에 이 문제에 대한 설명이 있습니다.$_SERVER['VAR']:

http://www.php.net/manual/en/reserved.variables.php#79811

편집 - 제공된 질문에 대한 추가 답변:

A: 환경 변수가 리디렉션과 관련된 경우 Apache에 의해 이름이 변경됩니다.예를 들어 다음과 같은 규칙이 있는 경우:

RewriteRule ^index.php - [E=VAR1:'hello',E=VAR2:'world']

그런 다음 VAR1 및 VAR2에 액세스할 수 있습니다.$_SERVER['VAR1']그리고.$_SERVER['VAR2']다만, 페이지를 이렇게 리다이렉트 하면, 다음과 같이 됩니다.

RewriteRule ^index.php index2.php [E=VAR1:'hello',E=VAR2:'world']

그럼 다음 명령어를 사용해야 합니다.$_SERVER['REDIRECT_VAR1'],기타.

B: 이 문제를 해결하는 가장 좋은 방법은 PHP를 사용하고 싶은 변수를 처리하는 것입니다.를 통해 실행되는 함수를 만듭니다.$_SERVER필요한 항목을 찾을 수 있습니다.다음과 같은 기능을 사용할 수도 있습니다.

function myGetEnv($key) {
    $prefix = "REDIRECT_";
    if(array_key_exists($key, $_SERVER))
        return $_SERVER[$key];
    foreach($_SERVER as $k=>$v) {
        if(substr($k, 0, strlen($prefix)) == $prefix) {
            if(substr($k, -(strlen($key))) == $key)
                return $v;
        }
    }
    return null;
}

코드를 변경하고 싶지 않기 때문에(사용하는 라이브러리의 코드도 변경할 수 없기 때문에), 어플리케이션의 부트스트래핑(예:index.php– 재작업합니다.$_ENV변수 앞에 프레픽스를 붙일 수 있도록 superglobalREDIRECT_는, 통상의 목적명으로 고쳐집니다.

// Fix ENV vars getting prepended with `REDIRECT_` by Apache
foreach ($_ENV as $key => $value) {
    if (substr($key, 0, 9) === 'REDIRECT_') {
        $_ENV[str_replace('REDIRECT_', '', $key)] = $value;
        putenv(str_replace('REDIRECT_', '', $key) . '=' . $value);
    }
}

직접 설정할 뿐만 아니라$_ENV, 그러나 우리는 그것을 저장하기도 합니다.putenv()기존 코드와 라이브러리– 이 방법에서는getenv()– 정상적으로 동작합니다.


사이드노트: 헤더를 추출하는 경우 –HTTP_AUTHORIZATION– 코드에서는, 같은 조작을 실시할 필요가 있습니다.$_SERVER:

foreach ($_SERVER as $key => $value) {
    if (substr($key, 0, 9) === 'REDIRECT_') {
        $_SERVER[str_replace('REDIRECT_', '', $key)] = $value;
    }
}

언급URL : https://stackoverflow.com/questions/3050444/when-setting-environment-variables-in-apache-rewriterule-directives-what-causes

반응형