I am trying to migrate my .htaccess rules to nginx. I have tried almost all the questions on SO & url rewriter as well but not getting success. In short i want to convert following dynamic urls:
from
[1] - https://vc.test/results.php?url=ngo-service
[2] - https://vc.test/jobs.php?d=17&t=oil-&-gas
[3] - https://vc.test/jobs.php?d=17
To
[1] - https://vc.test/ngo-service
[2] - https://vc.test/17/oil-&-gas
[3] - https://vc.test/17
Request help to sort out this issue.
My nginx effort
server {
listen 127.0.0.1:80;
listen 127.0.0.1:443 ssl http2;
ssl_certificate_key "d:/winnmp/conf/opensslCA/selfsigned/vc.test+4-key.pem";
ssl_certificate "d:/winnmp/conf/opensslCA/selfsigned/vc.test+4.pem";
server_name vc.test;
root "d:/winnmp/www/vc";
## Access Restrictions
allow 127.0.0.1;
deny all;
autoindex on;
location / {
index index.html index.htm index.php;
try_files $uri $uri.html $uri/ #extensionless-php;
if ($query_string ~* "fbclid="){
rewrite ^(.*)$ /$1? redirect;
break;
}
if ($query_string ~* "url="){
rewrite ^(.*)$ /%1? redirect;
rewrite ^/(.*)$ /results.php?url=$1 permanent;
break;
}
rewrite ^/([0-9]+)/(.*)?$ jobs.php?d=$1&t=$2 break;
rewrite ^/([0-9]+)?$ jobs.php?d=$1 break;
}
location #extensionless-php {
rewrite ^(.*)$ $1.php last;
}
location ~ \.php$ {
try_files $uri =404;
include nginx.fastcgi.conf;
include nginx.redis.conf;
fastcgi_pass php_farm;
fastcgi_hide_header X-Powered-By;
}
}
I don't know what your if ($query_string blocks are for, so I will ignore them.
Use rewrite...last if the rewritten URI is to be processed in a different location block, for example with URIs ending with .php. All Nginx URIs begin with a leading /, for example, use /jobs.php and not jobs.php.
You can place your list of rewrite statements in the location / block, and they will be evaluated in order until a match is found. If no match is found, the try_files statement will be evaluated. That's just how the rewrite module works!!
However, the 1st rewrite rule is too general and may break some of the URIs intended to be fulfilled by the try_files statement. A better solution may be to put all of the rewrite statements into the same named location block.
For example:
index index.html index.htm index.php;
location / {
try_files $uri $uri.html $uri/ #rewrite;
}
location #rewrite {
if (-f $document_root$uri.php) {
rewrite ^ $uri.php last;
}
rewrite ^/([0-9]+)/(.+)$ /jobs.php?d=$1&t=$2 last;
rewrite ^/([0-9]+)$ /jobs.php?d=$1 last;
rewrite ^/([^/]+)$ /results.php?url=$1 last;
return 404;
}
location ~ \.php$ {
try_files $uri =404;
...
}
See this caution on the use of if.
Related
On a server with Ubuntu 20.04 and nginx 1.18.0 using ISPConfig 3.2 I have the following configuration for my Wordpress website:
location /api {
rewrite ^(.*)$ $1.php last;
}
location ~* ^/index\.php$ {
break;
}
try_files $uri $uri/ /index.php$is_args$args;
location /user {
try_files $uri $uri/ /index.php$is_args$args;
rewrite ^/user/([^/]+)/([^/]+)/master?$ /index.php/master/?userid=$2 redirect;
rewrite ^/user/([^/]+)/([^/]+)/chief?$ /index.php/chief/?userid=$2 redirect;
rewrite ^/user/([^/]+)/([^/]+)?$ /user/?userid=$2 redirect;
}
The redirect for e.g. /user/john/123 to /user/?userid=123 is working as expected.
But I do not want a redirect but to keep the URL as it is and show the content of the internally rewritten URL. So I tried to change redirect to break or last but both changes are resulting in a 404.
...
location /user {
try_files $uri $uri/ /index.php$is_args$args;
rewrite ^/user/([^/]+)/([^/]+)/master?$ /index.php/master/?userid=$2 last;
rewrite ^/user/([^/]+)/([^/]+)/chief?$ /index.php/chief/?userid=$2 last;
rewrite ^/user/([^/]+)/([^/]+)?$ /user/?userid=$2 last;
}
Why is it working with the redirect but not without?
Edit
Another try:
location /api {
rewrite ^(.*)$ $1.php last;
}
location ~* ^/index\.php$ {
break;
}
try_files $uri $uri/ /index.php$is_args$args;
location /user {
try_files $uri $uri/ #userrules;
}
location #userrules {
rewrite ^/user/([^/]+)/([^/]+)/master?$ /index.php/master/?userid=$2 redirect;
rewrite ^/user/([^/]+)/([^/]+)/chief?$ /index.php/chief/?userid=$2 redirect;
rewrite ^/user/([^/]+)/([^/]+)?$ /index.php/user/?userid=$2 redirect;
rewrite ^/(.*)$ /index.php?$args last;
}
Same result - if I remove the redirect it results in a 404.
The resulting page e.g. /user/?userid=203 works but I would like to keep the readable URLs.
I want to do redirect from urls, real page exist here - mysite.com/folder/index.html :
mysite.com/folder/index.html to mysite.com/folder/
mysite.com/folder.html to mysite.com/folder/
mysite.com/index.html to mysite.com
This is part of my config
server_name k.my.net www.k.my.net;
index index.html;
root /var/www/demo/k.my.net/current/public;
rewrite ^(.*/)index\.html$ $1;
rewrite ^(/.+)\.html$ $1/;
location / {
try_files $uri $uri/ =404;
}
Also try do it with:
location / {
try_files $uri $uri/ #htmlext;
}
location ~ \.html$ {
try_files $uri =404;
}
location #htmlext {
rewrite ^(.*)$ $1.html permanent;
}
3-rd solution ERROR_LOOP
location ~* ^/([a-zA-Z1-9_-]*/)index\.html$ {
return 301 $1;
}
location ~* ^/([a-zA-Z1-9_-]*/?[1-9a-zA-Z_-]*)\.html$ {
return 301 /$1/;
}
location ~* ^/([a-zA-Z1-9_-]*/?[a-zA-Z1-9_-]*)/$ {
try_files /$1.html /$1/index.html =404;
}
You could use a regular expression location to extract the part of the URI before the trailing / and use try_files to test the two alternatives. See this document for details.
For example:
location ~ ^(.*)/$ {
try_files $1/index.html $1.html =404;
}
The location also matches / which will satisfy your third requirement.
Your rewrite statements should be safe, but if they cause redirection loops, you may need to replace them with an if block and test the original request in $request_uri. For example:
if ($request_uri ~ ^([^?]*?)(/index|)(\.html)(\?.*)?$) {
return 301 $1/$4;
}
I have no problems with redirect, but when I uncomment 2 lines that do "if folder doesn't exist" check, I get 404 error on any page. And I don't understand why, it's basic functionality.
I need to redirect all requests with trailing slash to urls without it. The only exception is when a folder with that url exists.
location / {
#if (!-d $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
#}
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?q=$request_uri;
}
You should read this caution on the use of if.
You could try an alternative approach and only rewrite after try_files has processed the URIs that it can:
location {
index index.php index.html index.htm;
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^/(.*)/$ /$1 permanent;
rewrite ^ /index.php?q=$request_uri last;
}
See this document for more.
When i click on a button using #jumpto it gives me a 404 error. I think it has something to do with the nginx config file because i am working on it.
How can I use #jump without giving me 404 error?
server {
listen 80;
server_name doutor.pt;
return 301 http://www.doutor.pt$request_uri;
}
server {
server_name doutor.pt www.doutor.pt;
access_log /var/log/nginx/doutor.pt.access.log;
error_log /var/log/nginx/doutor.pt.error.log;
root /var/www/doutor.pt/htdocs;
index index.php index.html;
location / {
try_files $uri $uri/ #rewrite;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
location #rewrite {
rewrite ^/sitemap-doctors-([0-9]+).xml$ /index.php?page_name=sitemap&category=doctors&page=$1 las$
rewrite ^/sitemap-doctors.xml$ /index.php?page_name=sitemap&category=doctors&page=0 last;
rewrite ^/sitemap.xml$ /index.php?page_name=sitemap last;
rewrite ^/category/([0-9]+)-([^/]+)$ /index.php?page_name=doctors&category=$1 last;
rewrite ^/medico/([^/]+)$ /index.php?page_name=medico&doctor_url=$1 last;
rewrite ^/([^/]+)/([^/]+)$ /index.php?page_name=$2&page_category=$2 last;
rewrite ^/([^/]+)$ /index.php?page_name=$1 last;
# some default action???
return 404;
}
I have some index.html files sitting in a folder to get some nice urls -
site.com/about
where index.html sits in the about folder. But I am seeing that my site.com/about is being 301 redirected to site.com/about/ I am not sure where the 301 is generated from. It is not in config.
/about/ also has a 301 result.
I guess it makes sense since I am redirecting to the index.html file but should it not be a rewrite? Is there a way to return 200 for /about instead of 301 to about/?
I am using nginx
Server Block:
server {
listen IP;
server_name site.com;
rewrite / $scheme://www.$host$request_uri permanent;
}
server {
listen IP:80;
server_name site.com *.site.com;
root /var/www/vhosts/site.com/htdocs;
charset utf-8;
rewrite_log on;
location / {
index index.html index.php;
try_files $uri $uri/ /$uri.php;
expires 30d;
}
if ($request_uri = /index.php) {
return 301 $scheme://$host;
}
if ($request_uri = /index) {
return 301 $scheme://$host;
}
location /. {
return 404;
}
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
include "ssl_offloading.inc";
location ~ .php$ {
# if (!-e $request_filename) { rewrite / /index.php last; }
if (!-e $request_filename) { rewrite / /404.php last; }
}
}
The index directive and the $uri/ element of the try_files directive, has the side-effect of adding a trailing / to directory names by performing an external redirect.
To avoid the external redirect and return an appropriate index file when presented with a slash-less directory name, implement the index functionality explicitly within the try_files directive:
location / {
try_files $uri $uri/index.html $uri.php;
expires 30d;
}
Notice that .php works only in the last element at this location. If you need to check for $uri/index.php (in addition to $uri.php) you can use a named location block - and move or copy your fastcgi configuration into it.
For example (based on your server block):
root /var/www/vhosts/site.com/htdocs;
error_page 404 /404.php;
location / {
try_files $uri $uri/index.html #php;
expires 30d;
}
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 = /index.php { return 301 $scheme://$host; }
location = /index { return 301 $scheme://$host; }
location /. { return 404; }
location ~* \.php(/|$) { rewrite ^(.*)\.php $1 last; }
include "ssl_offloading.inc";