Location blocks in nginx not getting desired outcome - maybe ordering? - nginx

I've got a website using nginx that's got a load of redirects to retain the juice and UI that old backlinks give me but they're not all working as I need them to. I suspect it could be an ordering issue but I'm not sure so I'd appreciate some help.
I'm pretty sure I'm almost there but I can't work out a way for it all to work together!
location / {
try_files $uri $uri/ #extensionless-php;
}
location #redirector {
rewrite ^(.*)$ /redirection-check/?request=$request_uri;
}
location #extensionless-php {
rewrite ^(.*?)/?$ $1.php;
}
location ~ ^([^.\?]*[^/])$ {
try_files $uri #addslash;
}
location #addslash {
return 301 $uri/;
}
location ~ \.php$ {
try_files $uri $uri/ #redirector;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php5.6-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
The way it should work is...
If someone lands on domain.com/page or domain.com/page.php then 301 to domain.com/page/
Interpret domain.com/page/ as domain.com/page.php
If domain.com/page.php doesn't exist then go to domain.com/redirection-check/?request=the404request. This is a 301/404 handler with a BUNCH of old urls in a big php array so they're not all listed in nginx config files.

You have a location ~ \.php$ block to process URIs that end with .php. This will handle both internally rewritten URIs (as generated by your #extensionless-php block) and externally presented URIs (such as in your 1st requirement).
To handle externally presented URIs differently, you need to look at the original request which is available as $request_uri.
The $request_uri contains the original request including the optional query string, and can be tested using a map or if directive.
For example:
if ($request_uri ~ ^(.*)\.php(\?|$)) { return 301 $1/; }
See this caution on the use of if.

Related

Problem configuring nginx to run wordpress from subdirectory but without subdirectory name in url

I'm pretty new to nginx.
I have two types of code one is simple php running through, index2.php and I have one directory named wordpress inside it has a whole wordpress website.
What I'm trying to achieve is to get them both running on the main domain without slashes with subdirectory names.
location ~ (/lottery-results|patternTwo) {
try_files $uri /index2.php$is_args$args;
}
location / {
try_files $uri /wordpress/index.php?$args;
}
This is the config I am currently using it works fine for my purpose.
The first directive loads some urls through simple php in index2.php.
The second directive loads wordpress, however when I open this url:
http://domain.test/
It send me to:
http://domain.test/wordpress/wp-admin/setup-config.php
My problem is that /wordpress part I want the url to be:
http://domain.test/wp-admin/setup-config.php
instead.
I tried to use alias and root but it didn't change anything, (honestly I don't get what alias and root even does!)
edit : PHP-FPM handler:
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/Applications/MAMP/Library/logs/fastcgi/nginxFastCGI_phpMAMP_PhpLocalhost_MAMP.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /Applications/MAMP/conf/nginx/fastcgi_params;
}
Lets try this:
# This block should be OUTSIDE the server block!
map $request_uri $new_uri {
~^/wordpress(/.*) $1;
default $request_uri;
}
server {
...
location ~ (/lottery-results|patternTwo) {
try_files $uri /index2.php$is_args$args;
}
location / {
try_files $uri /wordpress$uri /wordpress/index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
# Here the order of directives DOES matter
# This should be the first:
include /Applications/MAMP/conf/nginx/fastcgi_params;
# This should be the second:
fastcgi_param REQUEST_URI $new_uri;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/Applications/MAMP/Library/logs/fastcgi/nginxFastCGI_phpMAMP_PhpLocalhost_MAMP.sock;
}
}

Nginx rewrite rule (with try_files?) filename.php?text=$args (to) foldername/?text=$args

