nginx rewrite specific folder to php and arg - nginx

Am trying to redirect
domain.tld/blog/read.php?article=first-article to domain.tld/blog/first-article
What I tried and didn't work resulting in redirect to domain.tld/first-article
location "^blog/([^/]+)/?$" {
try_files /$uri /$uri/ /blog/read.php?article=$1;
}
location /blog {
rewrite ^/blog/?$ /blog/read.php?article=? last;
rewrite ^/blog/([-a-zA-Z0-9_]+)/$ /blog/read.php?article=$1? last;
}
location ~ "^/blog/([^/]+)/?$" {
try_files /$uri /$uri/ /blog/read.php?article=$1;
}
Thinking the issue comes from my other parts in the config and mainly second location from below
server {
...
...
location ~ "^/([^/]+)/?$" {
try_files $uri $uri/ /device.php?name=$1;
}
location ~ "^/([^/]+)/([^/]+)/?$" {
try_files $uri $uri/ /device.php?name=$1&crversion=$2;
}
...
Any pointers would help a lot
Cheers

So the fast answer is actually the fact that my config was fine first time, yet nginx config is read top bottom with first match being the one that is used.
So in the end the "fix" was adding the blog part upper in the site config
location ~ "^/blog/([^/]+)/?$" {
try_files /$uri /$uri/ /blog/read.php?article=$1;
}

Related

nginx rewrite & parameter full-url and file extensions

I will try to be brief. I have the following nginx rewrite url:
rewrite ^/(.*)?$ /index.php?completeURL=$1 last;
I want a url like:
http://mywebsite.com/http://www.otherwebsite.com/dir1/dirx/article.php&id=2&category=1
request:
http://mywebsite.com/index.php?completeURL=http://www.otherwebsite.com/dir1/dirx/article.php&id=2&category=1
Currently the nginx rule have a problem. Example: If the parameter contains a .php extension he looks for that file on my server.
Example: http://mywebsite.com/dir1/dirx/article.php
How can I solve this problem in your opinion?
UPDATE:
here the nginx configuration (and rewrite) files:
(config) https://gist.github.com/ivanionut/cc53c9de372b932c3937d9394d3b448c
(rewrite) https://gist.github.com/ivanionut/4df3ad9b858a54ae01461ab078adffb6
The simplest solution (assuming that the server does nothing else other than serve index.php) is to remove the usual location ~ \.php$ block and perform a rewrite ... break; in the same block as the fastcgi_pass. There are a number of ways of achieving this, including:
location / {
rewrite ^/(.*)?$ /index.php?completeURL=$1 break;
fastcgi_pass ...
...
}
An alternative strategy is to perform the rewrite only if a local file does not already exist, but you need to ensure that .php files are tested too. For example:
location / {
try_files $uri $uri/ #rewrite;
}
location ~ \.php$ {
try_files $uri #rewrite;
fastcgi_pass ...
...
}
location #rewrite {
rewrite ^/(.*)?$ /index.php?completeURL=$1 last;
}

NGINX try_files Fallback

