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

后端 未结 4 829
春和景丽
春和景丽 2020-12-23 10:36

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 PO

相关标签:
4条回答
  • 2020-12-23 11:09

    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;
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-23 11:16

    I'd recommend the nginx map function. This goes outside of your location block:

    map $request_method $destination {
        default 8080;
        PUT 9080;
        POST 9080;
        DELETE 9080;
    }
    

    Then in your location block:

    proxy_pass http://127.0.0.1:$destination
    

    This is all regexes too, so you can do things like:

    map $request_method $cookie_auth $destination {
        default 8080;
        "^POST " 9080;
        "^PUT someAuthCookieValue" 9080;
    }
    

    Plus this avoids the use of if at all. It's pretty awesome. I used it to direct all write traffic in a WordPress cluster to one FastCGI TCP socket on a remote node but send read traffic to a local FastCGI UNIX socket.

    0 讨论(0)
  • 2020-12-23 11:21

    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!

    0 讨论(0)
  • 2020-12-23 11:22

    In case someone looking for a way to simply make conditions by request method, the syntax is:

    if ($request_method = DELETE ) {
       . . . 
    }
    
    0 讨论(0)
提交回复
热议问题