Nginx client_max_body_size per location block (with php frontcontroller pattern)
Solution 1
If /admin/upload
path is virtual, it is possible to make it work as follows:
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;
}
Not the prettiest too, but works.
Solution 2
Define two php locations?
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;
}
Perhaps not the prettiest... Should be functional though..
Solution 3
Using multiple locations is possible, but is a bit tricky.
If you use try_files
or rewrite
as explained above, then the client_max_body_size
would be set to the client_max_body_size
of the higher context, not really the one for the location block you'd expect it to.
Move your PHP FastCGI configuration into a file that you can include, such as php-conf.conf
.
Then use such a configuration:
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;
}
Note that you need to overwrite SCRIPT_FILENAME
to use index.php
if you have a different script name set. This could happen because of fastcgi_split_path_info ^(.+\.php)(/.*)$;
.
Jurian Sluiman
Updated on September 18, 2022Comments
-
Jurian Sluiman almost 2 years
I am looking for a solution for this problem. I understand the reasoning why the setup in that question does not work, but I try to get to a solution where I can get it working.
The idea is to allow large file uploads only on certain urls. I can use a
location
block for this, but the problem is: I have a php frontcontroller pattern:location ~ \.php { # ... fastcgi_pass unix:/tmp/php5-fpm.sock; }
My total config looks like:
# ... 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; } } }
As I understand, only one location block will be applied. So if I have a default request size of 512K, the 256M will never be applied since all requests are matched through the frontcontroller pattern
~ \.php
.Am I right in this case and if so, what can be configured such that visitors cannot upload anything except when they upload to
admin/upload
?