Nginx locations - case insensitive with spaces - nginx

My question is about nginx "location" configuration blocks:
If I want to make a location with a space character (well, %20) in the URL I can do it like so:
location ^~ "/Style Library/" {
}
If I want to make a case-insensitive location, I can do it like so:
location ~* ^/StyleLibrary/ {
}
However, I can't find a way of getting case-insensitive locations with space characters working. None of these appear to work:
location ~* "^/Style Library/" {
}
location ~* ^/Style[^_]Library/ {
}
location ~* ^/Style\sLibrary/ {
}
location ~* ^/Style.Library/ {
}
Can anyone help?

Do you have other regex locations that may be handling the request earlier in the server block? I just ran a test locally and was able to make the following location work:
location ~* "^/Style Library/" {
rewrite ^ /dump.php;
}
where /dump.php is just a simple script that does a var_export($_SERVER);
I tested this with
curl -i "dev/StYlE LiBrArY/"
I'd guess that some other location is handling the request instead of that regex location.

Related

NGINX URI rewrite/add pattern

Having the uri /test/test.ssm/.umm/view=500-974652006, I need to have NGINX this converted to:
/test/test_new.ssm/.umm/view=500-974652006. In other words, add the _new pattern when capturing the .ssm URI.
I have tried the following NGINX configurations, but nothing worked:
rewrite ^(.*).ssm.*)$ $1_new.ssm$2;
location / { set $proxyurl 'http://backend'; if ($request_uri ~* "(.*).ssm(.*)") { set $proxyurl 'http://backend/$1_new.ssm$2'; } proxy_pass $proxyurl; }
thank you.

how to make nginx location match path both with slash and without slash?

currently i have this location in my nginx file, it does not work with http://mydomain/ab/cd. How can i make the browser to go to the same page when user type both http://mydomain/ab/cd and http://mydomain/ab/cd/?
location /ab/cd/ {
}
The fastest, in terms of performance, is simply two exact locations:
location = /ab/cd {
...
}
location = /ab/cd/ {
...
}
You can try
location ~* ^/ab/cd(|\/) {...}
It is a prefix matching regex that checks if it has trailing slash or not.

nginx server: how to remove first directory from URL

Can anybody please help me to remove first directory name from URL?
My Image location is _data/hotel/3/15377/hotel_image.jpg
But Image path gets changed due to relative URL in code and it become to something like this.
example.com/france/_data/hotel/3/15377/hotel_image.jpg
example.com/usa/_data/hotel/3/15377/hotel_image.jpg
example.com/india/_data/hotel/3/15377/hotel_image.jpg
is their any possibilities to remove dynamic country name from above URL
If you want to rewrite only this particular URL, you can use this location block in your config:
location ~ /[a-z]+/_data/hotel/3/15377/hotel_image.jpg {
try_files /_data/hotel/3/15377/hotel_image.jpg;
}
If you want to rewrite all URLs which lead to /<country>/_data/..., you can use:
location ~ /[a-z]+/_data/(.+) {
try_files /_data/$1;
}
or for stricter URL checking:
location ~ /(?:france|usa|india)/_data/(.+) {
try_files /_data/$1;
}
#Ivan Shatsky's answer is great for files but also if we want to redirect a general url is better if you use the rewrite directive.
Depending where you define the rewrite directive you have two ways to implement it:
A. In the server context
server {
...
rewrite ^/[a-z]+/_data/(.+)$ /_data/$1 last;
...
}
B. In the location context
location ~ /[a-z]+/_data/(.+) {
rewrite ^/[a-z]+/_data/(.+)$ /_data/$1 break;
proxy_pass http://backend;
}
Teo, why did you change the flag to break?* Because, if this directive is put inside of a location context, the last flag might make nginx to run 10 cycles and return the 500 error.
Note:
Remember not add / at the end of the proxy_pass directive. This example wont work:
...
proxy_pass http://backend/;
...

How to set the proxy_pass to get the desired address?

