changeset 391:1d9bef53cd8e

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.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 21 Jul 2008 05:33:01 +0400
parents a5f67d82aea3
children 77df96611112
files auto/modules auto/sources src/http/modules/ngx_http_range_filter_module.c src/http/ngx_http_request.h
diffstat 4 files changed, 76 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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"
--- 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
 
--- 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;
+}
--- 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;