nginx服务器使用PostgreSQL实例作为后端,提供了一个简单的REST接口。 Nginx应该将POST数据(已经以JSON格式)插入数据库表中。不幸的是,包含POST数据的$request_body
仅由nginx填充在fastcgi_pass
,proxy_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一起使用。还有其他方法可以获取请求正文数据吗?
答案 0 :(得分:1)
echo_read_request_body
和postgres_pass
指令均在内容阶段起作用。
在这种情况下,只有一个模块可以工作。
这里的问题是nginx本质上是异步的。 Nginx可能会在接收到完整的请求正文之前启动。
使用OpenResty,您可以通过lua_need_request_body强制nginx读取整个请求正文。
请注意client_body_buffer_size
和client_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;
}