nginx location with regular expression - nginx

i have the nginx server as reverse proxy for apache. just trying to have multiple locations with reg expressions but fail.
I want to set the expires header for all jpg's and png's but not for images in a specific folder
currently
location ~* ^(?!/login/)(.*)\.(jpg|png)$ { expires 30d; }
this works with request from
http://example.com/test/image.jpg
but not working with
http://example.com/login/image.jpg
also tried with several location
location ~ ^/login/$ { break; }
location ~* \.(jpg|png)$ { expires 30d; }
but not working. I also tried nested location but same problem, nothing work. Can anyone help me?
Thanks and kind regards, Tom

Related

Restrict access to a certain URL prefix

I want to block access to all URLs in my server except URLs starting with /myapp/path, excluding /myapp/path/nope, which should be blocked as well.
I tried:
nginx.org/server-snippets: |
location = /myapp/path/nope { return 404; }
location ^~ /myapp/path {}
location / { return 404; }
But got 404 messages on URLs starting with /myapp/path as well. To be frank, even after reading the documentation and trying all sorts of things it seems I haven't figured out how nginx determines what location to serve. What it wrong with my snippet? Thanks!
Eventually I resolved this issue using a negative regex.
In my question I used the location and the regex incorrectly, as I never told nginx what to do with the path I wrote.
So in order to restrict access to anything that doesn't start with /myapp/path use:
location ~ ^/(?!myapp/path) { return 404; } # Or deny all;

NGINX ignore hash css file and fetch any css that exists

I'm cache-busting with hashed css files (app-123456.css). The css file requests are proxied to a cdn with nginx. I need to keep the files statically named on the cdn, as there is a requirement to allow the customer to modify some css and re-upload the file. How can I pass the hashed file request to cdn and return the statically named file? For example a request to app-123456.css would return app.css, if it existed on the cdn. I'm trying to use try files but have been unsuccessful. Will cache-busting still work in this scenario, if the returned file is statically named? Thanks for any help.
location ~* (.+)\.(?:\d+)\.(css)$ {
try_files $uri $1.$2 #styles;
}
location #styles {
autoindex on;
proxy_pass http://[url].net; # needs to go to http://[url].net/styles/
}
EDIT
location ~* (.+)-(?:\d+)\.(css)$ {
try_files $uri $1.$2 #styles;
}
location #styles {
autoindex on;
rewrite ^(.+)-(?:\d+)\.(css)$ /styles$1.$2 break;
proxy_pass http://[url].net; # needs to go to http://[url].net/styles/
}
Fixed
^(.+)\-([a-zA-Z0-9]*)\.(css)$
You need to modify the URI within the named location before passing it upstream with proxy_pass. This can be accomplished using a rewrite...break statement. See this document for details.
For example, using your updated regular expression:
location ~* ^(.+)\-(?:[a-zA-Z0-9]*)\.(css)$ {
try_files $uri $1.$2 #styles;
}
location #styles {
rewrite ^(.+)\-(?:[a-zA-Z0-9]*)\.(css)$ /styles$1.$2 break;
proxy_pass http://...;
}
The above solution basically applies the same regular expression to the URI twice, which seems inefficient and redundant.
If the /styles/ URI prefix is unique to the upstream server, you could perform the translation in the original try_files statement. See this document for details.
For example:
location ~* ^(.+)\-(?:[a-zA-Z0-9]*)\.(css)$ {
try_files $uri $1.$2 /styles$1.$2$is_args$args;
}
location ^~ /styles/ {
internal;
proxy_pass http://...;
}
The ^~ operator give the prefix location a high precedence (see this document for details) and the internal directive prevents the URI from being directly accessible (see this document for details).

How to use regex like /page/.*/page/ in Nginx location

