Nginx 405’s with try_files for a DELETE request instead of proxying

nginx

I have nginx proxying to php-fpm with the following config:

location / {
  try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
  fastcgi_pass   127.0.0.1:9000;
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME /vol/app/www/$fastcgi_script_name;
  include        fastcgi_params;
}

“`

Everything is working great until a DELETE request comes in like:

DELETE /?file&path=foo

When this happens nginx returns a 405 (method not allowed) and doesn't appear to proxy the request to php-fpm. What's the best way to get DELETE/PUT requests to proxy? Is there way to bypass try_files for this type of request?

When hitting this URL, I see nothing in the error.log but access.log shows:


68.50.105.169 - - [20/Mar/2016:17:48:57 +0000] "DELETE /?file=client_img1.png&fileupload=e35485990e HTTP/1.1" 405 574 "http://ec2-foo.compute.amazonaws.com/jobs/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36" "-"

I've confirmed that I'm not hitting the proxy. My assumption is that nginx is blocking DELETE on the first "try" of try_files

Best Answer

I just got bitten by a similar scenario with exactly same symptoms. The issue is the request being matched by the folder index before it is matched by the try_files index.php. When you have your try_files looking like this:

try_files $uri $uri/ /index.php?$args; 

If you request any folder you will get $uri/ matched before /index.php?$args get's matched and if there is an index directive with index.php set like ie

index  index.html index.htm index.php;

with index.php in it, php is reached through the index. So when you try to do a delete or put request nginx sees that you are actually trying to perform that request on the folder index. This results in 405 Not Allowed responses.

It is very likely that if you are getting a 405 response in a place where other methods work it's that the folder index is matched before the php file in try_files. One way to be sure about that being the case is to turn autoindex off and see if a GET request still works.