Reputation: 441
I have a redirect (add trailing slash if there's not one) in nginx that I only want to run on GET requests in order to maintain POSTed data. Checking the if is evil article it seems like this setup is OK?:
location / {
if ($request_method = GET) {
rewrite ^([^.]*[^/])$ $1/ permanent;
}
try_files $uri $uri/ /index.php?$query_string;
}
However this rule appears to get me a 404 error on every request, before actually loading the content (because my 404 handler also goes through index.php I guess?). This is a Craft CMS site.
This doesn't seem to be an issue with the redirection part, this works fine (if I have no slash it redirects) it's when a trailing slash is hit that the 404 happens, so I presume it's something with the try_files
part that's wrong somehow? However, weirdly, if I comment out the whole if statement (so it just runs the try_files) I don't get the 404.
If it helps here are the rest of the location blocks etc. in the config (these all follow the location /
block shown above)
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/mysite.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* \.(css|js|gif|png|ico|svg)$ {
try_files $uri $uri/ /index.php?p=$uri&$args;
expires 7d;
}
location ~* \.(jpg|jpeg)$ {
expires 7d;
}
location ~ /\.ht {
deny all;
}
location ~ /\.(?!well-known).* {
deny all;
}
Upvotes: 2
Views: 3847
Reputation: 49692
The problem is that the if
context processes all of the GET requests.
Assuming that the POST requests should be handled by /index.php
, you could use the if
block to handle all POST requests instead.
For example:
location / {
if ($request_method = POST) {
rewrite ^ /index.php last;
}
rewrite ^([^.]*[^/])$ $1/ permanent;
try_files $uri $uri/ /index.php?$query_string;
}
Upvotes: 1