nginx:在 PostgreSQL 中存储 POST 数据

nginx: Storing POST data in PostgreSQL

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

上由 nginx 填充

ngx_form_input doesn’t help either, as it expects the POST data in key-value format. I tried 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 好像不能一起使用。还有其他方法可以获取请求体数据吗?

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

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

使用 OpenResty 你可以通过 lua_need_request_body 强制 nginx 读取整个请求体。 注意 client_body_buffer_sizeclient_max_body_size。 包括空 rewrite_by_lua*.

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

我同意 Alexander Altshuler 的观点。 Nginx 不支持在 postgres_escape 指令为 运行.

的重写阶段捕获 request_body

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

该分支添加了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;
}