Nginx不尊重必须重新validation

我想使用nginx作为caching逆向代理。 我也有一个特殊的要求,我认为可以用nginx来完成。

我使用Amazon S3作为原始服务器,并使用已签名的URL来保护内容。 因此,每个用户都会获得一段时间后过期的唯一url。 即使每个用户都有一个唯一的URL,为了让nginxcaching内容,我将caching键定义为仅包含请求文件名(参见下面的configuration)。

那到目前为止工作很好。 问题是,如果请求的URL将是无效的,因为查询string中的签名太旧或无效,服务器无论如何传递文件。 因为它被caching。

我确认了最初的请求必须包含有效的签名。 如果用户请求中的signture无效,nginx无法从服务器上获取(当然)。

现在我想要的是在每个请求上重新查找文件。 此重新查找应该与用户指定的URL一起进行。 如果请求成功,则应该传递caching的文件。

这正是使用Cache-control: must-revalidate应该完成的行为Cache-control: must-revalidate

所以我在我的原始服务器(amazon s3)上configuration了这个头文件。

然后我意识到,nginx并没有相应的行为。

所以文件直接从caching中传递而不需要与原始服务器进行validation。 因此,不好的签名不被识别,用户可以下载。

问题1:在这种情况下,有没有办法让nginx获得必须重新validation的头文件?

这是我的configuration文件

 proxy_cache_path /home/sbgag/cache keys_zone=MYZONE:10m inactive=365d max_size=10g; server { listen 80; server_name test.mydomain.com; location / { proxy_pass http://s3-eu-west-1.amazonaws.com; proxy_set_header Host s3-eu-west-1.amazonaws.com; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_key "$request_filename"; more_set_headers "X-My-Proxy-Cache-Key $request_filename"; more_set_headers "X-My-Proxy-Cache-realpath_root $realpath_root"; more_set_headers "X-My-Proxy-Cache-uri $uri"; proxy_cache MYZONE; proxy_cache_valid 200 365d; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; more_set_headers "X-AppServer $upstream_addr"; # Backend Server / Port more_set_headers "X-AppServer-Status $upstream_status"; # Backend HTTP Status more_set_headers "X-Cache $upstream_cache_status"; # HIT / MISS / BYPASS / EXPIRED } } 

我还发现这个更新日志

 *) Feature: the "proxy_cache_revalidate", "fastcgi_cache_revalidate", "scgi_cache_revalidate", and "uwsgi_cache_revalidate" directives. 

所以我想我玩了。 在将我的nginx启动到最新版本之后,我将caching时间设置为0。 用0s文件从不caching,所以我把它设置为1s。

几乎产生了我想要的行为。 它会导致文件在1秒后在服务器上重新validation。 然后再用用户提供的签名url进行validation。 如果不正确,那就失败了。 此外,该文件不会被删除,因为nginx似乎删除文件不是立即,但只有当空间已满。 所以,即使文件超时,即使另一个客户端提供了一个无效的URL,下一个有效URL的客户端也可以从caching中下载。

然而,在1秒的时间里,每个人都可以下载,但这不是我真正关心的问题。

好吧,这几乎是我想要的,我不喜欢的是,这是一个丑陋的工作,这是基于行为,而不是function的意外。

问题2:没有更好的方法吗?

我最希望将请求传递给一个validation脚本,在那里我可以使用我自己的脚本在backgorund中validation请求。 只有该脚本返回成功,下载是permittetd。 然后利用现有的经过validation的nginxcachingalgorithm。

马博甚至会改写规则。 用重写映射重写到脚本,并在validation成功时仅输出URL。

任何inputappriciated!

我认为你正在寻找的是实际上添加这个:

proxy_cache_bypass $ http_cache_control;

通过这种方式发送具有设置Cache-Control:must-revalidate头部的请求将绕过caching。