Apache에서 RewriteCond에 "AND", "OR"을 사용하는 방법은 무엇입니까?


115

이것이 RewriteCondApache에서 AND, OR을 사용하는 방법 입니까?

rewritecond A [or]
rewritecond B
rewritecond C [or]
rewritecond D
RewriteRule ... something

됩니다 if ( (A or B) and (C or D) ) rewrite_it.

그래서 "OR"이 "AND"보다 우선 순위가 높은 것 같습니까? (A or B) and (C or D)구문 처럼 쉽게 말할 수있는 방법이 있습니까?


1
네, 맞습니다. [OR]은 (암시 적) "AND"보다 우선 순위가 높습니다. 결합 된 조건은 실제로 ((A 또는 B) 및 (C 또는 D))입니다.
Doin

2
ckollars.org/apache-rewrite-htaccess.html#precedence 에서 자세한 내용이 도움 이 될 수 있습니다.
Chuck Kollars 2016 년

답변:


118

이것은 흥미로운 질문이며 문서에 명시 적으로 설명되어 있지 않기 때문에 mod_rewrite소스 코드를 통해 대답 할 것 입니다 . 오픈 소스 의 큰 이점을 보여줍니다 .

상단 섹션에서 이러한 플래그의 이름을 지정하는 데 사용정의를 빠르게 찾을 수 있습니다 .

#define CONDFLAG_NONE               1<<0
#define CONDFLAG_NOCASE             1<<1
#define CONDFLAG_NOTMATCH           1<<2
#define CONDFLAG_ORNEXT             1<<3
#define CONDFLAG_NOVARY             1<<4

CONDFLAG_ORNEXT를 검색 하면 [OR] 플래그의 존재에 따라 사용되는지 확인합니다 .

else if (   strcasecmp(key, "ornext") == 0
         || strcasecmp(key, "OR") == 0    ) {
    cfg->flags |= CONDFLAG_ORNEXT;
}

다음 플래그 발생은 RewriteRule에있는 모든 RewriteConditions를 통과하는 루프를 찾을 수 있는 실제 구현 이며 기본적으로 수행하는 작업은 (명확성을 위해 제거, 주석 추가)입니다.

# loop through all Conditions that precede this Rule
for (i = 0; i < rewriteconds->nelts; ++i) {
    rewritecond_entry *c = &conds[i];

    # execute the current Condition, see if it matches
    rc = apply_rewrite_cond(c, ctx);

    # does this Condition have an 'OR' flag?
    if (c->flags & CONDFLAG_ORNEXT) {
        if (!rc) {
            /* One condition is false, but another can be still true. */
            continue;
        }
        else {
            /* skip the rest of the chained OR conditions */
            while (   i < rewriteconds->nelts
                   && c->flags & CONDFLAG_ORNEXT) {
                c = &conds[++i];
            }
        }
    }
    else if (!rc) {
        return 0;
    }
}

이것을 해석 할 수 있어야합니다. 그것은 OR이 더 높은 우선 순위를 가지며 귀하의 예는 실제로 if ( (A OR B) AND (C OR D) ). 예를 들어 다음과 같은 조건이있는 경우 :

RewriteCond A [or]
RewriteCond B [or]
RewriteCond C
RewriteCond D

로 해석됩니다 if ( (A OR B OR C) and D ).


1
주어진 예제 .htaccess에서 소스 코드를 실행하면 ((A OR B) 및 C) 또는 D) [즉, OP가 바라는 내용도 처음에 계산 한 내용도 생성되지 않습니다]. 내 해석 오류를 찾는 데 도움을 줄 수 있습니까? [더 설명하자면 그 반대는 어떨까요? ((A OR B) AND (C OR D))를 구현하려면 .htaccess 파일에 정확히 하나의 코드가 있어야합니까?]
Chuck Kollars

3
+1 for '오픈 소스의 큰 이점 입증':)-@ChuckKollars 논리는 생성하지 않습니다 (((A 또는 B) 및 C) 또는 D) 그러나 (A 또는 B) 및 (C 또는 D). 루프를 통과 할 때마다 A와 C를 볼 때만 설정되는 CONDFLAG_ORNEXT를 확인합니다. 설정시 현재 조건이 통과되면 다음 조건을 건너 뛰거나 미래 조건이 실패 할 수 있기 때문에 현재 조건이 실패한 것을 계속 신경 쓰지 않습니다. 통과하고 마지막 OR 그룹에는 플래그가 설정되지 않으므로 모든 것이 실패하면 전체가 실패합니다.
tempcke 2015 년

1
((A and B) OR (C and D))-나는 결국 (A and (B or C) and D)
Pete

한다 RewriteCond한다 RewriteCond B RewriteRule의 AB한다 RewriteCond C한다 RewriteCond D RewriteRule의 CD : 당신은 두 개의 별도의 규칙으로 분할 그것에 의해 ((A와 B) 또는 (C와 D))를 할 수 @WillshawMedia
이삭

3

많은 어려움을 겪고 일반적이고 유연하며 더 읽기 쉬운 솔루션을 얻기 위해 제 경우에는 OR 결과를 ENV 변수에 저장하고 해당 변수 의 AND를 수행했습니다 .

# RESULT_ONE = A OR B
RewriteRule ^ - [E=RESULT_ONE:False]
RewriteCond ...A... [OR]
RewriteCond ...B...
RewriteRule ^ - [E=RESULT_ONE:True]

# RESULT_TWO = C OR D
RewriteRule ^ - [E=RESULT_TWO:False]
RewriteCond ...C... [OR]
RewriteCond ...D...
RewriteRule ^ - [E=RESULT_TWO:True]

# if ( RESULT_ONE AND RESULT_TWO ) then ( RewriteRule ...something... )
RewriteCond %{ENV:RESULT_ONE} =True
RewriteCond %{ENV:RESULT_TWO} =True
RewriteRule ...something...

요구 사항 :

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.