[patch-2] Slice filter: support multiple ranges.

胡聪 (hucc) hucong.c at foxmail.com
Tue Oct 31 16:58:10 UTC 2017


Hi,

Based on RFC 7233, I recently submitted a few patches.
Any suggestion will be greatly appreciated.

Here is a better patch.

# HG changeset patch
# User hucongcong <hucong.c at foxmail.com>
# Date 1509100127 -28800
#      Fri Oct 27 18:28:47 2017 +0800
# Node ID a9abe952df0f6fc5341fea766fb6543c38c65b67
# Parent  62c100a0d42614cd46f0719c0acb0ad914594217
Slice filter: support multiple ranges.

diff -r 62c100a0d426 -r a9abe952df0f src/http/modules/ngx_http_slice_filter_module.c
--- a/src/http/modules/ngx_http_slice_filter_module.c	Fri Oct 27 18:25:40 2017 +0800
+++ b/src/http/modules/ngx_http_slice_filter_module.c	Fri Oct 27 18:28:47 2017 +0800
@@ -22,6 +22,8 @@ typedef struct {
     ngx_str_t            etag;
     unsigned             last:1;
     unsigned             active:1;
+    unsigned             multipart:1;
+    ngx_uint_t           index;
     ngx_http_request_t  *sr;
 } ngx_http_slice_ctx_t;
 
