5.2.6 input_filter_init与input_filter回调方法

input_filter_init与input_filter这两个方法都用于处理上游的响应包体,因为处理包体前HTTP模块可能需要做一些初始化工作。例如,分配一些内存用于存放解析的中间状态等,这时upstream就提供了input_filter_init方法。而input_filter方法就是实际处理包体的方法。这两个回调方法都可以选择不予实现,这是因为当这两个方法不实现时,upstream模块会自动设置它们为预置方法(上文讲过,由于upstream有3种处理包体的方式,所以upstream模块准备了3对input_filter_init、input_filter方法)。因此,一旦试图重定义input_filter_init、input_filter方法,就意味着我们对upstream模块的默认实现是不满意的,所以才要重定义该功能。此时,首先必须要弄清楚默认的input_filter方法到底做了什么,在12.6节~12.8节介绍的3种处理包体方式中,都会涉及默认的input_filter方法所做的工作。

在多数情况下,会在以下场景决定重新实现input_filter方法。

(1)在转发上游响应到下游的同时,需要做一些特殊处理

例如,ngx_http_memcached_module模块会将实际由memcached实现的上游服务器返回的响应包体,转发到下游的HTTP客户端上。在上述过程中,该模块通过重定义了的input_filter方法来检测memcached协议下包体的结束,而不是完全、纯粹地透传TCP流。

(2)当无须在上、下游间转发响应时,并不想等待接收完全部的上游响应后才开始处理请求

在不转发响应时,通常会将响应包体存放在内存中解析,如果试图接收到完整的响应后再来解析,由于响应可能会非常大,这会占用大量内存。而重定义了input_filter方法后,可以每解析完一部分包体,就释放一些内存。

重定义input_filter方法必须符合一些规则,如怎样取到刚接收到的包体以及如何释放缓冲区使得固定大小的内存缓冲区可以重复使用等。注意,本章的例子并不涉及input_filter方法,读者可以在第12章中找到input_filter方法的使用方式。