无法到达POST请求缓存的嵌套位置指令

时间:2017-07-11 18:25:45

标签: symfony nginx nginx-location

我正在配置NginX以支持缓存GET请求+特定的POST请求。 我正在使用symfony框架,因此将URI重写为:app.php / ...。

为了能够分离GET和POST缓存的处理,我创建了一些嵌套的位置指令。

fastcgi_cache_path /nginx_cache_path levels=1:2 keys_zone=one:10m max_size=1g inactive=120m loader_threshold=300 loader_files=150;

server {
    listen 80;
    server_name example.com www.example.com;

    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
        return 444;
    }

    root /path_to_web_server;

    location / {            

        # try to serve file directly. If not existing change to app.php
        try_files $uri /app.php$is_args$args;          

    }

    location ~ ^/images/.*\.(gif|jpg|png)$ {

        root /path_to_images_folder;
    }

    location ~ ^/app\.php(/|$) {

        location ~ /post_request_path {

            fastcgi_cache_key "$request_uri|$request_body";
            fastcgi_cache_valid 5m;           
            fastcgi_cache_methods POST;

            fastcgi_cache one;
            fastcgi_cache_use_stale updating error timeout invalid_header http_500 http_503 http_404;

            fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
            add_header X-Fastcgi-Cache $upstream_cache_status;
            fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;

            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;

            internal;
        }

        location ~ / {

            fastcgi_cache_key $scheme$host$request_uri$request_method;
            fastcgi_cache_valid 60m;          
            fastcgi_cache_methods GET HEAD;

            fastcgi_cache one;
            fastcgi_cache_use_stale updating error timeout invalid_header http_500 http_503 http_404;

            fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
            add_header X-Fastcgi-Cache $upstream_cache_status;
            fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;

            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;

            internal;
        }
}

我的问题:POST请求永远不会被缓存。 “location~ / post_request_path”已经过测试,但从未被NginX选中。

根据NginX调试日志文件:

2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: "/"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "^/images/.*\.(gif|jpg|png)$"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "^/app\.php(/|$)"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "\.php$"
2017/07/11 19:31:00 [debug] 13707#0: *8961 using configuration "/"
2017/07/11 19:31:00 [debug] 13707#0: *8961 internal redirect: "/app.php?"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: "/"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "^/images/.*\.(gif|jpg|png)$"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "^/app\.php(/|$)"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "/post_request_path"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "/"
2017/07/11 19:31:00 [debug] 13707#0: *8961 using configuration "/"

我非常惊讶/ post_request_path从未被选中,因为我认为NginX算法在多个匹配URI时选择了第一个匹配的正则表达式。

我想我在这里错过了一些关于嵌套位置指令的东西...

有任何线索吗?

1 个答案:

答案 0 :(得分:0)

我自己找到了解决方案。我正朝着错误的方向挖掘。问题不是来自嵌套的位置指令,而是来自 try_files

原因在于我的调查日志:

2017/07/11 19:31:00 [debug] 13707#0: *8961 internal redirect: "/app.php?"

NginX正在将URI重写为“/app.php?”而不是“/app.php/post_request_path”

因而是“错误的”位置指令路线。

<强>校正

变化:

  

try_files $ uri /app.php$is_args$args;

  

try_files $ uri /app.php$uri;