0

I have a configuration as below, but I am getting 500 error. Where could this error be?

upstream masterservers {server 192.168.1.1:8000;}
upstream slaveservers {server 192.168.1.2:8001;}

map $request_uri $redirect_to {
    "target=master"     masterservers;
    "target=slave"   slaveservers;
}

server {
    listen 80;
        server_name 192.168.1.10;

       location / {
        proxy_pass              http://$redirect_to;
    }

}

When I call the URL as below, I get the following error.

http://192.168.1.10/app/index.html?target=master

http://192.168.1.10/app/index.html?target=slave

Nginx Log: *2 invalid URL prefix in "http://", client: 192.168.1.11, server: 192.168.1.10, request: "GET /favicon.ico HTTP/1.1", host: "192.168.1.10", referrer: "http://192.168.1.10/app/index.html?target=master"

MrTux01
  • 103
  • 1

1 Answers1

0

You are comparing your $request_uri, which is equals to /app/index.html?target=master from your example, to target=master and target=slave strings. None matched, so $redirect_to variable becomes an empty string. If you want to check if the $request_uri contains a target=master or target=slave substrings, you can use regex patterns inside the map block:

map $request_uri $redirect_to {
    "~target=master"     masterservers;
    "~target=slave"      slaveservers;
}

or better check the $arg_target variable value:

map $arg_target $redirect_to {
    master     masterservers;
    slave      slaveservers;
}

Also consider using some default value when no target query argument is specified in request (or its value is invalid):

map $arg_target $redirect_to {
    master     masterservers;
    slave      slaveservers;
    default    masterservers;
}

The last one can be simplified to

map $arg_target $redirect_to {
    slave      slaveservers;
    default    masterservers;
}

Or make some preliminary check like

map $arg_target $redirect_to {
    master     masterservers;
    slave      slaveservers;
}
server {
    listen 80;
    server_name 192.168.1.10;

    if ($redirect_to = '') {
        return 501; # HTTP 501 Not Implemented
    }

    location / {
        proxy_pass http://$redirect_to;
    }

}

Update

If I understand your additional question correctly - how to load all the assets from the same upstream as the main HTML file - you can try to get an upstream name from the HTTP Referer header value if the target query argument is absent using two chained map blocks (here are regex really come in place):


map $arg_target $redirect_to {
    master     masterservers;
    slave      slaveservers;
    default    $by_referer;
}
map $http_referer $by_referer {
    "~target=master"     masterservers;
    "~target=slave"      slaveservers;
}
server {
    ...
}
Ivan Shatsky
  • 2,726
  • 2
  • 7
  • 19