Apache RewriteCond比较RewriteMap时间与TIME变量不生效问题咨询
问题根因
你遇到的配置不生效问题通常由以下三个核心原因导致:
- 时间格式不匹配:默认
%{TIME}变量输出的是14位的YYYYMMDDHHmmss格式,如果你文件中存储的是12位YYMMDDHHmmss格式,直接比较必然逻辑错误 - 返回值带多余空白:txt类型的RewriteMap会保留key与value之间的前缀空白,如果你的映射文件中key和value之间有多个空格/制表符,读取到的value会带前导空格,导致字符串比较失败
- 比较逻辑兼容问题:默认RewriteCond的
</>是词典序比较,若时间字符串位数不一致会出现逻辑错误,部分老版本Apache对纯数字字符串的比较存在兼容缺陷
可行解决方案
方案1:变量清洗+统一格式(兼容Apache 2.2及以上版本)
先清洗RewriteMap返回值的多余空白,同时手动拼接和文件格式完全一致的时间字符串再做比较:
# 定义查询Map RewriteMap lookup "txt:/path/to/file.flat" # 把查询结果存入环境变量,同时去除前后空白 RewriteRule ^ - [E=LOOKUP_VAL:${lookup:somekey|19700101010101}] RewriteRule ^ - [E=LOOKUP_VAL:${ENV:LOOKUP_VAL//[[:space:]]/}] # 匹配规则 # 如果文件是14位YYYYMMDDHHmmss格式用以下配置 RewriteCond %{ENV:LOOKUP_VAL} ^NOT_FOUND$ [OR] RewriteCond %{ENV:LOOKUP_VAL} <"%{TIME_YEAR}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR}%{TIME_MIN}%{TIME_SEC}" # 此处添加你要执行的RewriteRule规则
如果你的文件存储的是12位YYMMDDHHmmss格式,把比较行的时间拼接逻辑替换为"%{TIME_YEAR:2}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR}%{TIME_MIN}%{TIME_SEC}"即可。
方案2:expr表达式数值比较(推荐,Apache 2.4及以上版本)
2.4以上版本支持直接用expr表达式做数值比较,完全避免词典序比较的坑,逻辑更严谨:
RewriteMap lookup "txt:/path/to/file.flat" RewriteCond expr "strtolower('${lookup:somekey|NOT_FOUND}') == 'not_found' || int('${lookup:somekey|19700101010101}') < int('%{TIME_YEAR}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR}%{TIME_MIN}%{TIME_SEC}')" # 此处添加你要执行的RewriteRule规则
调试验证方法
可以临时添加测试规则把变量输出到响应头,确认格式符合预期:
RewriteRule ^ - [E=LOOKUP_VAL:${lookup:somekey|19700101010101}] Header always set X-Debug-Lookup "%{LOOKUP_VAL}e" Header always set X-Debug-Time "%{TIME_YEAR}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR}%{TIME_MIN}%{TIME_SEC}t"
访问任意页面查看响应头的两个调试值,确认没有多余空白、格式完全一致即可。
内容的提问来源于stack exchange,提问作者fls-indinf
相关产品推荐
相关产品推荐

