# HG changeset patch # User Maxim Dounin # Date 1216603981 -14400 # Node ID 1d9bef53cd8e9461c73ed537a953f3a7bae6dbd2 # Parent a5f67d82aea3939b52c5cc0cd8350923449cc1ab Range filter: late_ranges functionality. Add one more filtering point after postpone filter. This allows to serve range capable replies with subrequests. It's not as efficient as range filtering for static data (i.e. doesn't save us from reading data from disk if some filter needs them in memory), but it may save some network bandwidth for us and for our users. diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -111,6 +111,8 @@ if [ $HTTP_GZIP = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS" fi +HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_RANGE_LATE_FILTER_MODULE" + if [ $HTTP_POSTPONE = YES ]; then HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_POSTPONE_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_POSTPONE_FILTER_SRCS" diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -264,6 +264,7 @@ HTTP_HEADERS_FILTER_MODULE=ngx_http_head HTTP_RANGE_HEADER_FILTER_MODULE=ngx_http_range_header_filter_module HTTP_RANGE_BODY_FILTER_MODULE=ngx_http_range_body_filter_module +HTTP_RANGE_LATE_FILTER_MODULE=ngx_http_range_late_filter_module HTTP_NOT_MODIFIED_FILTER_MODULE=ngx_http_not_modified_filter_module diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -60,6 +60,7 @@ typedef struct { static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf); static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf); +static ngx_int_t ngx_http_range_late_filter_init(ngx_conf_t *cf); static ngx_http_module_t ngx_http_range_header_filter_module_ctx = { @@ -124,8 +125,40 @@ ngx_module_t ngx_http_range_body_filter }; +static ngx_http_module_t ngx_http_range_late_filter_module_ctx = { + NULL, /* preconfiguration */ + ngx_http_range_late_filter_init, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + NULL, /* create location configuration */ + NULL, /* merge location configuration */ +}; + + +ngx_module_t ngx_http_range_late_filter_module = { + NGX_MODULE_V1, + &ngx_http_range_late_filter_module_ctx, /* module context */ + NULL, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + static ngx_http_output_header_filter_pt ngx_http_next_header_filter; -static ngx_http_output_body_filter_pt ngx_http_next_body_filter; +static ngx_http_output_body_filter_pt ngx_http_next_body_early_filter; +static ngx_http_output_body_filter_pt ngx_http_next_body_late_filter; static ngx_int_t @@ -484,7 +517,8 @@ next_filter: static ngx_int_t -ngx_http_range_body_filter(ngx_http_request_t *r, ngx_chain_t *in) +ngx_http_range_body_generic_filter(ngx_http_request_t *r, ngx_chain_t *in, + ngx_http_output_body_filter_pt ngx_http_next_body_filter) { off_t start, last; ngx_buf_t *b, *buf; @@ -741,6 +775,30 @@ overlapped: static ngx_int_t +ngx_http_range_body_early_filter(ngx_http_request_t *r, ngx_chain_t *in) +{ + if (!r->allow_ranges || r->late_ranges) { + return ngx_http_next_body_early_filter(r, in); + } + + return ngx_http_range_body_generic_filter(r, in, + ngx_http_next_body_early_filter); +} + + +static ngx_int_t +ngx_http_range_body_late_filter(ngx_http_request_t *r, ngx_chain_t *in) +{ + if (!r->allow_ranges || !r->late_ranges) { + return ngx_http_next_body_late_filter(r, in); + } + + return ngx_http_range_body_generic_filter(r, in, + ngx_http_next_body_late_filter); +} + + +static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf) { ngx_http_next_header_filter = ngx_http_top_header_filter; @@ -753,8 +811,18 @@ ngx_http_range_header_filter_init(ngx_co static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf) { - ngx_http_next_body_filter = ngx_http_top_body_filter; - ngx_http_top_body_filter = ngx_http_range_body_filter; + ngx_http_next_body_early_filter = ngx_http_top_body_filter; + ngx_http_top_body_filter = ngx_http_range_body_early_filter; return NGX_OK; } + + +static ngx_int_t +ngx_http_range_late_filter_init(ngx_conf_t *cf) +{ + ngx_http_next_body_late_filter = ngx_http_top_body_filter; + ngx_http_top_body_filter = ngx_http_range_body_late_filter; + + return NGX_OK; +} diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -479,6 +479,7 @@ struct ngx_http_request_s { unsigned filter_need_in_memory:1; unsigned filter_need_temporary:1; unsigned allow_ranges:1; + unsigned late_ranges:1; #if (NGX_STAT_STUB) unsigned stat_reading:1;