Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nginx proxy_pass based on whether request method is POST, PUT or DELETE

Tags:

I have two iKaaro instances running on port 8080 and 9080, where the 9080 instance is Read only.

I am unsure how to use nginx for example if the request method is POST, PUT, DELETE then send to write instance (8080) else send to 9080 instance.

I have done something using the location using the regex, but this is not correct.

From http://wiki.nginx.org/HttpLuaModule i see that there is the 'HTTP method constants' which can be called, so is it correct to add a location block as:

location ~* "(ngx.HTTP_POST|ngx.HTTP_DELETE|ngx.HTTP_PUT)" {     proxy_pass http://127.0.0.1:8080; 

Thanks

like image 862
khinester Avatar asked Dec 21 '11 14:12

khinester


People also ask

How does proxy_pass work Nginx?

When a URI is given in the proxy_pass definition, the portion of the request that matches the location definition is replaced by this URI during the pass. For example, a request for /match/here/please on the Nginx server will be passed to the upstream server as http://example.com/new/prefix/please .

What is Proxy_redirect Nginx?

Nginx provides proxy_redirect directive which can be used in http, server, or location context. The syntax is: proxy_redirect redirect replacement. In this example, the proxied server (upstream Apache or Lighttpd) returned line Location: http://server1.cyberciti.biz:8080/app/.


2 Answers

I just did a quick test, and this worked for me:

server {   location / {     # This proxy_pass is used for requests that don't     # match the limit_except     proxy_pass http://127.0.0.1:8080;      limit_except PUT POST DELETE {       # For requests that *aren't* a PUT, POST, or DELETE,       # pass to :9080       proxy_pass http://127.0.0.1:9080;     }   } } 
like image 81
kolbyjack Avatar answered Sep 22 '22 20:09

kolbyjack


I assume you got the basics in place. I.E., you have installed Lua 5.1, or better still, LuaJIT 2.0, on your server, compiled Nginx with the ngx_lua module and configured ngx_lua as required.

With that in place, This will do the job:

location /test {     content_by_lua '         local reqType = ngx.var.request_method         if reqType == ngx.HTTP_POST              OR reqType == ngx.HTTP_DELETE              OR reqType == ngx.HTTP_PUT          then             res = ngx.location.capture("/write_instance")         else             res = ngx.location.capture("/read_instance")         end         ngx.say(res.body)     '; } location /write_instance {     internal;     proxy_pass http://127.0.0.1:8080; } location /read_instance {     internal;     proxy_pass http://127.0.0.1:9080; } 

UPDATE

I thought perhaps you were specifically using Lua in a larger scope. The example below would also work on the same principle as limit_except.

location /test {     if ($request_method !~* GET) {         # For Write Requests         proxy_pass http://127.0.0.1:8080;     }     # For Read Requests     proxy_pass http://127.0.0.1:9080; } 

Both "if" and "limit_except" block effectively create a nested location block and once the condition matches, only the content handler ("proxy_pass") of the inner location block thus created will be executed.

Not fully getting this is why if is sometimes said to be "evil" but in this case the "evil" behaviour, common to both "if" and "limit_except", may be exactly what you want.

So three choices for you to pick from!

Note however that you will have to watch that you don't get bitten by the "evil" behaviour with either of the "if" or "limit_except" options if you need to set any other directives.

I.E., if you set a directive inside the "if" or "limit_except" block, it may not be active outside it and similarly, something set outside may be inherited inside. So you have to watch how defaults are inherited, or not, as the case may be, with both approaches.

All the potential issues listed on the If is Evil page apply equally to "if" and "limit_except" here. The Lua based scripting approach will avoid many of those potential pitfalls as suggested on that page.

Good luck!

like image 37
Dayo Avatar answered Sep 25 '22 20:09

Dayo