nginx:在PostgreSQL中存储POST数据

时间:2019-03-27 14:56:39

标签: postgresql rest nginx openresty

nginx服务器使用PostgreSQL实例作为后端,提供了一个简单的REST接口。 Nginx应该将POST数据(已经以JSON格式)插入数据库表中。不幸的是,包含POST数据的$request_body仅由nginx填充在fastcgi_passproxy_pass,...

ngx_form_input也不起作用,因为它期望键值格式的POST数据。我尝试了ngx_echo,但这会导致内部服务器错误:

location ~ "^/api/v1/dummy/$" {
    auth_basic              "Restricted";
    auth_basic_user_file    /usr/local/etc/nginx/.htpasswd;

    if ($request_method != POST) {
        return 405;
    }

    client_max_body_size    100k;
    client_body_buffer_size 100k;

    echo_read_request_body;

    postgres_pass       postgresql;
    postgres_escape     $json =$request_body;

    postgres_query      POST "INSERT INTO mytable (data) VALUES ('$json')";
    postgres_rewrite    POST changes    201;
    postgres_rewrite    POST no_changes 204;
}

似乎ngx_echo无法与ngx_postgres一起使用。还有其他方法可以获取请求正文数据吗?

2 个答案:

答案 0 :(得分:1)

echo_read_request_bodypostgres_pass指令均在内容阶段起作用。 在这种情况下,只有一个模块可以工作。

这里的问题是nginx本质上是异步的。 Nginx可能会在接收到完整的请求正文之前启动

使用OpenResty,您可以通过lua_need_request_body强制nginx读取整个请求正文。 请注意client_body_buffer_sizeclient_max_body_size。 包括空的rewrite_by_lua*

另一种可能的解决方案是例如在set_by_lua_block中编写Lua代码并读取完整的请求正文,请记住,它可能已被缓冲到文件中,请使用ngx.req.get_body_file进行检查。 / p>

答案 1 :(得分:0)

我同意亚历山大·阿尔舒勒(Alexander Altshuler)的观点。 Nginx不支持在运行postgres_escape指令的重写阶段捕获request_body。

我已经在我的GitHub分支capture-request-body中修改了ngx_postgres模块。但是我的请求请求不太可能被接受。

此分支添加了POST请求捕获功能。 您可以将请求保存到PostgreSQL数据库,例如,在此分支中使用这样的配置

location /dlr/sms
{
    allow all;
    postgres_escape_request_body on;
    postgres_pass     database;
    postgres_query    POST      "SELECT table2sms.treat_sms_dlr('$request_body')";
    postgres_rewrite  POST      changes 200;
    postgres_rewrite  POST      no_changes 400;
    postgres_output   value;
}