strange behaviour when using captured naming group to define alias - nginx

I have a very simple virtualhost configuration:
server {
listen 80 default_server;
server_name datavis.dev.localserver.fr;
root /var/www;
location ~ ^\/datavis\/(?<datarep>[\w]+) {
alias /var/www/data-${datarep}-front;
autoindex on;
}
}
I have 2 index.html in 2 dirs : /var/www/data-test1-front and /var/www/data-test2-front
When i try http://datavis.dev.localserver.fr/datavis/test1/ in my browser i have this return in the error logs:
2016/10/04 17:36:43 [error] 4614#4614: *1 opendir() "/var/www/data-test1-fron" failed (2: No such file or directory), client: 192.168.56.1, server: datavis.dev.localserver.fr, request: "GET /datavis/info/ HTTP/1.1", host: "datavis.dev.localserver.fr"
The last letter is removed... do anyone know why ?

Although not explicit, the example in the manual shows the entire URI being constructed on the alias statement, when enclosed within a regular expression location.
So, although this doesn't directly answer your question, a working alternative configuration could be:
location ~ ^/datavis/(\w+)(.*)$ {
alias /var/www/data-$1-front$2;
autoindex on;
}
Obviously named captures would work too.

You alias doesn't ends with /, but autoindex want it and strip last char from path. index index.html wont work too, because result path will be /var/www/data-test-frontindex.html. So, all you need is to add /:
location ~ ^\/datavis\/(?<datarep>[\w]+)/ {
alias /var/www/data-${datarep}-front/;
autoindex on;
}

Related

How can I reference a variable set by lua in nginx?

