I want to make a Nginx rewrite rule for parameters pretending to be top-level directories. For instance, I want example.org/myval to be redirected to example.org/foo.php?param=myval, but at the top level I already have some other files (like index.php) I would like to be reachable.
My attempt is:
location = ^/(?!.*)$ {
rewrite ^/$ https://example.org/index.php break;
}
location = ^/(.*) {
rewrite /(.*) /foo.php?param=$1 last;
}
the 1st rule catching only root, the second trying to catch pretending top-levels (but failing),so all I get when accessing non-(something.php) files is a 404. Any ideas?
EDIT:
Later I have the PHP block:
location ~ ^/(index|signup|login|).php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
which I've come to know contains the try_files part (but shouldn't match anything else); I don't know where does the 404 come from.
Related
I'm trying to do the following:
There is a site where you can find a user in the format http://localhost/username . I tried to make a rule that if there is no file on the server, then it will redirect to index.php?username=username. But the problem is that it redirects everything, even js and css. I want to do it like this, if the file was on the server, then it would access it, and if not, then it would make a request
index.php?username=username
There is this piece of code:
rewrite ^/(.+)$ /index.php?type=userinfo&username=$1 last;
Use try_files to determine if the file already exists, and branch to a named location containing your rewrite rule, if it does not.
For example:
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^/(.+)$ /index.php?type=userinfo&username=$1 last;
}
so this one is a weird one! I have these nginx stanzas. I used an online tool to convert .htaccess rules into nginx capable ones.
location / {
rewrite ^/(([^/]+/)*)login/$ /login.php?path=$1&$query_string break;
rewrite ^/(([^/]+/)*)comment/$ /comment.php?path=$1&$query_string break;
rewrite "^/([^/]+/){4}$" /asset.php break;
rewrite ^/(\d\w+)/$ /public.php?ticket=$1 break;
rewrite "^/(\d\w+)/([^/]+/){2}?$" /public-asset.php?ticket=$1 break;
if (!-e $request_filename){
rewrite ^/(([^/]+/)*) /index.php?path=$1&$query_string break;
}
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/vh1-fpm.sock;
include fastcgi_params;
}
going to https://example.test/ ok
going to https://example.test/login/ all heck break loose and PHP code is flooded onto the screen.
The regex routing works because the redirects take place. but once the redirect it done, it's like the masked .php file is not caught. All this is fixed if I encapsulate the PHP checks within the / location block.
You cannot use rewrite ... break when the rewritten URI is to be processed in a different location block.
Use: rewrite...last
Also, there is no need to tack &$query_string on the end of the rewritten URI, as rewrite will do it anyway unless the rewritten URI ends with a ?.
See this document for details.
I've created a simple php file to display info fetched from my MYSQL database. Right after that i use a rewrite rule in Nginx to make the link seo friendly and to mask the .php file that fetches it.
Ex: http://localhost/myfile.php?seo=how-to-install-linux
After rewrite rule the i can access it like:
http://localhost/how-to-install-linux
My rewrite rules are:
location / {
rewrite ^/([a-zA-Z0-9_$\-]+)$ /myfile.php?seo=$1 last;
rewrite ^/(.*)/$ /$1 permanent; <- just to block trailing slash
}
My problem is that i also want to block any direct access to my php file and i want only the seo friendly url to work.
location = /myfile.php {
deny all;
}
This rule blocks complete access to my php file, including through seo friendy url.
Is there a way to make it work for the seo friendly version using NGINX?
My other settings are:
location ~ \.php$ {
try_files $uri =404;
include fcgi.conf;
fastcgi_pass unix:/var/run/ajenti-v-php7.0-fcgi-drnou-php7.0-fcgi-0.sock;
}
I only use Nginx, no Apache installed.
You can use the internal directive to prevent a location from being accessed directly. See this document for details.
For example:
location = /myfile.php {
internal;
include fcgi.conf;
fastcgi_pass unix:/var/run/ajenti-v-php7.0-fcgi-drnou-php7.0-fcgi-0.sock;
}
We have a custom PHP application that we wrote and runs on Apache with .htaccess files to handle the url rewrites. We are trying to convert it to work under NGINX with FPM under Plesk Onyx.
The application generates links like:
https://somedomain.com/mypage (same as index/mypage)
https://somedomain.com/index/sitemap
https://somedomain.com/blog/some-article-name
These URL's map to index.php files that take the request_uri and use it to render the page responses.
The structure of the application is nested as follows:
docroot (/)
./index.php //handler for the request in /
./blog/index.php //handler for any request to /blog
Each index.php expects to receive a ?path={request_uri} so that it can map the request to the controllers and actions.
I have tried multiple ways to get NGINX to do this using tryfiles and rewrite, but no luck. Using rewrite I can get / to work, but it wont render /mypage or /index/sitemap.
If I try to hit /index/sitemap it downloads the index.php instead of executing it, and if I try the blog the same thing happens. In fact the only path that works is /, all others just download the index.php file.
Here is my configuration as it is now, where am I going wrong?
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control “public”;
try_files $uri #fallback;
}
location / {
#index index.php index.html index.html;
rewrite ^/([^?]*) /index.php?path=$1 break;
rewrite ^blog/([^?]*) /blog/index.php?path=$1 break;
#try_files $uri #fallback;
}
Your configuration has multiple issues. I will ignore the first location block as it seems to have nothing to do with your question.
The first rewrite will always match, so the second rewrite will never be consulted. The second rewrite will never match anyway, as nginx URIs always begin with a /. The [^?] is meaningless, because rewrite uses a normalised URI which does not include the ? or query string. Using rewrite...break means that the rewritten URI is processed within the same location, which is an error as this location is not equipped to process PHP files. See this document for more.
A solution using try_files might look like this:
location / {
try_files $uri $uri/ /index.php?path=$uri&$args;
}
location /blog {
try_files $uri $uri/ /blog/index.php?path=$uri&$args;
}
location ~ \.php$ { ... }
See this document for more.
I want any requests like http://example.com/whatever/index.php, to do a 301 redirect to http://example.com/whatever/.
I tried adding:
rewrite ^(.*/)index.php$ $1 permanent;
location / {
index index.php;
}
The problem here, this rewrite gets run on the root url, which causes a infinite redirect loop.
Edit:
I need a general solution
http://example.com/ should serve the file webroot/index.php
http://example.com/index.php, should 301 redirect to http://example.com/
http://example.com/a/index.php should 301 redirect to http://example.com/a/
http://example.com/a/ should serve the index.php script at webroot/a/index.php
Basically, I never want to show "index.php" in the address bar. I have old backlinks that I need to redirect to the canonical url.
Great question, with the solution similar to another one I've answered on ServerFault recently, although it's much simpler here, and you know exactly what you need.
What you want here is to only perform the redirect when the user explicitly requests /index.php, but never redirect any of the internal requests that end up being served by the actual index.php script, as defined through the index directive.
This should do just that, avoiding the loops:
server {
index index.php;
if ($request_uri ~* "^(.*/)index\.php$") {
return 301 $1;
}
location / {
# ...
}
}
Try that
location ~ /*/index.php {
rewrite ^/(.*)/(.*) http://www.votre_domaine.com/$1 permanent;
}
location /index.php {
return 301 http://www.example.com/;
}
If you already have first line mentioned below in your Nginx configuration file you don't have rewrite it again.
index index.php index.html index.htm;
rewrite ^(/.).html(?.)?$ $1$2 permanent;
rewrite ^/(.*)/$ /$1 permanent;
try_files $uri/index.html $uri.html $uri/ $uri =404;
This will remove .html from the URL and additionally will also remove "index" from home page or index page. For example -
https://www.example.com/index will be changed to https://www.example.com
Try
location = /whatever/index.php {
return 301 $scheme://www.example.com/whatever/;
}
Another benefit from doing it this way is that nginx does a return faster than a rewrite.