Mercurial > hg > nginx-vendor-current
diff src/http/modules/ngx_http_range_filter_module.c @ 636:943566b4d82e NGINX_1_1_2
nginx 1.1.2
*) Change: now if total size of all ranges is greater than source
response size, then nginx disables ranges and returns just the source
response.
*) Feature: the "max_ranges" directive.
*) Bugfix: the "ssl_verify_client", "ssl_verify_depth", and
"ssl_prefer_server_ciphers" directives might work incorrectly if SNI
was used.
*) Bugfix: in the "proxy/fastcgi/scgi/uwsgi_ignore_client_abort"
directives.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 05 Sep 2011 00:00:00 +0400 |
parents | 8246d8a2c2be |
children | d0f7a625f27c |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -58,8 +58,8 @@ typedef struct { } ngx_http_range_filter_ctx_t; -ngx_int_t ngx_http_range_parse(ngx_http_request_t *r, - ngx_http_range_filter_ctx_t *ctx); +static ngx_int_t ngx_http_range_parse(ngx_http_request_t *r, + ngx_http_range_filter_ctx_t *ctx, ngx_uint_t ranges); 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, @@ -146,7 +146,7 @@ static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r) { time_t if_range; - ngx_int_t rc; + ngx_http_core_loc_conf_t *clcf; ngx_http_range_filter_ctx_t *ctx; if (r->http_version < NGX_HTTP_VERSION_10 @@ -158,6 +158,12 @@ ngx_http_range_header_filter(ngx_http_re return ngx_http_next_header_filter(r); } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->max_ranges == 0) { + return ngx_http_next_header_filter(r); + } + if (r->headers_in.range == NULL || r->headers_in.range->value.len < 7 || ngx_strncasecmp(r->headers_in.range->value.data, @@ -192,10 +198,9 @@ ngx_http_range_header_filter(ngx_http_re return NGX_ERROR; } - rc = ngx_http_range_parse(r, ctx); + switch (ngx_http_range_parse(r, ctx, clcf->max_ranges)) { - if (rc == NGX_OK) { - + case NGX_OK: ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module); r->headers_out.status = NGX_HTTP_PARTIAL_CONTENT; @@ -206,16 +211,17 @@ ngx_http_range_header_filter(ngx_http_re } return ngx_http_range_multipart_header(r, ctx); - } + + case NGX_HTTP_RANGE_NOT_SATISFIABLE: + return ngx_http_range_not_satisfiable(r); - if (rc == NGX_HTTP_RANGE_NOT_SATISFIABLE) { - return ngx_http_range_not_satisfiable(r); + case NGX_ERROR: + return NGX_ERROR; + + default: /* NGX_DECLINED */ + break; } - /* rc == NGX_ERROR */ - - return rc; - next_filter: r->headers_out.accept_ranges = ngx_list_push(&r->headers_out.headers); @@ -231,15 +237,18 @@ next_filter: } -ngx_int_t -ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx) +static ngx_int_t +ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx, + ngx_uint_t ranges) { u_char *p; - off_t start, end; + off_t start, end, size, content_length; ngx_uint_t suffix; ngx_http_range_t *range; p = r->headers_in.range->value.data + 6; + size = 0; + content_length = r->headers_out.content_length_n; for ( ;; ) { start = 0; @@ -263,26 +272,11 @@ ngx_http_range_parse(ngx_http_request_t return NGX_HTTP_RANGE_NOT_SATISFIABLE; } - if (start >= r->headers_out.content_length_n) { - return NGX_HTTP_RANGE_NOT_SATISFIABLE; - } - while (*p == ' ') { p++; } if (*p == ',' || *p == '\0') { - range = ngx_array_push(&ctx->ranges); - if (range == NULL) { - return NGX_ERROR; - } - - range->start = start; - range->end = r->headers_out.content_length_n; - - if (*p++ != ',') { - return NGX_OK; - } - - continue; + end = content_length; + goto found; } } else { @@ -305,36 +299,49 @@ ngx_http_range_parse(ngx_http_request_t } if (suffix) { - start = r->headers_out.content_length_n - end; - end = r->headers_out.content_length_n - 1; + start = content_length - end; + end = content_length - 1; } - if (start > end) { - return NGX_HTTP_RANGE_NOT_SATISFIABLE; + if (end >= content_length) { + end = content_length; + + } else { + end++; } - range = ngx_array_push(&ctx->ranges); - if (range == NULL) { - return NGX_ERROR; - } + found: - range->start = start; + if (start < end) { + range = ngx_array_push(&ctx->ranges); + if (range == NULL) { + return NGX_ERROR; + } - if (end >= r->headers_out.content_length_n) { - /* - * Download Accelerator sends the last byte position - * that equals to the file length - */ - range->end = r->headers_out.content_length_n; + range->start = start; + range->end = end; - } else { - range->end = end + 1; + size += end - start; + + if (ranges-- == 0) { + return NGX_DECLINED; + } } if (*p++ != ',') { - return NGX_OK; + break; } } + + if (ctx->ranges.nelts == 0) { + return NGX_HTTP_RANGE_NOT_SATISFIABLE; + } + + if (size > content_length) { + return NGX_DECLINED; + } + + return NGX_OK; }