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过滤模块,一样可以从这个例子中衍生出来。