Nginx redirect with/without php extension - php

I am building an NGINX virtual host that should:
redirect pages ending with .php to the version without extension (301 redirect)
properly handle URLs not ending with .php by passing them to FASTCGI for php execution
My issue is that this will in effect create an infinite redirect loop. What am I missing here?
server {
server_name ~^my\.domain\.com$;
listen 80;
root /path/to/root;
error_page 404 /404.php;
location ~ \.php$ {
rewrite ^(.*)\.php$ $1 permanent;
break;
}
location / {
index index.php;
try_files $uri $uri/ #extensionless-php;
}
location #extensionless-php {
rewrite ^(.*)$ $1.php last;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# rest of fastcgi configuration...
}
}

For a start, you cannot have two location ~ \.php$ blocks. The solution is to process the fastcgi_pass within the named location itself and avoid the internal rewrite to .php. Something like this:
location / {
try_files $uri #php;
}
location #php {
try_files $uri.php $uri/index.php =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass ...;
}
location ~* ^(.*)\.php$ {
return 301 $1;
}
Notice that the index directive and the $uri/ elements are no longer required.

Related

How can I make this php redirect not be conflicted by Nginx

My php file 404.php contains a php redirect at the top of the file:
<?php
header('Location: some-page.html');
If I go to www.mysite.com/404, it redirects to www.mysite.com/some-page.html as expected, however, if I go to www.mysite.com/non-existent-page, the redirect does not work.
In my nginx.conf:
location ~* \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
error_page 404 =200 /404.php;
try_files $uri #remExt;
location #remExt {
rewrite ^(.*)$ $1.php last;
}
if ($request_uri ~ ^/([^?]*)\.php($|\?)) {
return 301 /$1$is_args$args;
}
rewrite ^/index$ / permanent;
rewrite ^/(.*)/$ /$1 permanent;
How can I make the php redirect work when visiting www.mysite.com/non-existent-page?
PS
Sorry for the badly written question title. The clear and better written question title I wanted to use was automatically rejected.
Try this in your nginx config and restart it.
error_page 404 /404.php;
location = /404.php {
root /path/to/www/;
internal;
}
/404.php
<?php
http_response_code(301);
header('Location: /the/page/you/want');
nginx.conf
error_page 404 /404.php
location / {
try_files $uri $uri.php $uri/ =404;
}
then check syntax with nginx -t and reload nginx with systemctl reload nginx(if you're using systemd)
http://php.net/manual/en/function.http-response-code.php
It appears I have solved the problem, although there may be some edge cases where my Nginx code fails.
The problem was with this line error_page 404 =200 /404.php;. The solution is to use try_files inside location ~* \.php$.
index index.php;
location ~* \.php$ {
try_files $uri $uri/ /404.php$is_args$args;
fastcgi_pass unix:/var/run/php-fpm/php-fpm-root.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location / {
try_files $uri $uri/ $uri.php$is_args$query_string;
}
if ($request_uri ~ ^/([^?]*)\.php($|\?)) {
return 301 /$1$is_args$args;
}
rewrite ^/index$ / permanent;
rewrite ^/(.*)/$ /$1 permanent;

Nginx with wordpress 404 on all pages

Although this issue has been answered many times but still its not working for me.
I am getting 404 on all pages except home page on Nginx.
I am posting in my configuration below:
server {
listen 80 ;
listen [::]:80;
root /var/www/html/p/swear;
index index.php index.html index.htm;
server_name skinnybikiniswimwear.org;
location / {
try_files $uri /$uri/ /index.php?args =404;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
try_files $uri /index.php?args =404;
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
I am not able to find the issue in this configuration.
Wordpress is installed at: /var/www/html/p/swear
Thanks
Try this :
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$is_args$args =404;
}
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
Having had a lot of failures configuring wordpress to work with nginx, the rewrite rule solves every issue with the 404 errors.
try removing slash in front of /$uri/
location / {
try_files $uri $uri/ /index.php?$args ;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass php;
}
Images does not because you dont have nothing in your server block about images. You have to add the images into your server block.
For example:
location ~* ^.+\.(jpe?g|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mp3)$ {
root /home/example/public_html
}

Returns 404 if =404 is in try_files

Webpage always returns 404 if the =404 is in the try_files
Webserver is Nginx
I can access www.mydomain.com/admin/ just fine (contains a index.php)
if I go to www.mydomain.com/player/players/ it doesn't work (players is players.php) and there are no index files in player.
Removing =404 from the first try_files makes everything work as if there isn't anything wrong but then etc www.mydomain.com/filethatdoesentexist/ returns "no input file"
My code
location / {
try_files $uri $uri/ $uri.html #rewrite =404;
}
location #rewrite {
rewrite ^ $uri.php last;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+?\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
include fastcgi.conf;
}
rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
location /admin/ {
try_files $uri $uri/ $uri.html #rewrite;
}

Nested Laravel Project Nginx Config

We are introducing a new section on our website which uses the Laravel framework. It is placed in a sub-directory, for example /newsection. How should I configure the nginx.conf without making any conflicts with my previous rewrite rules.
This is my current nginx.conf
server {
listen 80;
server_name localhost www.website.com;
root /home/www/website;
index index.html index.php;
location /newsection/ {
rewrite ^/ /newsection/public/index.php last;
# this is my attempt at it
}
location / {
try_files $uri $uri/ #rewrite;
}
location /php-status {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
location #rewrite {
rewrite ^/([\w_-]+)/?$ /index.php?page=$1 last;
rewrite ^/([\w_-]+)/([\w_-]+)/?$ /index.php?page=$1&slug=$2 last;
rewrite ^/([\w_-]+)/([\w_-]+)/([\w_-]+)/?$ /index.php?page=$1&slug=$2&pagination=$3 last;
}
include php.conf;
}
If it works like most frameworks I know work, this should work
location /newsection/ {
try_files $uri $uri/ /newsection/public/index.php$request_uri;
}
If this returns 404 try removing the extra /newsection in the fallback URI of the try_files
Try this for laravelin subdirectories
location ^~ /laravel {
alias /var/www/laravel/public;
try_files $uri $uri/ #laravel;
location ~ \.php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(.*)$;
include /etc/nginx/fastcgi_params;
}
}
location #laravel {
rewrite /laravel/(.*)$ /laravel/index.php?/$1 last;
}