@@ -103,7 +105,9 @@ ngx_http_slice_header_filter(ngx_http_re
 {
     off_t                            end;
     ngx_int_t                        rc;
+    ngx_uint_t                       i;
     ngx_table_elt_t                 *h;
+    ngx_http_range_t                *range;
     ngx_http_slice_ctx_t            *ctx;
     ngx_http_slice_loc_conf_t       *slcf;
     ngx_http_slice_content_range_t   cr;
@@ -182,27 +186,47 @@ ngx_http_slice_header_filter(ngx_http_re
 
     r->allow_ranges = 1;
     r->subrequest_ranges = 1;
-    r->single_range = 1;
 
     rc = ngx_http_next_header_filter(r);
 
-    if (r != r->main) {
-        return rc;
+    if (r == r->main) {
+        r->preserve_body = 1;
+
+        if (r->headers_out.status == NGX_HTTP_PARTIAL_CONTENT) {
+            ctx->multipart = (r->headers_out.ranges->nelts != 1);
+            range = r->headers_out.ranges->elts;
+
+            if (ctx->start + (off_t) slcf->size <= range[0].start) {
+                ctx->start = slcf->size * (range[0].start / slcf->size);
+            }
+
+            ctx->end = range[r->headers_out.ranges->nelts - 1].end;
+
+        } else {
+            ctx->end = cr.complete_length;
+        }
     }
 
-    r->preserve_body = 1;
+    if (ctx->multipart) {
+        range = r->headers_out.ranges->elts;
+
+        for (i = ctx->index; i < r->headers_out.ranges->nelts - 1; i++) {
+
+            if (ctx->start < range[i].end) {
+                break;
+            }
 
-    if (r->headers_out.status == NGX_HTTP_PARTIAL_CONTENT) {
-        if (ctx->start + (off_t) slcf->size <= r->headers_out.content_offset) {
-            ctx->start = slcf->size
-                         * (r->headers_out.content_offset / slcf->size);
+            if (ctx->start + (off_t) slcf->size <= range[i + 1].start) {
+                i++;
+                ctx->index = i;
+                ctx->start = slcf->size * (range[i].start / slcf->size);
+
+                ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                               "range multipart so fast forward to %O-%O @%O",
+                               range[i].start, range[i].end, ctx->start);
+                break;
+            }
         }
-
-        ctx->end = r->headers_out.content_offset
-                   + r->headers_out.content_length_n;
-
-    } else {
-        ctx->end = cr.complete_length;
     }
 
     return rc;


------------------ Original ------------------
From:  "胡聪 (hucc)";<hucong.c at foxmail.com>;
Date:  Oct 27, 2017
To:  "nginx-devel"<nginx-devel at nginx.org>;
Subject:  [patch-2] Slice filter: support multiple ranges.

# HG changeset patch
# User hucongcong <hucong.c at foxmail.com>
# Date 1509100127 -28800
#      Fri Oct 27 18:28:47 2017 +0800
# Node ID 56fe1738d1b8bdfa59ecb3eb8934db6404061e47
# Parent  62c100a0d42614cd46f0719c0acb0ad914594217
Slice filter: support multiple ranges.

diff -r 62c100a0d426 -r 56fe1738d1b8 src/http/modules/ngx_http_slice_filter_module.c
--- a/src/http/modules/ngx_http_slice_filter_module.c	Fri Oct 27 18:25:40 2017 +0800
+++ b/src/http/modules/ngx_http_slice_filter_module.c	Fri Oct 27 18:28:47 2017 +0800
@@ -22,6 +22,8 @@ typedef struct {
     ngx_str_t            etag;
     unsigned             last:1;
     unsigned             active:1;
+    unsigned             multipart:1;
+    ngx_uint_t           index;
     ngx_http_request_t  *sr;
 } ngx_http_slice_ctx_t;
 
@@ -103,7 +105,9 @@ ngx_http_slice_header_filter(ngx_http_re
 {
     off_t                            end;
     ngx_int_t                        rc;
+    ngx_uint_t                       i;
     ngx_table_elt_t                 *h;
+    ngx_http_range_t                *range;
     ngx_http_slice_ctx_t            *ctx;
     ngx_http_slice_loc_conf_t       *slcf;
     ngx_http_slice_content_range_t   cr;
@@ -182,27 +186,48 @@ ngx_http_slice_header_filter(ngx_http_re
 
     r->allow_ranges = 1;
     r->subrequest_ranges = 1;
-    r->single_range = 1;
 
     rc = ngx_http_next_header_filter(r);
 
-    if (r != r->main) {
-        return rc;
+    if (r == r->main) {
+        r->preserve_body = 1;
+
+        if (r->headers_out.status == NGX_HTTP_PARTIAL_CONTENT) {
+            ctx->multipart = (r->headers_out.ranges->nelts != 1);
+            range = r->headers_out.ranges->elts;
+
+            if (ctx->start + (off_t) slcf->size <= range[0].start) {
+                ctx->start = slcf->size * (range[0].start / slcf->size);
+            }
+
+            ctx->end = range[r->headers_out.ranges->nelts - 1].end;
+
+        } else {
+            ctx->end = cr.complete_length;
+        }
     }
 
-    r->preserve_body = 1;
+    if (ctx->multipart) {
+        end = ctx->start + (off_t) slcf->size - 1;
+
+        range = r->headers_out.ranges->elts;
+        for (i = ctx->index; i < r->headers_out.ranges->nelts - 1; i++) {
+
+            if (end < range[i].end) {
+                break;
+            }
 
-    if (r->headers_out.status == NGX_HTTP_PARTIAL_CONTENT) {
-        if (ctx->start + (off_t) slcf->size <= r->headers_out.content_offset) {
-            ctx->start = slcf->size
-                         * (r->headers_out.content_offset / slcf->size);
+            if (end < range[i + 1].start && ctx->start >= range[i].end) {
+                i++;
+                ctx->index = i;
+                ctx->start = slcf->size * (range[i].start / slcf->size);
+
+                ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                               "range multipart so fast forward to %O-%O @%O",
+                               range[i].start, range[i].end, ctx->start);
+                break;
+            }
         }
-
-        ctx->end = r->headers_out.content_offset
-                   + r->headers_out.content_length_n;
-
-    } else {
-        ctx->end = cr.complete_length;
     }
 
     return rc;
_______________________________________________
nginx-devel mailing list
nginx-devel at nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


More information about the nginx-devel mailing list