How can I rewrite rule in nginx for the case, when I send parameters with this request example.com/index.php?text=s1&sort=s2, but I want nginx to process it as example.com/process/?text=s1&sort=s2 ?
"s1" and "s2" is something that you type in search form.
I've already tried this:
rewrite ^/index.php?text=(.*)$ /process/?text=$1 last;
And this:
location ~* /index.php?text=(.*)$ {
try_files $uri /search/?text=$1;
#try_files $uri /search/?text=$is_args$args;
}
And this..
location =index.php?text=$1&sort=$2 {
rewrite index.php?text=$1&sort=$2 /process/text=$1&sort=$2;
}
But it somehow doesn't work.
This is main part of my config:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.php$ {
include /etc/nginx/php_params;
include /etc/nginx/fastcgi_params;
}
I'm so confused.. :/
Anything after the ? is part of the query string and individual values can be accessed with variable names beginning with the arg_ prefix.
A simple rewrite of all /index.php could be defined using:
location = /index.php {
rewrite ^ /process/?text=$arg_q&sort=$arg_sort? last;
}
The final ? prevents rewrite from appending the old query string on to the end of the new URI.
If you wish to single out only those URIs that contain an $arg_q parameter, you will need to use an evil if inside the PHP location block. Like this:
location ~* \.php$ {
if ($arg_q) {
rewrite ^/index.php$ /process/?text=$arg_q&sort=$arg_sort? last;
}
...
}
EDIT:
1) In your case, the URI is mostly handled by /index.php, but the value of $request_uri (the original value of the request) is used to route it within /index.php. The value of $request_uri is difficult to modify without performing an external redirect.
2) When /index.php is presented as the original request, you would like it to be routed to /search/. The current value of $request_uri begins with /index.php which is unhelpful.
The solution is to identify unhelpful values of $request_uri and perform an external redirect to modify the value of $request_uri. Something like this:
if ($request_uri ~ ^/index.php) {
return 302 /search/?$args;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.php$ {
...
}
If the query string is identical, just use $args (or $query_string) to append it. Otherwise break it into individual arguments as in my original answer.
Not wishing to edit an accepted answer - I would like to offer an alternative solution that I have tested:
root ...;
location / {
try_files $uri $uri/ #index;
}
location #index {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param REQUEST_URI $uri;
fastcgi_pass php5-fpm-sock;
}
location ~* \.php$ {
if ($arg_text) {
rewrite ^/index.php$ /search/ last;
}
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php5-fpm-sock;
}
This version avoids the immutable $request_uri by using $uri within a named location. Also the earlier redirect loop is avoided by using the named location for index.php.

Nginx remove php extension and index from url

Hope someone can help me.
be aware; sorry for possible bad english ;)
I'm trying for hours to setup my configs so my site is accessible without php extension, but will redirect any request with extension and in addition remove the /index from URL.
i have come to the point where every extension will removed and still got parsed by php5-fpm.
here is my current code:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.php;
<<unrelated Modulecode>>
rewrite ^(.*).php(.*)$ $1$2 permanent; # << forces index to be appended, so not exactly wanted
#rewrite ^/index$ / permanent; >> results in infinity loop for indexpage
# location ~ ^(.*)(?<!(index)).php(.*)$ { # << even don't know how to at least except index...gwarz regex x|
# rewrite ^(.*).php(.*)$ $1$2 permanent;
# }
location / {
try_files $uri $uri/ #phprule;
}
location ~ \.php$ {
try_files $uri $uri/ 404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location #phprule {
rewrite ^(.*)$ $1.php last;
}
}
the uncommented parts are some desperate trys to get it somehow to work x<
so what i want to accomplish:
example.com/index.php => example.com/
example.com/foo.php => example.com/foo
example.com/some/path/foo.php => example.com/some/path/foo
hope you will get the idea.
Probably found the issue or moved on, but for the benefit of those who come along after, these little changes did the trick for me:
location #phprule {
rewrite ^/(.*)$ "/$1.php" last;
}
/ added to the regex, quotes and a forward slash added to the rewrite string.

nginx location block matching order query

I have the following in my conf file:
server {
listen 80;
server_name a.mydomain.com;
location /f/ {
alias /var/www/sites/mydomain/photos/;
expires 1y;
}
location ~ \.(php|html)$ {
include php.conf;
}
location / {
return 301 http://www.mydomain.com$request_uri;
}
}
Where php.conf is
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "include_path=.:/usr/share/pear:/var/www/sites/mydomain/conf";
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
What puzzles me, is that my final location ("location /") block, does exactly what I want it to. Any request other than those starting with /f/ get redirect to the parent www domain.
Which is great, it's what I want.
But, the documentation states otherwise. It says that the regex php block I have should match before (and take precedence) over the final "/" block?
Doesn't it?
"The order in which location directives are checked is as follows:
Directives with the = prefix that match the query exactly (literal string). If found, searching stops.
All remaining directives with conventional strings. If this match used the ^~ prefix, searching stops.
Regular expressions, in the order they are defined in the configuration file.
If #3 yielded a match, that result is used. Otherwise, the match from #2 is used."

uri mapping - '/index.php/dashboard' in nginx

In Apache, I can access php scripts through an uri like /index.php/dashboard,
how can I set nginx to act the same?
Also I can access /index with Apache and it automatically maps to /index.php.
Is this also possible in nginx?
I think something like this is the solution:
map $uri $myvalue {
/index.php/(.*) /index.php?$;
}
Or is there a solution w/o rewrite?
My actual config is this:
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
I don't know if you pass the URI as a query string or what, but if that's the case here's what you could try
location ~ /index.php(.*) {
try_files /index.php?$1 =404;
}

Resources