Nginx rewrite rule for CodeIgniter

Here is the rule in English:
Any HTTP request other than those for index.php, assets folder, files folder and robots.txt is treated as a request for your index.php file.
I have an .htaccess file that works correctly on Apache server:
RewriteCond $1 !^(index\.php|assets|files|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
Some correct results for this rule:
example.com = example.com/index.php
example.com/index.php/welcome = example.com/welcome
example.com/assets/css/main.css != example.com/index.php/assets/css/main.css
I tried some tools to convert from htaccess rule to nginx rule but all were incorrect.
Via http://winginx.com/htaccess (missing the exception rules for assets folder...):
location / { rewrite ^(.*)$ /index.php/$1 break; }
Via http://www.anilcetin.com/convert-apache-htaccess-to-nginx/ (error in $1 value):
if ($1 !~ "^(index.php|assets|files|robots.txt)"){
set $rule_0 1$rule_0;
}
if ($rule_0 = "1"){
rewrite ^/(.*)$ /index.php/$1 last;
}
How can I fix this? It's really hard to debug the rule.
Here is my nginx config so far:
server {
listen 80;
server_name www.example.com example.com;
location / {
try_files $uri $uri/ /index.php?/$request_uri;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
You can add this to your config:
location ~* ^/(assets|files|robots\.txt) { }
This will work correctly with your location / rule.
Your config also need to add root document and default index file.
...
root /ftp/wardrobe;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?/$request_uri;
}
location ~* ^/(assets|files|robots\.txt) { }
...
You want to do this instead:
if ($request_uri !~ ^/(index\.php|assets|files|robots\.txt)) {
rewrite ^/(.*)$ /index.php/$1 last;
}
$request_uri is for the original URI request by the client. If you want the URI request AFTER other Nginx rewrite rules have processed it then you would use $uri. However, for what you are trying to do the prior would be the one you would want.
Also, you need to escape special regular expression characters like . by using a backslash.
Please try this. It works for me.
server {
server_name domain.tld;
root /var/www/codeignitor;
index index.html index.php;
# set expiration of assets to MAX for caching
location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
expires max;
log_not_found off;
}
location / {
# Check if a file or directory index file exists, else route it to index.php.
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

Categories