Url example:
http://test.com/test/page/4?-test?o?o_html/page/100/page/2/page/3/page/4/page/4/page/2/page/106/page/107/page/2/page/3/page/4/page/108/page/3/page/2/page/3/page/4&-test
I want to use nginx location to forbidden it.
But I faild, I have tried different rules in http://nginx.viraptor.info/
location ~ /page/.*/page/ {
return 403;
}
location ~* \/page/.*/page/ {
location ~* /page/\.*/page/ {
None of them worked...
I found only use /page/ is Worked.
location ~* /page/ {
But when I add .*/page/ like:
location ~* /page/.*/page/ {
It's not worked...
Now I use php to judge url like:
if (preg_match ("/\/page\/.*\/page\//i", $_SERVER["REQUEST_URI"]))
Please tell me how to use regex .* in nginx conf location. I want to use nginx.
Everything after the first ? are URI arguments, they are not part of the URI, as such a location match will never work. If there is a solution that allows you to do this in Nginx, it will be a kludge, you should perform this level of checking in your script like you stated you are already doing.
See: https://serverfault.com/questions/811912/can-nginx-location-blocks-match-a-url-query-string

Nginx location block for specific path and certain file types

I am having trouble defining a location block for certain paths and file types.
I am using wordpress and using a plugin which generates dynamic sitemaps..It redirects to path like sitemapindex.xml, which do not actually exist and nginx is trying to serve it statically.
I need to be able to pass this to apache
I need to send anything that is http://example.com/blog/*.xml to apache. This is what i am trying, which does not work.. so for instance:
http://example.com/blog/post.xml or http://example.com/blog/sitemapindex.xml
nginx config
server {
location ~* ^/blog/*.xml$ {
include /etc/nginx/proxy_params;
proxy_pass http://127.0.0.1:8080;
}
}
what is the correct syntax
Thanks
I had similar problem with my images. In my applications, images were being served from two different locations.
You can specify different sources based on url pattern. Your solution would then look something like this.
location ~* ^/blog/.+\.(xml)$ {
root /some/path/;
expires 90d;
}
location ~* \.(xml|js|jpg|png|css|html|otf|eot|svg|ttf)$ {
root /some/other/path/;
expires 30d;
index index.html;
}
Gotta escape that period
server {
location ~* ^/blog/.*\.xml$ {
proxy_pass http://127.0.0.1:8080;
}
}

Nginx : Serve JPG images from different root and location

I have 3 different stockage area : "avatars" , "articles", "trends" where I store my images.
I want to "link" the URL "/trends/123.jpg" to trends folder , "/avatars/23.jpg" to avatar and so on.
Configuration 1:
server
{
listen 8089;
server_name localhost;
root /var/www;
location /trends/
{
alias /var/storage/hottrend/;
}
location ~* ^.+\.(jpeg|gif|png|jpg)
{
add_header Cache-control "public";
access_log off;
expires 90d;
}
}
Configuration 1 : "GET /trends/123.jpg" never match /trends/ location, why ?
Configuration 2:
server
{
listen 8089;
server_name localhost;
root /var/www;
location ~ ^/trends/(.*)\.jpg$
{
rewrite ^/trends/(.*)$ /$1 break;
root /var/storage/hottrend;
}
location ~* ^.+\.(jpeg|gif|png|jpg)
{
add_header Cache-control "public";
access_log off;
expires 90d;
}
}
Configuration 2: The last rule with the caching stuff is not matched. What is the best approach to server JPG files from different location/root ?
The two configurations have different but related problems. The two issues are:
the order in locations are matched; and
what happens when a location is matched.
I'll first explain how it works, and then I'll address your configurations.
How it works
Location matching
You can find the details on this nginx wiki page, but I have always found the wording to be confusing. (It mixes implementation details in the description of behaviour.) What it means is that locations are matched in the following order:
exact matches like location = /robots.txt
eager non-regex prefixes like location ^~ /trends/
regex matches like location ~* \.(jpg|png), or case-sensitive location ~ \.(jpg|png)
lazy non-regex prefixes like location /trends/ or location /
If multiple regular expressions match, then the first match beats the others. If multiple non-regex prefix match, I think it selects the most specific match -- I'll check this and update.
Location behaviour
A matching location is responsible for serving the designated content. It is also responsible for providing cache-control headers and so on. You can have a location that matches particular URL patterns to apply specific headers, but that location must also serve the content. If it cannot serve the content, you will most likely get an 404 error -- it won't look for other matching locations.
Lastly, be extra careful if you have a rewrite within a location. An internal redirect can happen earlier than some directives, in which case, those directive may not apply before the redirect causes the locations to be searched again.
Configuration 1
Your trends location is a lazy non-regex prefix, so it would only match if the regex location fails to match. You can fix this by using an eager non-regex match, such as
location ^~ /trends {
...
}
However, doing so will highlight the other configuration problem.
Configuration 2
You have two locations that could potentially match jpg files. Only one will succeed. If the first matches, then the cache control of the second location won't be applied. If the second matches, then the alias won't take effect.
The fix is to make sure that all directives needed are applied within the location that matches. You can either be explicit in one file, such as
location ^~ /trends
{
alias /var/storage/hottrend;
add_header Cache-control "public";
access_log off;
expires 90d;
}
location ~* ^.+\.(jpeg|gif|png|jpg)
{
add_header Cache-control "public";
access_log off;
expires 90d;
}
The neater solution for managing directives that must be applied to several locations is to factor those details into another file, and then include it at both locations. (Mohammad AbuShady did so in his example.) Something like this:
# Inside your main .conf
location ^~ /trends
{
alias /var/storage/hottrend;
include image-headers.conf;
}
location ~* ^.+\.(jpeg|gif|png|jpg)
{
include image-headers.conf;
}
# Inside image-headers.conf
add_header Cache-control "public";
access_log off;
expires 90d;
well I don't usually use alias but I think this is a good example to use alias for, you can put your caching settings inside /etc/nginx/image_caching.conf. If trends is only used for images i would not try to complicate the regex and assume that it always has images
location /trends {
alias /var/storage/trends;
include /etc/nginx/image_caching.conf;
}
And for your example config, you should have not added /trends inside root /var/storage/trends; because it's already used in the location, so i think it would show 404 becuase it's looking for /var/storage/trends/trends/123.jpg
Nginx checks locations defined as regular expressions in the order in which they appear in the configuration file and uses the location with the first matching expression.
Therefore, you should make sure location ~\.jpg$ appears before any other locations defined as regular expressions

Resources