Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2008-07-29 17:58:13 +0400
committerIgor Sysoev <igor@sysoev.ru>2008-07-29 17:58:13 +0400
commit4a1b0329019e19079eae073089c55ed533c74931 (patch)
treed3fce2f7341dd47db01d72b759615e50f8e04e19 /src
parent96eaa05fd2523995f95d7410d5d8a48f76e5bca1 (diff)
support several buf's for single-part range
patch by Maxim Dounin
Diffstat (limited to 'src')
-rw-r--r--src/http/modules/ngx_http_range_filter_module.c92
1 files changed, 73 insertions, 19 deletions
diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c
index e8134d164..377ca9b28 100644
--- a/src/http/modules/ngx_http_range_filter_module.c
+++ b/src/http/modules/ngx_http_range_filter_module.c
@@ -64,13 +64,13 @@ static ngx_int_t ngx_http_range_singlepart_header(ngx_http_request_t *r,
ngx_http_range_filter_ctx_t *ctx);
static ngx_int_t ngx_http_range_multipart_header(ngx_http_request_t *r,
ngx_http_range_filter_ctx_t *ctx);
+static ngx_int_t ngx_http_range_not_satisfiable(ngx_http_request_t *r);
static ngx_int_t ngx_http_range_test_overlapped(ngx_http_request_t *r,
ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
static ngx_int_t ngx_http_range_singlepart_body(ngx_http_request_t *r,
ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
static ngx_int_t ngx_http_range_multipart_body(ngx_http_request_t *r,
ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
-static ngx_int_t ngx_http_range_not_satisfiable(ngx_http_request_t *r);
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);
@@ -551,6 +551,14 @@ ngx_http_range_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
return ngx_http_next_body_filter(r, in);
}
+ if (ctx->ranges.nelts == 1) {
+ return ngx_http_range_singlepart_body(r, ctx, in);
+ }
+
+ /*
+ * multipart ranges are supported only if whole body is in a single buffer
+ */
+
if (ngx_buf_special(in->buf)) {
return ngx_http_next_body_filter(r, in);
}
@@ -559,16 +567,6 @@ ngx_http_range_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
return NGX_ERROR;
}
- if (ctx->ranges.nelts == 1) {
-
- /*
- * the optimized version for the responses
- * that are passed in the single buffer
- */
-
- return ngx_http_range_singlepart_body(r, ctx, in);
- }
-
return ngx_http_range_multipart_body(r, ctx, in);
}
@@ -624,23 +622,79 @@ static ngx_int_t
ngx_http_range_singlepart_body(ngx_http_request_t *r,
ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in)
{
+ off_t start, last;
ngx_buf_t *buf;
+ ngx_chain_t *out, *cl, **ll;
ngx_http_range_t *range;
- buf = in->buf;
+ out = NULL;
+ ll = &out;
range = ctx->ranges.elts;
- if (buf->in_file) {
- buf->file_pos = range->start;
- buf->file_last = range->end;
+ for (cl = in; cl; cl = cl->next) {
+
+ buf = cl->buf;
+
+ start = ctx->offset;
+ last = ctx->offset + ngx_buf_size(buf);
+
+ ctx->offset = last;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http range body buf: %O-%O", start, last);
+
+ if (ngx_buf_special(buf)) {
+ *ll = cl;
+ ll = &cl->next;
+ continue;
+ }
+
+ if (range->end <= start || range->start >= last) {
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http range body skip");
+
+ buf->pos = buf->last;
+ continue;
+ }
+
+ if (range->start > start) {
+
+ if (buf->in_file) {
+ buf->file_pos += range->start - start;
+ }
+
+ if (ngx_buf_in_memory(buf)) {
+ buf->pos += (size_t) (range->start - start);
+ }
+ }
+
+ if (range->end <= last) {
+
+ if (buf->in_file) {
+ buf->file_last -= last - range->end;
+ }
+
+ if (ngx_buf_in_memory(buf)) {
+ buf->last -= (size_t) (last - range->end);
+ }
+
+ buf->last_buf = 1;
+ *ll = cl;
+ cl->next = NULL;
+
+ break;
+ }
+
+ *ll = cl;
+ ll = &cl->next;
}
- if (ngx_buf_in_memory(buf)) {
- buf->pos = buf->start + (size_t) range->start;
- buf->last = buf->start + (size_t) range->end;
+ if (out == NULL) {
+ return NGX_OK;
}
- return ngx_http_next_body_filter(r, in);
+ return ngx_http_next_body_filter(r, out);
}