I have been struggling with setting up Nginx for our use case.
When I set up Nginx with the following config:
location /dep-core {
proxy_pass http://node-server:7070/;
}
and call the server with following endpoint:
<END-POINT>/dep-core/api/login
the call is redirected to
<ADDRESS-AFTER-RESOLUTION>//api/login
with two leading //s.
and when I remove the trailing / in proxy_pass after 7070:
location /dep-core {
proxy_pass http://node-server:7070;
}
the call is redirected to
<ADDRESS-AFTER-RESOLUTION>/dep-core/api/login
with leading /dep-core appended.
I want my call to redirect my call to:
<ADDRESS-AFTER-RESOLUTION>/api/login
What would be the standard way to achieve this??
For correct translation from /dep-core/foo to /foo, the location directive requires a trailing /.
For example:
location /dep-core/ {
proxy_pass http://node-server:7070/;
}
See this document for details.
To translate /dep-core to /, you can use a rewrite...break with a clever regular expression in the second block of your question. But a simple solution is to add an exact match location for that single edge case.
For example:
location = /dep-core {
rewrite ^ $uri/ last;
}
location /dep-core/ {
proxy_pass http://node-server:7070/;
}

nginx: auth_basic for everything except a specific location

How can I enable HTTP Basic Auth for everything except for a certain file?
Here is my current server block configuration for the location:
location / {
auth_basic "The password, you must enter.";
auth_basic_user_file /etc/nginx/htpasswd;
}
location /README {
auth_basic off;
}
However, on /README, it is still prompting for a password.
How can we fix this?
Thanks!
Mark
Try to use sign = , that helps you:
location = /README {
auth_basic off;
allow all; # Allow all to see content
}
I am doing something similar using "map" instead of "if" to assign the auth_basic realm variable and htpasswd file:
map $http_host $siteenv {
default dev;
~^(?<subdomain>.+)\.dev dev;
~^(?<subdomain>.+)\.devprofile devprofile;
~^(?<subdomain>.+)\.devdebug devdebug;
~^(?<subdomain>.+)\.test test;
~^(?<subdomain>.+)\.demo demo;
~^(?<subdomain>.+)\.stage stage;
# Live
~^(?<subdomain>.+)\.live live;
~^.*\.(?P<subdomain>.+)\.[a-zA-Z]* live;
}
map $http_host $auth_type {
default "Restricted";
~^(?<subdomain>.+)\.dev "Development";
~^(?<subdomain>.+)\.devprofile "Development";
~^(?<subdomain>.+)\.devdebug "Development";
~^(?<subdomain>.+)\.test "Testing";
~^(?<subdomain>.+)\.stage "Stage";
~^(?<subdomain>.+)\.demo "Demo";
# Live
~^(?<subdomain>.+)\.live "off";
~^.*\.(?P<subdomain>.+)\.[a-zA-Z]* "off";
}
server {
.. etc ..
auth_basic $auth_type;
auth_basic_user_file /etc/nginx/conf.d/htpasswd-$siteenv;
}
I'm doing the following:
location = /hc.php {
auth_basic "off";
}
location / {
try_files $uri $uri/ =404;
}
The narrow match:location = /somefile.txt {} comes first, so location / {} can capture the remaining requests
auth_basic "off" requires the quotes around it as far as I know
I also use the exact (full, if you like) match, in order to stop iteration over the other locations defined in the config (read below quote for more info on what it does)
Probably this would work in different orders, and/or without the double quotes also, but why not try to do things as correct and complete as possible, if possible.
The most important modifiers are:
(none) No modifier at all means that the location is interpreted as a prefix. To determine a match, the location will now be matched against the beginning of the URI.
=: The equal sign can be used if the location needs to match the exact request URI. When this modifier is matched, the search stops right here.
~: Tilde means that this location will be interpreted as a case-sensitive RE match.
~*: Tilde followed by an asterisk modifier means that the location will be processed as a case-insensitive RE match.
^~: Assuming this block is the best non-RE match, a carat followed by a tilde modifier means that RE matching will not take place.
quoted from here: https://www.keycdn.com/support/nginx-location-directive
Only auth_basic off didn't work for me
If we have to skip auth for ALL uri's under our url
location ^~ /some/location/to_skip/ {
auth_basic off;
try_files $uri $uri/ /index.html;
}

Resources