nginx redirects 302 instead of rewrite 200 - php

If a user requests any .php file on my webserver I want his request (e.g. he requested mysite.com/testfile.php) to be handled by index.php
In index.php I use $_SERVER['REQUEST_URI'] to see which page the user wants to see (e.g. /testfile.php), so the index.php can generate the appropriate html-code. Notice that testfile.php doesn't need to exist.
My problem is that I always get a redirect 302 to / when I try to request testfile.php (as a result $_SERVER['REQUEST_URI'] is /). But what I want is a 200 OK for testfile.php and that index.php generates the right html-code for this.
This is a snippet from my buggy nginx.conf:
server {
[...]
root /home/test;
# When I go to mysite.com redirect my to mysite.com/
location = / {
index index.php;
}
# For any php file request: let index.php handle the request
location ~ \.(php)$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /home/test/index.php;
}
}
Anyone can help me out?
Thanks.

If the files never exist you can do this:
try_files $uri $uri/ /index.php
you can also rewrite the request like this:
location / {
rewrite ^.*$ /index.php last;
}
in both cases you should be able to read the original request with PATH_INFO or REQUEST_URI.
Have a look at these links for some more suggestions: http://drupal.org/node/110224, http://michaelshadle.com/2010/08/20/front-controller-patterns-and-nginx/, Zend Framework on nginx

Related

Return content based on REQUEST_URI by PHP

Say, My domain is 'www.miraj.com'. If users click on the link 'www.miraj.com/childhood-of-miraj' then I want to check my database if there is any post having the title 'childhood-of-miraj' it should be shown otherwise 404 page will be shown. But since there is no directory(folder) named 'childhood-of-miraj' it immediately returns 404 page. How can I do that?
This depends on the httpd you are using (Apache or Nginx).
For Apache, you should edit your .htaccess file to look like this:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^([A-Za-z-]+)/?$ FileToHandleDatabaseSearch.php?title=$1 [NC,L]
This will transform the URL on fly www.miraj.com/childhood-of-miraj to www.miraj.com/FileToHandleDatabaseSearch.php?childhood-of-miraj on the server, not in browser address bar.
FileToHandleDatabaseSearch.php
if (isset($_GET['title'])) {
//...Search DB for $title
//If title exists display page with title
//If title does not exist display 404 page not found
}
For NGINX you edit that in the conf file
www.miraj.com.conf in /etc/nginx/sites-available should look like this
server {
listen 80;
listen [::]:80;
root /path/to/project/root;
server_name www.miraj.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
rewrite ^([A-Za-z-]+)/?$ FileToHandleDatabaseSearch.php?title=$1 last;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
}
You would want to prefix the paths to be object-specific to avoid URL conflicts. For example if childhood-of-miraj is a movie title let the rewrite conditions be rewrite ^/movies/([A-Za-z-]+)/?$ "/path/to/project/root/FileToHandleDatabaseSearch.php?title=$1" last;
You can visit Apache Rewrite Rules for more .htaccess rules you can employ and Nginx Rewrite Rules for more Nginx rules you can employ.

Nginx how to return 404 when access index.php directly

For security purpose, I am attempting to hide almost all the fingerprint info of my web application. The most important thing is to hide PHP from any visitors. So I try to modify my Nginx's configuration file. The configuration will show as follows.
location / {
root /data/site/public;
index index.html index.htm index.php;
try_files $uri /index.php;
location /index.php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi.conf;
}
}
By this way, I successfully hide index.php from URL. However, Hackers could also directly access my website by using some URL such as http://example.com/index.php, which shows that my website is written by PHP. Sometimes it maybe dangerous.
So, I modify the Nginx's config second time, longing for 404 when access index.php directly, and it looks like
location / {
root /data/site/public;
if ( $request_uri ~ /index\.php ) {
return 404;
}
index index.html index.htm index.php;
try_files $uri /index.php;
location /index.php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi.conf;
}
}
However..., it seems that Nginx acts nothing different from the previous one.
Could anyone tell me the reason ? or any other solutions...

nginx redirect loop, remove index.php from url

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.

PHP not processing in Nginx

I have created a try_files directive that tries files in a different directory than the files are put in. I.e., if I visit www.example.com/home/main it will try the file /var/www/main/home/main.php. It works, but when I visit a page, it only shows the PHP source code and not the processed page. Here is my directive:
location ~ /home/ {
index main.php
try_files /main$uri.php #404;
location \.php {
fastcgi_pass php_server;
include fastcgi_params;
}
}
Any ideas on how I can get the page to process instead of just showing the PHP source?
Edit for additional information: I have tried making a location directive that looks like
location ~ /main/(.*)\.php {
fastcgi_pass php_server;
include fastcgi_params;
}
but this doesn't work either and the pages still show just the source code.
Of course it will show you source, since you don't have fastcgi_pass in your /home/ location.
Try this one:
location /home/ {
try_files /main$uri.php #static;
fastcgi_pass php_server;
include fastcgi_params;
}
location #static { }
EDIT: Actually the below is wrong - the last parameter is always used as a redirect if the file can't be found anywhere else in the try_files directive. In this example, it is hitting the .php file, but not be processed, so the #404 wasn't being hit. However, if no #404 example exists, then a failure to find the file would blow up anyways.
In the event that no file is found, an internal redirect to the last parameter is invoked [...]The last parameter is the fallback URI and must exist, or else an internal error will be raised.
source: http://wiki.nginx.org/HttpCoreModule#try_files
The #404 at the end of your try_files directive will send the php file to be parsed by a location #404 directive, not your php directive that uses fastcgi.
Try dropping the #404 or simple doing: try_files $uri /main$uri.php;

Issues converting .htaccess to Nginx configuration for PHP scripts

I have an .htaccess file that I'm trying to convert so it can be run on my Nginx server.
I'm having two primary problems:
1. I'm not sure how to convert some lines
2. I don't know where to put the Nginx configuration code
Here are the lines I'm having issues converting:
Options All -Indexes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page_request=$1 [QSA,L]
I've tried some online converters, but they don't seem to be working.
Also, once I've converted the lines, where do I put them? I assume I need to place them in the mysite.conf file in /etc/nginx/sites-available/, but within that file, do I just put them within the server {} block?
Thanks a lot for any help you can give me.
Edit: Here's the conf file
server {
listen 0.0.0.0:80;
server_name www.subdomain.domain.tld subdomain.domain.tld;
access_log /var/log/subdomain.domain.tld.log;
location / {
root /srv/www/subdomain.domain.tld/public_html;
index index.html index.php;
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /srv/www/subdomain.domain.tld/public_html$fastcgi_script_name;
}
try_files $uri $uri/ /index.php?page_request=$uri;
}
UPDATE
Doing some nginx research, came across this, give this a shot and see if it works as you expect:
location / {
# other code below this line
try_files $uri $uri/ /index.php?page_request=$uri;
}
Basically the try_files is the if statement, it tries the regular file first, if it cannot find it, it tries it as a directory, if it cannot find that it sends it to the last argument.
OLD
Have you tried using a service like: http://www.anilcetin.com/convert-apache-htaccess-to-nginx/
It outputs:
#ignored: condition 0
#ignored: condition 1
if ($rule_0 = "2"){
rewrite /RewriteRule ^/(.*)$;
}
For the data you provided.
Where you put them is inside the:
server {
}
Since this is not for a specific location you would just put it after the default stuff. There is order of operations to be had, so yea. It can be inside of a location, if you have more than one location type bit. For nginx, I would probably put this under the .php location definition.

Categories