即使调用了ngx.exit(),Nginx仍然使用200来响应。

我正在尝试从 S3 提供静态内容。我正在使用 nginxlua 脚本进行配置。我对 nginxlua 都不熟悉。

我要实现的任务是:

  1. 将请求的 URL 传递到 nginx 中。
  2. 验证 URL 的查询参数。
  3. 如果参数有效,则从 S3 中提供服务。
  4. 如果参数无效,则发送错误响应。

我的 nginx.conf 文件如下:

location ~ "^/media/(.*?)/(.*?)/(.*)$" {
     set $mediaUrl "$1/$2/$3";
     set $key "$2/$3"
     set $target http://$1.s3.amazonaws.com

     rewrite_by_lua "
         local uri = '/authenticate'
         local res = ngx.location.capture(uri, {args = { param = '/xmedia/'.. ngx.var.mediaUrl }})

         if (res.status ~= 200) then
              return ngx.exit(ngx.HTTP_GONE)
              end
         ";

         rewrite .* /$key break;
         proxy_pass $target;
}

location "/authenticate" {
    proxy_set_header Range "";
    proxy_set_header Content-Range "";
    set_by_lua $param "
        local params = ngx.req.get_uri_args()
        return params.param
    ";

    set $test_url http://127.0.0.1:some_port/authenticate?url=$param;
    proxy_pass $test_url;
 }

在我的情况下,如果 authenticate 返回 200,则一切正常。但是,即使 authenticate 返回 null,nginx 也会返回正确的文件,并且不会给出 if 语句中指定的错误报告:return ngx.exit(ngx.HTTP_GONE)

我是否做错了什么?如何以有效的方式实现预期的行为?

谢谢。

点赞
用户1058509
用户1058509

正如在您问题的评论中已经提到的,HttpRewriteModule始终在rewrite_by_lua之前执行; 因此您必须使用 ngx.req.set_uri 将逻辑放在_rewrite_by_lua_部分,就像这样:

location ~ "^/media/(.*?)/(.*?)/(.*)$" {
     set $mediaUrl "$1/$2/$3";
     set $key "$2/$3"
     set $target http://$1.s3.amazonaws.com

     rewrite_by_lua "
         local uri = '/authenticate'
         local res = ngx.location.capture(uri, {args = { param = '/xmedia/'.. ngx.var.mediaUrl }})
         if (res.status ~= 200) then
              ngx.exit(ngx.HTTP_GONE)
         else
            ngx.req.set_uri(string.format('/%s', ngx.var.key))
         end
    ";
     proxy_pass $target;
    }
...
2014-12-03 20:42:14