Aarti
Aarti

Reputation: 765

How to change request parameters before passing request to nginx reverse proxy server

I am using Nginx to proxy request to some backend server. For this, i am using proxy_pass module to redirect. Config file: location = /hello { proxy_pass: abc.com }

I want to execute the following workflow. Request to nginx server --> change request parameters --> pass the request to abc.com --> change the response parameters --> send response back to client.

Is this possible with nginx ? Any help/pointers to this problem would be appreciated.

Upvotes: 1

Views: 5616

Answers (1)

curtwphillips
curtwphillips

Reputation: 5811

You should be able to change/set new parameters with this

location /hello {
  proxy_pass: abc.com 
  if ($args ~* paramToChange=(.+)) {
    set $args newParamName=$1;
  }
  set $args otherParam=value;
}

Update:

There is not a way in nginx out of the box to make a request to get params dynamically then apply them to another request before sending the client response.

You can do this by adding a module to nginx called lua.

This module can be recompiled into nginx by downloading it and adding it in the .configure options during installation. Also I like the openresty bundle that comes with it and other useful modules already available, like echo.

Once you have the lua module this server code will work:

server {
    listen 8083;

    location /proxy/one {
        proxy_set_header testheader test1;
        proxy_pass http://localhost:8081;
    }

    location /proxy/two {
       proxy_pass http://localhost:8082;
    }

    location / {
        default_type text/html; 

        content_by_lua '
            local first = ngx.location.capture("/proxy/one",
               { args = { test = "test" } }
            )

            local testArg = first.body

            local second = ngx.location.capture("/proxy/two",
               { args = { test = testArg } }
            )

            ngx.print(second.body)
        ';

    }
}

I tested this configuration with a couple of node js servers like this:

var koa = require('koa');
var http = require('http');

startServerOne();
startServerTwo();

function startServerOne() {
  var app = koa();


  app.use(function *(next){
    console.log('\n------ Server One ------');
    console.log('this.request.headers.testheader: ' + JSON.stringify(this.request.headers.testheader));
    console.log('this.request.query: ' + JSON.stringify(this.request.query));

    if (this.request.query.test == 'test') {
      this.body = 'First query worked!';
    }else{
      this.body = 'this.request.query: ' + JSON.stringify(this.request.query);
    }  
  });

  http.createServer(app.callback()).listen(8081);

  console.log('Server 1 - 8081');
}

function startServerTwo(){
  var app = koa();
  app.use(function *(next){

    console.log('\n------ Server Two ------');
    console.log('this.request.query: ' + JSON.stringify(this.request.query));

    if (this.request.query.test == 'First query worked!') {
      this.body = 'It Worked!';
    }else{
      this.body = 'this.request.query: ' + JSON.stringify(this.request.query);
    }
  });

  http.createServer(app.callback()).listen(8082);

  console.log('Server 2 - 8082');
}

This was the output from the node console logs:

Server 1 - 8081
Server 2 - 8082

------ Server One ------
this.request.headers.testheader: "test1"
this.request.query: {"test":"test"}

------ Server Two ------
this.request.query: {"test":"First query worked!"}

Here's what happens:

  1. Nginx sends server one a request query with the test parameter set.

  2. Node server 1 sees the test parameter and responds with 'First query worked!'.

  3. Nginx updates the query parameters with the body from the server one response. Nginx sends server two a request with the new query parameters.

  4. Node server 2 sees that the 'test' query parameter equals 'First query worked!' and responds to the request with response body 'It Worked!'.

And the curl response or visiting localhost:8083 in a browser shows 'It worked':

curl -i 'http://localhost:8083'
HTTP/1.1 200 OK
Server: openresty/1.9.3.2
Date: Thu, 17 Dec 2015 16:57:45 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive

It Worked!

Upvotes: 1

Related Questions