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
544 stars 123 forks source link

echo_read_request_body doesn't populate $request_body in postgres_query #32

Closed michelp closed 9 years ago

michelp commented 9 years ago

Hi,

We have the following config:

    location = "/foo" {                                                                                                                                                                                         
        echo_read_request_body;                                                                                                                                                                                 
        echo $request_body;                                                                                                                                                                                     
    }                                                                                                                                                                                                           

    location ~ "/(?<db>\w+)/(?<schema>\w+)/(?<function>\w+)(?<path>/.*){0,}$" {                                                                                                                                 
        echo_read_request_body;                                                                                                                                                                                 
        postgres_escape $user $remote_user;                                                                                                                                                                     
        postgres_output text;                                                                                                                                                                                   
        postgres_pass $db;                                                                                                                                                                                      
        postgres_query POST "SELECT * FROM http.post('$schema', '$function', '$path', '$user', '$request_body')";                                                                                               
        postgres_query HEAD GET "SELECT * FROM http.get('$schema', '$function', '$path', '$user')";                                                                                                             
    }   

POSTing to /foo works fine (the request body is correctly echoed) but POSTing to any urls that match the other location, $request_body is always an empty string. Otherwise the module works perfectly and we are very happy with it. We have been considering switching to a lua content block to get what we want as a workaround, but we'd rather keep it simple.

Thanks so much for your excellent module!

agentzh commented 9 years ago

@michelp Both echo_read_request_body and postgres_pass run in a content handler registered by their corresponding nginx C module (ngx_echo and ngx_postgres), respectively. But for a single nginx location, there can only be one nginx module's content handler running.

Maybe you should try the following instead?

access_by_lua 'ngx.req.read_body()';

This will trigger reading the request body at nginx's "access phase", which is before the "content phase" where postgres_pass is running. The access_by_lua directive is from the ngx_lua module, BTW.

michelp commented 9 years ago

It works! Thank you so much for the detailed explanation as well.

fridjon commented 7 years ago

I am having the same problem (bit of a nginx newbie) I want to store the $request_body in a postgres table.

Do I have to add the ngx_lua module or can I somehow solve this by reading the request body in the server config ... ?

agentzh commented 7 years ago

@fridjon It's recommended to use the ngx_lua module, or even better, OpenResty, for this.

fridjon commented 7 years ago

@agentzh Thanks, I am actually beginning to like lua very much. You can actually do a lot of performance critical things in a very smooth and nice way :) I will take a look at OpenResty.

agentzh commented 7 years ago

@fridjon Awesome! Please make sure you join the openresty-en mailing list to connect to us and our community :)