mod rewrite - htaccess - cómo usar "Y", "O" para RewriteCond en Apache?
mod_rewrite htaccess (1)
¿Es así como usar AND, O para RewriteCond
en Apache?
rewritecond A [or]
rewritecond B
rewritecond C [or]
rewritecond D
RewriteRule ... something
se convierte en if ( (A or B) and (C or D) ) rewrite_it
.
¿Entonces parece que "O" tiene precedencia más alta que "Y"? ¿Hay alguna manera de decir fácilmente, como en la sintaxis (A or B) and (C or D)
?
Esta es una pregunta interesante y dado que no se explica de forma muy explícita en la documentación, responderé esto pasando por el código fuente de mod_rewrite ; demostrando un gran beneficio de código abierto .
En la sección superior, detectará rápidamente las definiciones utilizadas para nombrar estos indicadores :
#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
y la búsqueda de CONDFLAG_ORNEXT confirma que se usa en función de la existencia del indicador [OR] :
else if ( strcasecmp(key, "ornext") == 0
|| strcasecmp(key, "OR") == 0 ) {
cfg->flags |= CONDFLAG_ORNEXT;
}
La siguiente aparición de la bandera es la implementación real donde encontrará el bucle que recorre todas las RewriteConditions que tiene RewriteRule, y lo que básicamente hace es (despojado, comentarios agregados para mayor claridad):
# 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;
}
}
Deberías poder interpretar esto; significa que O tiene una precedencia más alta, y su ejemplo de hecho conduce a if ( (A OR B) AND (C OR D) )
. Si tuviera, por ejemplo, estas Condiciones:
RewriteCond A [or]
RewriteCond B [or]
RewriteCond C
RewriteCond D
se interpretaría como if ( (A OR B OR C) and D )
.