nginx:在PostgreSQL中存储POST数据

一个nginx服务器提供一个简单的REST接口,使用PostgreSQL实例作为后端。nginx应该将POST数据(已经是JSON格式)插入到数据库表中。不幸的是,$request_body包含POST数据仅由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;

 如果($request_method!= POST){
返回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不兼容。有其他方法可以获得请求体数据吗?

点赞
用户2060502
用户2060502

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来检查它。

2019-03-29 13:24:28
用户11815747
用户11815747

我同意Alexander Altshuler的观点。在postgres_escape命令运行的重写阶段中,Nginx不支持捕获请求体。

我已经在我的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;
}
2020-10-18 15:03:20