我有一个 Nginx 缓存服务器从源服务器获取内容,源服务器设置Cache-Control
为Public
,以便我的 Nginx 缓存服务器可以缓存内容并减少对源服务器的请求。但在为用户提供服务时,我不希望它再发送缓存Public
,而是将其设置为,Private
以便其他人(此网络之外)无法缓存或修改它。
我仍然需要它传递最大年龄并尝试通过发送的自定义标头来执行此操作,但条件if
失败。
仅此一项就可以了:
add_header Cache-Control "private, max-age=$upstream_http_adr_private_cache_seconds";
此条件不成立
if ($upstream_http_adr_private_cache_seconds) {
add_header Cache-Control "private, max-age=$upstream_http_adr_private_cache_seconds";
}
但这次测试也失败了:
if ($upstream_http_adr_private_cache_seconds) {
return 404;
}
我做错了什么?还是还有其他方法可以public
改变private
?
答案1
来自的指令在变量ngx_http_rewrite_module
评估之前进行处理$upstream_...
。您不应将 nginx 配置视为编程语言,其中您的操作按源代码中出现的顺序执行。例如,无论您在指令之前还是之后使用proxy_set_header
指令,都没有关系。来自的指令是一个特殊的故事,它们与任何其他指令都不同,您可以阅读一些详细信息proxy_pass
ngx_http_rewrite_module
这里。
对于您的情况,您可以使用map
翻译:
map $upstream_http_adr_private_cache_seconds $cache_control {
"" ""; # empty string if no custom header present
default "private, max-age=$upstream_http_adr_private_cache_seconds";
}
...
server {
...
add_header Cache-Control $cache_control;
...
}
$upstream_http_adr_private_cache_seconds
如果翻译的结果$cache_control
为空字符串,则 nginx 根本不会设置 Cache-Control(或当传递空值作为 add_header 指令的参数值时任何其他 HTTP 标头)。
更新
OP 提出了附加问题:
如果
Cache-Control: public
标题已存在,则两个标题均保留(一个public
,一个private
),是否有办法仅在找到自定义标题时删除公共标题?
解决方案如下:
map $upstream_http_adr_private_cache_seconds $cache_control {
"" $upstream_http_cache_control; # use original upstream Cache-Control header if no custom header is given
default "private, max-age=$upstream_http_adr_private_cache_seconds";
}
...
server {
...
proxy_hide_header Cache-Control; # clear Cache-Control header that came from upstream
add_header Cache-Control $cache_control; # set Cache-Control header again
...
}