How to pass HTTP POST vars through to postgres_query

546 views
Skip to first unread message

Eugene Ware

unread,
Sep 14, 2013, 6:57:40 AM9/14/13
to openre...@googlegroups.com
Hi, I've just discovered openresty through the following blog post:


The example given shows you to query postgres using GET query parameters.

I wish to do the same thing as the example, but also pass through HTTP POST parameters.

I've managed to get access to the POST variables in lua, but I can't work out how to pass them through to the postgres_query function.

When I do just lua code (using content_by_lua) everything is fine. But trying to get out HTTP POST variables in LUA while also using the postgres_ handlers throws 500 errors.

Are you able to provide an example of passing through HTTP POST variables to postgres_query? Thanks in advance.

Cheers,

Eugene

Yichun Zhang (agentzh)

unread,
Sep 14, 2013, 3:52:54 PM9/14/13
to openresty-en
Hello!

On Sat, Sep 14, 2013 at 3:57 AM, Eugene Ware wrote:
> I wish to do the same thing as the example, but also pass through HTTP POST
> parameters.
>
> I've managed to get access to the POST variables in lua, but I can't work
> out how to pass them through to the postgres_query function.
>
[...]
>
> Are you able to provide an example of passing through HTTP POST variables to
> postgres_query? Thanks in advance.
>

In short, you should use rewrite_by_lua instead of content_by_lua
here, because content_by_lua conflicts with postgres_pass in a single
nginx location block (both of them correspond to a content handler
while a single location can only have one content handler).

Below is a tested example to demonstrate this usage:

location = /t {
# The following two directives should take the same value
# so that nginx will always buffer the whole request body
# in memory:
client_body_buffer_size 8k;
client_max_body_size 8k;

set $quoted_id '';
rewrite_by_lua '
ngx.req.read_body()
local args = ngx.req.get_post_args()
local id = args.id
if not id then
ngx.status = 400
ngx.say("ERROR: No id specified.")
return ngx.exit(400)
end

-- you need to install the ngx_set_misc module for the following
-- line of code:
ngx.var.quoted_id = ndk.set_var.set_quote_pgsql_str(id)
';
postgres_query 'select * from cats where id = $quoted_id';
postgres_pass backend;
postgres_output rds;
rds_json on;
}

Here're the test results on my side (assuming the Nginx listens on the
8080 port):

$ curl -i -d 'id=3' localhost:8080/t
HTTP/1.1 200 OK
Server: nginx/1.4.2
Date: Sat, 14 Sep 2013 19:48:07 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive

[{"id":3,"name":"bob"}]

$ curl -i -d 'id=2' localhost:8080/t
HTTP/1.1 200 OK
Server: nginx/1.4.2
Date: Sat, 14 Sep 2013 19:48:40 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive

[{"id":2,"name":null}]

$ curl -i -d 'foo=2' localhost:8080/t
HTTP/1.1 400 Bad Request
Server: nginx/1.4.2
Date: Sat, 14 Sep 2013 19:49:19 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive

ERROR: No id specified.

Here I'm using curl's -d option to specify the POST request body on
the command line.

Please note that you need to install at least 4 modules to your Nginx:
ngx_lua, ngx_set_misc, ngx_postgres, and ngx_rds_json. If you're using
the openresty bundle, then you can have all these at once :)

Best regards,
-agentzh

Eugene Ware

unread,
Sep 15, 2013, 2:55:39 AM9/15/13
to openre...@googlegroups.com
Thanks so much for the quick and detailed response!

I worked out how to do it with set_form_input as well. Are there any tradeoffs compared with your proposed approach?:

location /articles {
      set_form_input $post_title title;
      set_unescape_uri $ue_title $post_title;
      postgres_escape $title $ue_title;

      set_form_input $post_body body;
      set_unescape_uri $ue_body $post_body;
      postgres_escape $body  $ue_body;

      set_form_input $post_data data;
      set_unescape_uri $ue_data $post_data;
      postgres_escape $data  $ue_data;

      postgres_pass database;
      rds_json on;
      postgres_query    HEAD GET  "SELECT * FROM articles";

      postgres_query
        POST "INSERT INTO articles (title, body, data) VALUES($title, $body, $data) RETURNING *";
      postgres_rewrite  POST changes 201;
    }



--
You received this message because you are subscribed to a topic in the Google Groups "openresty-en" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/openresty-en/auaaefMbn1Y/unsubscribe.
To unsubscribe from this group and all its topics, send an email to openresty-en...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--

Eugene Ware
Chief Executive Officer

Phone: +61 3 9955 7041
Email: eug...@noblesamurai.com
Twitter: @EugeneWare

Noble Samurai Pty Ltd
Level 1, 234 Whitehorse Rd
Nunawading, Victoria, 3131, Australia

Yichun Zhang (agentzh)

unread,
Sep 15, 2013, 3:01:13 AM9/15/13
to openresty-en
Hello!

On Sat, Sep 14, 2013 at 11:55 PM, Eugene Ware wrote:
>
> Thanks so much for the quick and detailed response!
>
> I worked out how to do it with set_form_input as well. Are there any tradeoffs compared with your proposed approach?:
>

Well, you could use ngx_form_input for this but I would recommend
ngx_lua because you have much more control over error handling and etc
(keep in mind that "if" is evil :)).

Also ensure that you configure client_body_buffer_size to the same
value of client_max_body_size, otherwise you need to handle (large)
in-file request bodies yourself.

Regards,
-agentzh

Eugene Ware

unread,
Sep 16, 2013, 10:10:07 AM9/16/13
to openre...@googlegroups.com
Great. Thanks for much for the clarification, and thanks so much for your great work with openresty!



Regards,
-agentzh

--
You received this message because you are subscribed to a topic in the Google Groups "openresty-en" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/openresty-en/auaaefMbn1Y/unsubscribe.
To unsubscribe from this group and all its topics, send an email to openresty-en...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages