如何编写 IF 包含条件匹配通过 RewriteRules 设置的 2 个 ENV 变量

How to write an IF contains condition matching 2 ENV variables set via RewriteRules

给出上下文,目标:

使用 apache httpd 我需要测试请求 uri 的上下文段是否包含在 header 中发送的 cookie 值中,然后再将用户重定向到初始页面以进行 cookie 确认,或允许他们访问网站。

假设如下:

url: http://www.example.com/en/gb/main.html

cookie:;acceptedCookies=fr,en,de,it

如果url的语言段="en",这就是用户接受的Cookies。然后允许用户访问主站点,否则将用户重定向到初始页面。

我试过的:

SetEnvIf Host ^ uriCountryCode=NUL
SetEnvIfNoCase Request_URI "^(.+)?\/([a-zA-Z]{2})\/[a-zA-Z]{2}\/.+$" uriCountryCode=

SetEnvIf Host ^ acceptedCookieList=EMP 
SetEnvIf Cookie "(^|;\*)acceptedCookies=([^;]+)?" acceptedCookieList=
#1st.
<If "%{acceptedCookieList} =~ %{uriCountryCode}">
// Doesn't work
</If>

#2nd.
<If "env('acceptedCookieList') =~ env('uriCountryCode')">
// No luck
</If>

#3rd.
<If "env('acceptedCookieList') =~ /env('uriCountryCode')/">
// Now I'm just guessing
</If>

#4th.
RewriteCond %{acceptedCookieList} !%{uriCountryCode}
RewriteCond %{REQUEST_URI} !^/en/gb/splash.html$ [NC]
RewriteRule ^(.+)$ /mt/en/splash [L,R=301]

我最近了解到,其中一些模块,即 env('x') 不会加载 SetEnvIf 变量,因为 SetEnvIf 变量加载得不够早,无法访问,但我正在尝试找到一个httpd 解决这个我的问题

  1. mod_rewrite可以set environment variables.
  2. 使用 302 redirect (Moved Temporarily) instead of a 301 redirect(永久移动)。
  3. 匹配客户端提供的任意正则表达式(即 acceptedCookies cookie 的内容)是危险的。尽管如此, httpd expressions language doesn't have a built-in "contains" function and so it's non-obvious how to avoid the regex matching. This will make your server(s) susceptible to DoS attacks.

综上所述,请考虑以下内容:

RewriteCond %{HTTP_COOKIE} acceptedCookies=([^;]+)
RewriteRule ^.*$ - [E=COOKIE_ACCEPTED_LANGS:%1]

RewriteCond %{REQUEST_URI} ^/([^/]+)/.*$
RewriteRule ^.*$ - [E=URL_LANG:%1]

RewriteCond expr %{ENV:URL_LANG} =~ %{ENV:COOKIE_ACCEPTED_LANGS}
RewriteCond %{REQUEST_URI} !^/en/gb/splash.html$ [NC]
RewriteRule ^.*$ /mt/en/splash [R]

遵循@Avi 的解决方案可以工作,但任何允许长度未知的客户端值执行验证的解决方案都存在根本性缺陷,存在超出缓冲区和 DOS 的潜在风险。