Score:0

Nginx Query String rewrite

cn flag

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"

Score:0
gr flag

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 {
    ...
}
MrTux01 avatar
cn flag
Thanks for great explanation. How can I get rid of 500 error for css and js files?
Ivan Shatsky avatar
gr flag
Not sure if I understand your question correctly, if I am, check the update to an answer.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.