每个位置块的 Nginx client_max_body_size(使用 php frontcontroller 模式)

每个位置块的 Nginx client_max_body_size(使用 php frontcontroller 模式)

我正在寻找解决方案这个问题。我理解为什么该问题中的设置不起作用的原因,但我尝试找到一个可以使其起作用的解决方案。

这个想法是只允许在某些 URL 上上传大文件。我可以使用一个location块来实现这一点,但问题是:我有一个 php 前端控制器模式:

location ~ \.php {
    # ...
    fastcgi_pass unix:/tmp/php5-fpm.sock;
}

我的整体配置如下:

# ...

http {
    # ...

    client_max_body_size 512K;

    server {
        server_name example.com;
        root        /var/www/example.com/public;

        location / { 
            try_files $uri /index.php?$query_string;
        }

        location /admin/upload {
            client_max_body_size 256M;
        }

        location ~ \.php {
            # ...

            fastcgi_pass unix:/tmp/php5-fpm.sock;
        }
    }
}

据我了解,只会应用一个位置块。因此,如果我的默认请求大小为 512K,则永远不会应用 256M,因为所有请求都通过 frontcontroller 模式进行匹配~ \.php

在这种情况下我是对的吗?如果是这样,那么如何配置才能使得访问者除了上传到之外不能上传任何内容admin/upload

答案1

如果/admin/upload路径是虚拟的,则可以使其按如下方式工作:

location / {
    try_files $uri /index.php?$args;
}

location /admin/upload {
    client_max_body_size 256M;

    include inc/php.conf;
    rewrite ^(.*)$ /index.php?$args break;
}

location ~ \.php$ {
    include inc/php.conf;
}

虽然不是最漂亮的,但是还是有用。

答案2

定义两个 php 位置?

location ~ ^/admin/upload/.+\.php$
{
    client_max_body_size 256M;
    include /etc/nginx/conf.d/php-fpm.conf;
}   
location ~ \.php
{
    include /etc/nginx/conf.d/php-fpm.conf;
}

也许不是最漂亮的...但应该是实用的......

答案3

可以使用多个位置,但有点棘手。

如果您按照上述说明使用try_filesrewrite,那么将client_max_body_size被设置为client_max_body_size更高上下文的,而不是您真正期望的位置块的。

将您的 PHP FastCGI 配置移动到您可以包含的文件中,例如php-conf.conf

然后使用这样的配置:

    location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$query_string;
    }

    location ~ ^/admin/upload$ {
        client_max_body_size 4m;
        include /etc/nginx/php-conf.conf;
        fastcgi_param SCRIPT_FILENAME $realpath_root/index.php;
    }

    location ~ ^/index\.php(/|$) {
        include /etc/nginx/php-conf.conf;
        internal;
    }

请注意,如果您设置了不同的脚本名称,则需要覆盖SCRIPT_FILENAME才能使用index.php。这可能是因为fastcgi_split_path_info ^(.+\.php)(/.*)$;

相关内容