6.4.6 处理请求中的HTTP包体
根据图6-3中描述的处理流程看,ngx_http_myfilter_body_filter回调方法的实现应如下所示。
static ngx_int_t
ngx_http_myfilter_body_filter(ngx_http_request_tr,ngx_chain_tin)
{
ngx_http_myfilter_ctx_t*ctx;
ctx=ngx_http_get_module_ctx(r,ngx_http_myfilter_module);
/如果获取不到上下文,或者上下文结构体中的add_prefix为0或者2时,都不会添加前缀,这时直接交给下一个HTTP过滤模块处理/
if(ctx==NULL||ctx->add_prefix!=1){
return ngx_http_next_body_filter(r,in);
}
/将add_prefix设置为2,这样即使ngx_http_myfilter_body_filter再次回调时,也不会重复添加前缀/
ctx->add_prefix=2;
//从请求的内存池中分配内存,用于存储字符串前缀
ngx_buf_t*b=ngx_create_temp_buf(r->pool,filter_prefix.len);
//将ngx_buf_t中的指针正确地指向filter_prefix字符串
b->start=b->pos=filter_prefix.data;
b->last=b->pos+filter_prefix.len;
/从请求的内存池中生成ngx_chain_t链表,将刚分配的ngx_buf_t设置到buf成员中,并将它添加到原先待发送的HTTP包体前面/
ngx_chain_t*cl=ngx_alloc_chain_link(r->pool);
cl->buf=b;
cl->next=in;
//调用下一个模块的HTTP包体处理方法,注意,这时传入的是新生成的cl链表
return ngx_http_next_body_filter(r,cl);
}
到此,一个简单的HTTP过滤模块就开发完成了。无论功能多么复杂的HTTP过滤模块,一样可以从这个例子中衍生出来。