Nginx image not found fallback - nginx

My site have many images /image/test/manyfile.jpg and now day I have /image/test/manyfile_large.jpg, but not all .jpg have _large.jpg.
So my idea is use Nginx to check manyfile_large.jpg file, if not exist then rewrite or redirect to manyfile.jpg
Can anyone give an example config?
Thanks a lot! :)

You can use try_files to test for the existence of one or more files. See this document for details.
First you need to capture the components of the URI so that you can construct the two filename variants to try.
I am not sure if the examples in your question and comment are URIs or pathnames. In the following example, the URI is /image/foo/bar.jpg and the corresponding files are located at /path/to/image/foo/bar.jpg and (optional) /path/to/image/foo/bar_large.jpg.
For example:
location ~ ^(/image/.+)\.(jpg|png|svg)$ {
root /path/to;
try_files $1_large.$2 $1.$2 =404;
}
The block will return the large variant if it exists, then the regular variant if it exists, then a 404 status if neither exist.
The order of regular expression location blocks is significant, as the first block with a matching regular expression is used to process the request. See this document for details.

Related

Nginx - turn an $arg_ into a path with 3 subdirectories for try_files

I'm currently working on an image caching server using Nginx, however I'm running into problems getting Nginx to serve the cached images.
There are two kinds of images the caching server is supposed to be able to serve, the first being rather small images which require little interference from the image server.
This works the way I want it to using the following configuration:
location = /small/ {
try_files /small/logos/$arg_id.jpg #gen_script;
}
location #gen_script {
rewrite ^(.*)$ /small/index.php?id=$arg_id;
}
No problems here, using this configuration it tries to find an image in the directory /small/logos with a name that matches the supplied ID-parameter, if it doesn't exist it refers to #gen_script, that one leads to an index.php which will generate the image. This works without a problem.
Now for the part that is giving me trouble, the second kind of image the server is supposed to serve is generally larger and is created based on multiple parameters (height, width, that sort of thing).
These images are identifiable by a generated hash which is always 128 characters long.
What I'm trying to achieve is that the first three characters of the hash are turned into directories of the path where the image can be found, followed by the complete hash and ".jpg". Here is the configuration for that aspect, it's not working and I'm out of ideas as to why:
location ~* "^\/image\.php\?hash=(?<a>.{1})(?<b>.{1})(?<c>.{1})(?<d>.{125})(?:.+)$" {
try_files /images/$a/$b/$c/$a$b$c$d.jpg #image_gen;
}
location #image_gen {
rewrite ^(.*)$ /image.php$is_args$args;
}
In contrast to expected behaviour every request to image.php is actually received by (or sent to) image.php, creating the requested image again, completely in contrast with what the (or any...) caching server is supposed to do.
For clarification purposes, if the hash would be abcde12345 (shortened for readability) then the image would be located in /images/a/b/c/abcde12345.jpg.
How can I ensure try_files checks if the file exists in the expected subdirectory-structure and if it doesn't then forward the original request to /image.php with its arguments, ensuring the image is generated?
You can use something like below
http {
map $arg_hash $arg_hash_folder {
default '';
~*(.)(.)(.)(.*)$ /$1/$2/$3/$1$2$3$4.jpg;
}
server {
location = /image.php {
try_files $arg_hash_folder #process_image;
}
location #process_image {
# Try rewrite here and see if it works
# If it doesn't work then you should have the php processing code here
# fastcgi_pass ....;
}
}
}
The map will give you the folder path, if it is not found the process_image will be called, here you can try a rewrite, which I have my doubts will work, so you will need to include the PHP processing code here again

Rewrite url without hash in nginx

I am trying to use Nginx rewrite static file path to strip the hash added for cache busting. The hash is always 10-symbol long. For example,
/min/3rd.party.min.1234567899.js has to become /min/3rd.party.min.js
I have tried this, but it doesn't work (fails at configtest) and also looks way to complicated.
location /min/ {
root /opt/app/public;
rewrite ^.*(?<=(.))[a-z0-9]{10}[.](?=(js|css))[js|css]$ $1$3;
}
I have no idea how you arrived at your regular expression pattern, but the following seems to work:
rewrite "^(.*)\.\w{10}\.(js|css)$" $1.$2 break;
Any pattern that contains a brace, must be placed within quotes. Use the break suffix to process the rewritten URI within the same location. See this document for details, and this useful resource on regular expressions.

Nginx location expressions

I have problem when im using ~* for case insensitive expression
this will download my index.php instead of showing this file.
maybe i do not have a correct understanding of this expression. can you help me ?
I found my problem
When I want to use an insensitive expression, I should create
another location block to route the query to proper location in webserver!
Thank you for the response !

Having issues with regex matching wrong URLs in NGINX rewrite

Hi I have urls that look like this
http://dansawesomesite.com/123/articlename
I have the following rewrite rule in nginx
location ~* /(\d+)/([\+\w-\ ]+)/?$ {
try_files $uri /wpcontentredir.php?slug=$1;
}
This matches the above URL however the issue comes about when I have the following URL's
http://dansawesomesite.com/posts/630325/like
(as well as a number of similar)
These also end up getting matched which is correct based on my regex, but will mess things up as I dont want these urls parsed through that try_files, I just want them to pass as is.
Just wondering if anyone can help me with only matching the top first URL?
CHeers
Dan
Try to add "^" to the beginning of regexp
location ~* ^/(\d+)/([+\w-\ ]+)/?$
So it will match only if first part of URI contains digits and not "posts" or something

Rewrite Rule in Nginx

I conisder moving to Nginx but I want you to ask if is possible to rewrite urls into that schema, and if you could help me a bit:
A url like http://example.com/username into profile.php?u=username. But then, will I have problems in accessing other pages like e.g. home.php
A url like http://example.php/questions/102039/that-question into questions.php?quid=102039
Thank you very much!
Yes, it is possible to rewrite URLs with Nginx.
Your first example can be handled easily by wrapping the rewrite with a block which checks if a file (home.php in your example) exists; if it doesn't, then it tries the redirect into the profile.php request. (See the try_files syntax for this.)
Your second example is just as simple:
Rewrite ^/questions/(\d+) /questions.php?quid=$1
(Because the matching expression is not anchored at the end, it should accept any string after the digits, but I haven't checked that so I'd recommend you test it.)

Resources