I have this folder structure:
/document/root/
|-- main
`-- wishlist
I want to get my nginx to work like this: If I point my browser to example.com/wishlist it will display the index.html on the wishlist folder. If I point my browser to example.com, I want it to fallback to main/index.html (and, of course, related main/style.css and other files that are in the main directory).
I don't want to write a location rule for every folder I have under my root, so I want this to be as generic as possible. I have found this questtion and it has helped me to get most of the job done, but there's something not working: if I point the browser to wishlist/index.html it works perfectly. But if I remove the index.html and point it just to example.com/wishlist the browser will return a 404. My current Nginx config is below. Can someone point me in the right direction? Thanks.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /document/root/main;
location ~ ^/([^/]+)(/.+)?$ {
if (!-d "$document_root/$1") {
return 404;
}
try_files /$1$2 /main$2 =404;
}
}
All you need to do for the index file is:
index index.html
location / {
try_files $uri.html $uri/index.html =404;
}
location /wishlist {
try_files $uri.html $uri/index.html =404;
}
Turns out I found out a way that worked for me: using a custom #location on nginx. My final piece of code turned out something like this:
location / {
root /document/root/main;
index index.html;
try_files $uri $uri/ index.html;
}
location ~ ^/(.+)$ {
root /document/root;
index index.html;
try_files $uri $uri/ index.html #main;
}
location #main {
try_files /main/$uri /main/$uri/;
}
Now example.com uses /document/root/main as it's root and example.com/wishlist uses /document/root/wishlist :) Hope this helps someone else.
Keep it simple:
server {
root /document/root/main/;
index index.html;
location /wishlist {
root /document/root/;
}
}

Nginx Proxy_pass try_files drop to location handler

I'm running into small hick up with try_files in combination with proxy_pass (or alias for that matter).
Current config:
location /staticsrv {
alias /var/www/static/trunk/;
#proxy_pass http://static.localtest.nl/;
}
location ~ ^/staticsrv/images/gallery/(.*)$ {
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^(.*)$ /index.php/?c=media&m=index&imag=$uri;
}
However for every file it gets dropped to the rewrite rule as it doesn't exist.
Is there a "trick" (read correct config) to fix my misfortune? Or is it just not possible? Both domains will eventually be on the same server so we can work with alias and proxy_pass.
Thanks in advance
Your location ~ ^/staticsrv/images/gallery/(.*)$ needs a root or an alias to construct a local path for try_files to try. Also, you do not necessarily need a regular expression here:
location /staticsrv/images/gallery/ {
alias /var/www/static/trunk/images/gallery/;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}
proxy_pass will not work with try_files as one deals with remote content and the other with local content.
I try to avoid using alias and try_files in the same location block because of this open bug.
A possible work around would be to use another intermediate URI that closely matches the document root:
location /staticsrv/images/gallery/ {
rewrite ^/staticsrv(.+)$ /trunk$1 last;
}
location /trunk {
internal;
root /var/www/static;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}

nginx rewrite if specific name is included

I would like to rewrite all requests that contain 'xhr.php' to /xhr.php instead of the original path.
The request:
type: "POST",
url: "/system/classes/templates/address/xhr.getAddress.php",
data: vars,
dataType: "html"
Should go to /xhr.php with the path as argument. I tried this:
rewrite ^/(.*)/xhr.(.*)\.php$ /xhr.php?parameter=$1&parameter2=$2 last;
However it does not work. Any ideas? My Config looks like this:
location / {
root /var/www/http;
try_files $uri $uri/ index.php /index.php$is_args$args #rewrite;
}
location #rewrite {
rewrite ^/(.*)/xhr.(.*)\.php$ /xhr.php?parameter=$1&parameter2=$2 last;
}
Is this basically possible with nginx? Whats wrong here?
Thanks :)
//EDIT:
I solved it, however it does not look very efficient …
location / {
root /var/www/http;
try_files $uri $uri/ index.php /index.php$is_args$args;
}
if ($request_uri ~ .*/xhr.*) {
rewrite ^/(.*)/xhr.(.*)\.php$ /xhr.php?parameter=$1&parameter2=$2 break;
}
You can remove the if and let the rewrite at the same level of location. In this way you'll save one regex for each request (the one inside the if).
Actually I think you can remove the location / too:
root /var/www/http;
rewrite ^/(.*)/xhr.(.*)\.php$ /xhr.php?parameter=$1&parameter2=$2 break;
try_files $uri $uri/ index.php /index.php$is_args$args;

Nginx - multiple/nested IF statements

What i want to do:
Check if request comes from Facebook
Check if URL is like domain.com/2
If above conditions are true - show content from /api/content/item/$1?social=1
If above conditions are false - show "normal page"
It is a single page app. Before my changes configuration looked like this (and it worked):
location / {
root /home/eshlox/projects/XXX/project/project/assets/dist;
try_files $uri $uri/ /index.html =404;
}
I've tried to use if statements:
location / {
set $social 1;
if ($http_user_agent ~* "facebookexternalhit") {
set $social UA;
}
if ($uri ~* "^/(\d+)$") {
set $social "${social}URL";
}
if ($social = UAURL) {
rewrite ^/(\d+)$ /api/content/item/$1?social=1;
}
root /home/eshlox/projects/XXX/project/project/assets/dist;
try_files $uri $uri/ /index.html =404;
}
With this configuration everything works as i expected only if both conditions are true or false.
If one of conditions is true and the second is false (or vice versa) then nginx always returns status 404.
I have found "IfIsEvil" on nginx site, i've tried to use mapping (can i use mapping in this case?) but still i can't resolve this problem.
Any ideas?
Best regards.
There is good article about common pitfalls in nignx wiki.
First, I've moved root directive to server level. Second, location is the best way to check urls. So I rethink your requirements as
if location consist of digits
and request from facebook
we have to rewrite url, and the result is:
root /home/eshlox/projects/XXX/project/project/assets/dist;
location / {
try_files $uri $uri/ /index.html;
}
location ~ "^/\d+$" {
if ($http_user_agent ~* "facebookexternalhit") {
rewrite (.+) /api/content/item$1?social=1;
}
try_files $uri $uri/ /index.html;
}
Also, there is almost no reason to have =404 after /index.html in try_files directive.

Resources