how to rewrite invalid images urls with nginx - nginx

I have an image path like this
www.domain.com/i/1.png
but this image doesn't exist so i want to rewrite the url to show this image instead
www.domain.com/i/0.jpg

You can use try_files for such checks. The try_files only works if the nginx is used as webserver for local files".
https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files
location /i/ {
try_files $uri /i/0.jpg;
}
location = /i/0.jpg {
expires 30s;
}

Related

Nginx config for hosting two nested websites

I am trying to write a Nginx config so that:
If the URL is exactly /Site/ it must serve C:\Site\index.html
If the URL is /Site/something/else it must serve C:\Site\something\else (fallback to index.html if it doesn't exists) BUT only if /something/ is different from /api/ and /dev/
If the URL is /Site/api/something/else it must redirect the exact request to another server otherserver/api/something/else
If the URL is exactly /Site/dev/ it must serve C:\Site-Dev\index.html
If the URL is /Site/dev/something/else it must serve C:\Site-Dev\something\else (fallback to index.html if it doesn't exists) BUT only if /something/ is different from /api/
If the URL is /Site/dev/api/something/else it must redirect the exact request to another server otherserverdev/api/something/else
So the key point here is that:
/Site/ and /Site/dev are two different websites
Each one has its own .../api endpoint
So far I wrote this config:
server {
listen 19001;
include mime.types;
location ^~ /Site/api/ {
proxy_pass http://otherserver;
}
location ^~ /Site/dev/api/ {
proxy_pass http://otherserverdev;
}
location = /Site/ {
root C:\Site;
try_files /index.html =404;
}
location ~ ^/Site/(.*) {
root C:\Site;
try_files $1 $1/ /index.html =404;
}
location = /Site/dev/ {
root C:\Site-Dev;
try_files /index.html =404;
}
location ~ ^/Site/dev/(.*) {
root C:\Site-Dev;
try_files $1 $1/ /index.html =404;
}
}
This doesn't work at all, I'm getting index.html in every request and also dev and nondev are mixed up.
Is there a way to achieve what I need?

Nginx sites-available configuration

So, I emigrate from Apache to Nginx, and it is a terrible experience for me.
Right now I need your help with understanding of Nginx file of configuration:
server {
....
location / {
try_files $uri $uri/ $uri.html $uri.php$is_args$args;
}
location ~ "^/([-0-9a-zA-Z_\s]+)$" {
try_files $uri $uri/ /user/user?username=$1;
}
location ~ "^/trends/([.*]+)$" {
try_files $uri $uri/ /trends/trend?name=$1;
}
}
When I type to the URL bar site https://example.com/someuser ,
it successfully redirect me (show to me the folder) to the folder example.com/user/user?username=someuser .
But when I trying to access to https://example.com/trends/sometrend
Nginx load me the page from the fist block.
Why it do this?
Thanks for your help.
Sorry, for my late reply, but I suppose that it will be helpful for others, who will face with similar problem:
server {
...
# enable utf8
charset UTF-8;
# pretty urls
# user folder
location ~ "^/([-0-9a-zA-Z_\s]+)$" {
try_files $uri $uri/ /user/user?username=$1;
}
# trends
location ~ "^/trends/([\x00-\xff]+)$" {
try_files $uri $uri/ /trnds/trend?name=$1;
}
...
}
Let me explain it in details.
\x00-\xff - it allow all symbols in Unicode format, don't forget to enable UTF-8 with charset UTF-8; in the server block.
/trnds/ - on official documentation to Nginx (cant find it now to post the link) they have a little explain that this folder shouldn't exist in the server if we have the same address in the URL bar.
So, I change try_files from /trends/ to /trnds/ and do refactor of folder on my server and everything work like a charm!

Nginx - server static files

I'm trying to configure nginx to serve static files (images).
I would like to get images by this URL:
DOMAIN/images/RANDOM_FOLDER_NAME_123/RANDOM_FILE_NAME_456.png
On server I store images as:
/usr/share/nginx/html/RANDOM_FOLDER_NAME_123/IMAGES
/usr/share/nginx/html/RANDOM_FOLDER_NAME_234/IMAGES
/usr/share/nginx/html/RANDOM_FOLDER_NAME_345/IMAGES
/usr/share/nginx/html/RANDOM_FOLDER_NAME_456/IMAGES
I would like to match fe.
DOMAIN/images/RANDOM_FOLDER_NAME_123/RANDOM_FILE_NAME_456.png -> /usr/share/nginx/html/RANDOM_FOLDER_NAME_123/RANDOM_FILE_NAME_456.png
How have I set nginx path to achieve this? I tried to do this by:
location /images/ {
try_files $uri =404;
autoindex off;
}
But I think that problem is images in URL.
You can try
location /images {
alias /usr/share/nginx/html;
}
https://www.techcoil.com/blog/understanding-the-difference-between-the-root-and-alias-directives-in-nginx/

Use nginx directive to look for a jpg in another location

I have a general nginx rule to serve jpgs from their URI.
So if the URI is "http://example.com/images/1.jpg" it will serve under the form root of the site/images/1.jpg
I want to try and serve the image from alternative path if not found on the original path. How do I write the second location?
Here is what I got:
location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|ico)$ {
try_files $uri $uri/ #fallback;
access_log off;
expires max;
log_not_found off;
}
How do I write the fallback to look for the files in another location like /home/user/anotherfolder?
You can use a named capture in the regular expression location to save the filename for later. You can cascade named locations, to try different roots:
location ~* ^/images(?<filename>/.+\.jpg)$ {
try_files $uri #other;
}
location #other {
root /path/to/alternate;
try_files $filename #fallback;
}
If there is a suitable common parent directory, you can achieve the same thing in a single location block.
location ~* ^/images(?<filename>/.+\.jpg)$ {
root /path/to/ancestor;
try_files /dir/$uri /other/dir/$filename #fallback;
}

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