nginx模块:捕获整个响应体
尽管Nginx是一款非常有趣的软件,但缺少文档让我抓狂 目标:捕获整个响应主体,该主体将被记录到服务器上 问题:我总是有一个大小为零的缓冲区 方法 我希望能够使用一个,在迭代整个缓冲区链之前“等待”最后一个buf来完成这个需求nginx模块:捕获整个响应体,nginx,filter,module,buffer,Nginx,Filter,Module,Buffer,尽管Nginx是一款非常有趣的软件,但缺少文档让我抓狂 目标:捕获整个响应主体,该主体将被记录到服务器上 问题:我总是有一个大小为零的缓冲区 方法 我希望能够使用一个,在迭代整个缓冲区链之前“等待”最后一个buf来完成这个需求 /** * @param ngx_http_request_t *r HTTP request * @param ngx_chain_t *in Buffer chain */ static ngx_int_t c
/**
* @param ngx_http_request_t *r HTTP request
* @param ngx_chain_t *in Buffer chain
*/
static ngx_int_t
create_response_snapshot(ngx_http_request_t *r, ngx_chain_t *in)
{
ngx_chain_t *chain = NULL;
int chain_contains_last_buffer = 0;
size_t buffer_size = 0;
// check if body is complete
chain = in;
for ( ; ; )
{
if (chain->buf->last_buf)
{
chain_contains_last_buffer = 1;
}
if (NULL == chain->next)
break;
chain = chain->next;
}
if (0 == chain_contains_last_buffer)
{
// response is not complete
return ngx_http_next_body_filter(r, in);
}
// Response Content-Length
ngx_log_error(NGX_LOG_ALERT,r->connection->log,0,"Content-Length: %d",
r->headers_out.content_length_n);
// lets iterate buffers chain
for (chain = in; NULL != chain; chain = chain->next)
{
buffer_size = ngx_buf_size(chain->buf);
ngx_log_error(NGX_LOG_ALERT,r->connection->log,0,"buffer_size#%d",buffer_size);
}
return ngx_http_next_body_filter(r, in);
}
我的评论太大了,不能作为评论,但我觉得这不是一个正确的答案——哦,好吧 要重新迭代,您发布的代码的问题是,不会在整个链上同时调用模块的body filter函数。它在第一个片段上被调用,然后在第二个片段上被调用,直到第n个片段。最后,它会在一个完全空的链上被调用,无论出于什么原因,
last\u buf=1
的buf总是自己空的
因此,我认为您要做的是通过在模块中累积缓冲区来“拦截”缓冲区流,而不向下一个过滤器释放任何缓冲区,直到您同时拥有所有缓冲区
查看替代过滤器模块:
它使用了一个“忙”链,这正是我所指的。据我所知,它使用它来跟踪实际发送了哪些缓冲区(当这种情况发生时,大小设置为零),并将这些缓冲区添加到模块上下文的空闲列表中以供重用。有关此行为,请参阅第438行的ngx_http_sub_输出
我的建议是做一些类似于模块所做的事情,除了在获得整个页面之前不调用下一个过滤器。如果要将整个页面作为一个整体进行处理,则不能调用next_filter,因为这样做将导致数据被发送到客户端。同样,这与Nginx的设计背道而驰,因此我认为,如果可以的话,您应该找到一种不需要立即提交整个响应正文的替代方案。缺少文档也让我抓狂!我找到的唯一指南(Evan Miller的)并没有开始解释大多数
ngx_,而是成员的目的。我认为在这种情况下,您需要不断将in
链添加到模块上下文的busy
成员中,直到获得最后一个buf。这是因为你的过滤器被调用了很多次,包含last\u buf
的过滤器是最后一个调用,它总是与我所看到的内容相隔离。哦,如果你没有得到最后一个链,你可能会返回NGX\u OK
而不是调用NGX\u http\u next\u body\u filter
。然后将整个链条一次传递到其余的过滤器。基本上,您正在删除Nginx以块的形式处理输出的功能,这有点违背了这一点。@GVH“我认为在这种情况下,您需要继续将in-chain添加到模块上下文的繁忙成员中,直到获得最后一个buf”。你能解释一下“忙碌的成员”吗。我不知道它应该是什么。关于返回“NGX_OK”,根据Evan Miler的教程,每个过滤器负责调用下一个过滤器。我将深入研究其他模块。