FRiCKLE / ngx_postgres

upstream module that allows nginx to communicate directly with PostgreSQL database.
http://labs.frickle.com/nginx_ngx_postgres/
BSD 2-Clause "Simplified" License
545 stars 122 forks source link

Document postgres_set functionality in control flow #15

Open Downchuck opened 11 years ago

Downchuck commented 11 years ago

The eval module has been deprecated, "production use is discouraged"; is the postgres_set feature usable at all in the nginx control flow? There does not seem to be a means of passing the value of postgres_set into an if statement, redirect or error page; the value seems to be opaque until sending it to the client.

agentzh commented 11 years ago

You're recommended to use the ngx_lua module with ngx_postgres, which supports all the magic of ngx_eval (and much more!) and is considered stable for long: http://wiki.nginx.org/HttpLuaModule

PiotrSikora commented 11 years ago

You can use it with ngx_lua (http://wiki.nginx.org/HttpLuaModule), ngx_http_auth_request_module (http://mdounin.ru/hg/ngx_http_auth_request_module/) or anything else that uses subrequests.

You cannot use it as a conditional in an if statement (without using subrequests), because if statements are evaluated at the rewrite phase, long time before SQL query is actually sent to the database.

Downchuck commented 11 years ago

Does that include postgres_rewrite? I'm currently using postgres_rewrite + error_page; not currently using postgres_set.

PiotrSikora commented 11 years ago

What are you trying to do?

Downchuck commented 11 years ago

I'm currently just using "select true from table where" for authentication before passing over to the push stream module. I'd like to select a value from the table to check if the user should be redirect to another server.

This is working well: postgres_rewrite rows 410; postgres_rewrite no_rows 403; error_page 410 = /json/subscribe?$args;

At this point, I'm checking if this will work: postgres_set $value 0 0 optional; error_page 410 = /json/subscribe?value=$value&$args;

PiotrSikora commented 11 years ago

I'd recommend using either auth request module or ngx_lua's access_by_lua to do that, i.e.:

location = /auth {
    internal;

    postgres_escape   $user $remote_user;
    postgres_escape   $pass $remote_passwd;

    postgres_pass     database;
    postgres_query    "SELECT optional FROM users WHERE login=$user AND pass=$pass";
    postgres_rewrite  no_rows 403;
    postgres_output   none;
    postgres_set      $postgres_optional 0 0 required;
}

location / {
    auth_request /auth;
    auth_request_set $optional $postgres_optional;

    if ($optional != "") {
        # do something
    }

    # do something else
}