I am using nginx lua docker image firesh/nginx-lua:alpine-3.4. And i tried to use environment variable in nginx.config file. Below is the configuration in /etc/nginx/nginx.conf.
user nginx;
env ES_USERNAME;
env ES_PWD;
worker_processes 1;
events {
worker_connections 10240;
}
http {
server {
listen 8080;
server_name localhost;
set_by_lua $es_username os.getenv("ES_USERNAME");
set_by_lua $es_pwd os.getenv("ES_PWD");
location /health {
proxy_pass http://$es_username:$es_pwd#elk-es-http:9200/_cluster/health;
}
...
After launching the container, I see this error in the log:
2021/11/18 01:07:14 [error] 6#6: *6 failed to load inlined Lua code: set_by_lua:1: unexpected symbol near '"http://"', client: 10.0.4.122, server: localhost, request: "GET /health HTTP/1.1", host: "10.0.2.170:8080"
The problem is that the url after proxy_pass is not reading the variable from lua. It treats the ${es_username} as a string rather than read its value. What is the correct way to use that?
That sounds strange. I rather expect both $es_username and $es_pwd variables will have an empty value. set_by_lua expects a function that should return a value, and your returns nothing. The correct usage is
set_by_lua $es_username 'return os.getenv("ES_USERNAME")';
set_by_lua $es_pwd 'return os.getenv("ES_PWD")';

directory index of "/opt/eds/web/html" is forbidden

To configure nginx, as follows
location ~ "^/[A-Z0-9]{32}" {
alias /opt/eds/web/html;
index index.html index.htm;
}
nginx Abnormal log
`2019/12/17 23:22:56 [error] 28874#28874: *4 directory index of "/opt/eds/web/html" is forbidden`
but modify nginx configuration, as follows
location /25DE5ADF310211E9BDB874D435BEC0BA {
alias /opt/eds/web/html;
index index.html index.htm;
}
No problem with access
When alias is used with a regular expression location, you need to capture the remainder of URI and append it on the alias value.
For example:
location ~ "^/[A-Z0-9]{32}(/.*)?$" {
alias /opt/eds/web/html$1;
index index.html index.htm;
}
See this document for details.

Only one NGINX Server Context works at a time for NGINX sites-enabled

I have the following structure I am working with for NGINX
/etc/nginx
- nginx.conf
- conf.d
- a.conf-disabled (I appended 'disabled' so it wont be used)
- b.conf-disabled (I appended 'disabled' so it wont be used)
- sites-available
- a
- b
- sites-enabled
- a (sym link to sites-available/a)
- b (sym link to sites-available/b)
The nginx.conf file looks like the following:
worker_processes 4;
events {
worker_connections 1024;
}
http {
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
The a file in sites-available looks like the following:
server {
listen 80;
server_name a;
location /a/ {
proxy_pass http://172.17.0.20:5678/;
}
}
and the b file in sites-available looks like the following:
server {
listen 80;
server_name b;
location /b/ {
proxy_pass http://172.17.0.20:5678/;
}
}
I am aware these pointing at the same address, I am just using it because I want to be able to test /a and /b separately.
The problem I am having is that only /a will work and /b fails. If I remove a, then /b works fine.
For example:
curl -X GET http://container-ip/a/ -> WORKS FINE
curl -X GET http://container-ip/b/ -> DOESN'T WORK
I ran logs and its not complaining about anything, but does fail with this when I try to hit /b.
2015/07/13 04:51:59 [error] 235#235: *58 "/etc/nginx/html/b/index.html" is not found (2: No such file or directory), client: 10.0.2.2, server: , request: "GET /b/ HTTP/1.1", host: "localhost:8181"

nginx redirect loop, index.html

This seems ridiculous but I've not found a working answer in over an hour of searching.
When I access "http://oa.wechat.com/screen/index.html", it will cause a 301 redirect loop, like this:
"GET /screen/ HTTP/1.1" 301
"GET /screen/index.html/ HTTP/1.1" 301
"GET /screen/index.html/index.html/ HTTP/1.1" 301
...
nginx verson: 1.5.6
nginx.conf
server {
listen 80;
server_name oa.wechat.com;
location ~ ^/screen/ {
alias /data/screen/static/;
index index.html;
}
}
Could anyone tell me the reason? Thanks very much.
i have checked nginx document. the right usage of 'alias':
# use normal match like this
location /i/ {
alias /spool/w3/images/;
}
# use regex match like this
location ~ ^/download/(.*)$ {
alias /home/website/files/$1;
}
the wrong way to use 'alias' is:
location ~ ^/screen/ {
alias /data/screen/static/;
index index.html;
}
In this case, the request would be considered as a directory request, not file request, which will lead a redirect loop.
Anyway, Thanks Flesh very much!
It's already trying to access index.html in that directory because it's the default of nginx's index directive. The problem is that you're using the index directive within a location block where it has a special meaning and executes an internal redirect (as documented).
Unless you know what you're doing, set the index directive within the server block. We end up with the following server block (be sure to read the comments).
server {
# Both default values and not needed at all!
#index index.html;
#listen 80;
server_name oa.wechat.com;
# Do not use regular expressions to match the beginning of a
# requested URI without protecting it by a regular location!
location ^~ /screen/ {
alias /data/screen/static/;
}
}
location examples
server {
# Won't work because the /data is considered the new document root and
# the new location matches the regular expression again.
location ~ ^/screen/ {
alias /data/screen/static/;
}
# Should work because the outer location limits the inner location
# to start with the real document root (untested)
location / {
location ~ ^/screen/ {
alias /data/screen/static/;
}
}
# Should work as well above reason (untested)
location / {
location ~ ^(/screen/) {
alias /data$1static/;
}
}
# Might work as well because we are using the matching group
# VERY BAD because we have a regular expression outside any regular location!
location ~ ^(/screen/) {
alias /data$1static/;
}
# Always works and allows nesting of more directives and is totally save
location ^~ /screen/ {
alias /data/screen/static/;
}
}
Weblinks
alias documentation
index documentation
location documentation
you should move ^ location modifier from ^/screen/, then add ^ before ~, like this:
`location ^~ /screen/ {
alias /data/screen/static/;
index index.html;
}`

nginx how to include rewrite outside of root

How do you call get a file that outside of the root to the be processed. i was reading about the alias and couldnt get it working. so ive tried adding a new root within the location no luck.
this is a cutdown of my config file
server {
listen 443;
server_name domain.com;
---
root ../var/www/domain/public_html;
# works as being called form within the root
location /login {
rewrite ^/login /account/login permanent;
}
#need to
location /validation/code.png {
root /var/www/domain/include;
rewrite ^/validation/code.png /captcha/display_captcha.php;
}
}
You are rewriting the png file to a php file. This will create a sub request for /captcha/display_captcha.php. Is there a location for php in your config? Assuming the php location uses the general root, when the sub request hits this, /captcha/display_captcha.php will not be found an you will get a 404 error.
Your best bet is to copy the php location and create a php location specifically for the php file.
server {
listen 443;
server_name domain.com;
root /var/www/domain/public_html;
...
location = /validation/code.png {
rewrite ^/validation/code.png /captcha/display_captcha.php;
}
location ~ ^/captcha/display_captcha.php {
root /var/www/domain/include
...
# copy php processing code from normal php location.
}
}
Better still, just use '/captcha/display_captcha.php' directly in your html and drop '/validation/code.png' altogether.

Resources