# HG changeset patch # User Igor Sysoev # Date 1084340275 0 # Node ID af451db3fe99e2aa85c47e708f61afc55c098ca1 # Parent be40e9893a196b9e6bd9637aa81b2dbf0bd33e4a nginx-0.0.3-2004-05-12-09:37:55 import diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -43,7 +43,7 @@ fi HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES \ $HTTP_CHUNKED_FILTER_MODULE \ - $HTTP_RANGE_FILTER_MODULE \ + $HTTP_RANGE_HEADER_FILTER_MODULE \ $HTTP_CHARSET_FILTER_MODULE" HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE $HTTP_INDEX_MODULE" @@ -80,6 +80,8 @@ fi modules="$CORE_MODULES $EVENT_MODULES $HTTP_MODULES $HTTP_FILTER_MODULES \ $HTTP_HEADERS_FILTER_MODULE \ + $HTTP_COPY_FILTER_MODULE \ + $HTTP_RANGE_BODY_FILTER_MODULE \ $HTTP_NOT_MODIFIED_FILTER_MODULE" diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -173,13 +173,16 @@ HTTP_MODULES="ngx_http_module \ HTTP_FILE_CACHE_MODULE=ngx_http_cache_module HTTP_FILTER_MODULES="ngx_http_write_filter_module \ - ngx_http_output_filter_module \ ngx_http_header_filter_module" HTTP_CHUNKED_FILTER_MODULE=ngx_http_chunked_filter_module -HTTP_RANGE_FILTER_MODULE=ngx_http_range_filter_module HTTP_CHARSET_FILTER_MODULE=ngx_http_charset_filter_module HTTP_HEADERS_FILTER_MODULE=ngx_http_headers_filter_module +HTTP_COPY_FILTER_MODULE=ngx_http_copy_filter_module + +HTTP_RANGE_HEADER_FILTER_MODULE=ngx_http_range_header_filter_module +HTTP_RANGE_BODY_FILTER_MODULE=ngx_http_range_body_filter_module + HTTP_NOT_MODIFIED_FILTER_MODULE=ngx_http_not_modified_filter_module HTTP_STATIC_MODULE=ngx_http_static_module @@ -204,7 +207,7 @@ HTTP_SRCS="src/http/ngx_http.c \ src/http/ngx_http_headers.c \ src/http/ngx_http_header_filter.c \ src/http/ngx_http_write_filter.c \ - src/http/ngx_http_output_filter.c \ + src/http/ngx_http_copy_filter.c \ src/http/ngx_http_log_handler.c \ src/http/ngx_http_request_body.c \ src/http/ngx_http_parse_time.c \ diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c --- a/src/core/ngx_output_chain.c +++ b/src/core/ngx_output_chain.c @@ -81,7 +81,11 @@ int ngx_output_chain(ngx_output_chain_ct ctx->hunk = ctx->free->hunk; ctx->free = ctx->free->next; - } else if (ctx->hunks < ctx->bufs.num) { + } else if (out || ctx->hunks == ctx->bufs.num) { + + break; + + } else { size = ctx->bufs.size; @@ -118,9 +122,6 @@ int ngx_output_chain(ngx_output_chain_ct ctx->hunk->tag = ctx->tag; ctx->hunk->type |= NGX_HUNK_RECYCLED; ctx->hunks++; - - } else { - break; } } @@ -148,10 +149,6 @@ int ngx_output_chain(ngx_output_chain_ct *last_out = cl; last_out = &cl->next; ctx->hunk = NULL; - - if (ctx->free == NULL) { - break; - } } if (out == NULL && last != NGX_NONE) { diff --git a/src/http/modules/ngx_http_range_filter.c b/src/http/modules/ngx_http_range_filter.c --- a/src/http/modules/ngx_http_range_filter.c +++ b/src/http/modules/ngx_http_range_filter.c @@ -44,10 +44,11 @@ typedef struct { } ngx_http_range_filter_ctx_t; -static ngx_int_t ngx_http_range_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_range_header_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_range_body_filter_init(ngx_cycle_t *cycle); -static ngx_http_module_t ngx_http_range_filter_module_ctx = { +static ngx_http_module_t ngx_http_range_header_filter_module_ctx = { NULL, /* pre conf */ NULL, /* create main configuration */ @@ -61,12 +62,36 @@ static ngx_http_module_t ngx_http_range }; -ngx_module_t ngx_http_range_filter_module = { +ngx_module_t ngx_http_range_header_filter_module = { NGX_MODULE, - &ngx_http_range_filter_module_ctx, /* module context */ + &ngx_http_range_header_filter_module_ctx, /* module context */ NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ - ngx_http_range_filter_init, /* init module */ + ngx_http_range_header_filter_init, /* init module */ + NULL /* init child */ +}; + + +static ngx_http_module_t ngx_http_range_body_filter_module_ctx = { + NULL, /* pre conf */ + + 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_body_filter_module = { + NGX_MODULE, + &ngx_http_range_body_filter_module_ctx, /* module context */ + NULL, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + ngx_http_range_body_filter_init, /* init module */ NULL /* init child */ }; @@ -88,13 +113,18 @@ static ngx_int_t ngx_http_range_header_f if (r->http_version < NGX_HTTP_VERSION_10 || r->headers_out.status != NGX_HTTP_OK || r->headers_out.content_length_n == -1 + || !(r->filter & NGX_HTTP_FILTER_ALLOW_RANGES)) +#if 0 /* STUB: we currently support ranges for file hunks only */ || !r->sendfile || r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY +#endif +#if 0 || (r->headers_out.content_encoding && r->headers_out.content_encoding->value.len)) +#endif { return ngx_http_next_header_filter(r); } @@ -294,7 +324,7 @@ static ngx_int_t ngx_http_range_header_f } #endif - ngx_http_create_ctx(r, ctx, ngx_http_range_filter_module, + ngx_http_create_ctx(r, ctx, ngx_http_range_body_filter_module, sizeof(ngx_http_range_filter_ctx_t), NGX_ERROR); len = 4 + 10 + 2 + 14 + r->headers_out.content_type->value.len @@ -414,7 +444,7 @@ static ngx_int_t ngx_http_range_body_fil return ngx_http_next_body_filter(r, in); } - ctx = ngx_http_get_module_ctx(r, ngx_http_range_filter_module); + ctx = ngx_http_get_module_ctx(r, ngx_http_range_body_filter_module); ll = &out; for (i = 0; i < r->headers_out.ranges.nelts; i++) { @@ -483,11 +513,17 @@ static ngx_int_t ngx_http_range_body_fil } -static ngx_int_t ngx_http_range_filter_init(ngx_cycle_t *cycle) +static ngx_int_t ngx_http_range_header_filter_init(ngx_cycle_t *cycle) { ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_range_header_filter; + return NGX_OK; +} + + +static ngx_int_t ngx_http_range_body_filter_init(ngx_cycle_t *cycle) +{ ngx_http_next_body_filter = ngx_http_top_body_filter; ngx_http_top_body_filter = ngx_http_range_body_filter; diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -480,6 +480,7 @@ static ngx_int_t ngx_http_static_handler return NGX_HTTP_INTERNAL_SERVER_ERROR; } + r->filter |= NGX_HTTP_FILTER_ALLOW_RANGES; rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_copy_filter.c rename from src/http/ngx_http_output_filter.c rename to src/http/ngx_http_copy_filter.c --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_copy_filter.c @@ -6,28 +6,29 @@ typedef struct { ngx_bufs_t bufs; -} ngx_http_output_filter_conf_t; +} ngx_http_copy_filter_conf_t; -static void *ngx_http_output_filter_create_conf(ngx_conf_t *cf); -static char *ngx_http_output_filter_merge_conf(ngx_conf_t *cf, - void *parent, void *child); +static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf); +static char *ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, + void *parent, void *child); +static ngx_int_t ngx_http_copy_filter_init(ngx_cycle_t *cycle); -static ngx_command_t ngx_http_output_filter_commands[] = { +static ngx_command_t ngx_http_copy_filter_commands[] = { {ngx_string("output_buffers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, ngx_conf_set_bufs_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_output_filter_conf_t, bufs), + offsetof(ngx_http_copy_filter_conf_t, bufs), NULL}, ngx_null_command }; -static ngx_http_module_t ngx_http_output_filter_module_ctx = { +static ngx_http_module_t ngx_http_copy_filter_module_ctx = { NULL, /* pre conf */ NULL, /* create main configuration */ @@ -36,40 +37,41 @@ static ngx_http_module_t ngx_http_outpu NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_output_filter_create_conf, /* create location configuration */ - ngx_http_output_filter_merge_conf /* merge location configuration */ + ngx_http_copy_filter_create_conf, /* create location configuration */ + ngx_http_copy_filter_merge_conf /* merge location configuration */ }; -ngx_module_t ngx_http_output_filter_module = { +ngx_module_t ngx_http_copy_filter_module = { NGX_MODULE, - &ngx_http_output_filter_module_ctx, /* module context */ - ngx_http_output_filter_commands, /* module directives */ + &ngx_http_copy_filter_module_ctx, /* module context */ + ngx_http_copy_filter_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ - NULL, /* init module */ - NULL /* init child */ + ngx_http_copy_filter_init, /* init module */ + NULL /* init process */ }; +static ngx_http_output_body_filter_pt ngx_http_next_filter; -ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in) + +ngx_int_t ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in) { - ngx_int_t rc; - ngx_output_chain_ctx_t *ctx; - ngx_http_output_filter_conf_t *conf; + ngx_output_chain_ctx_t *ctx; + ngx_http_copy_filter_conf_t *conf; if (r->connection->write->error) { return NGX_ERROR; } ctx = ngx_http_get_module_ctx(r->main ? r->main : r, - ngx_http_output_filter_module); + ngx_http_copy_filter_module); if (ctx == NULL) { conf = ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_output_filter_module); + ngx_http_copy_filter_module); - ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module, + ngx_http_create_ctx(r, ctx, ngx_http_copy_filter_module, sizeof(ngx_output_chain_ctx_t), NGX_ERROR); ctx->sendfile = r->sendfile; @@ -78,33 +80,23 @@ ngx_int_t ngx_http_output_filter(ngx_htt ctx->pool = r->pool; ctx->bufs = conf->bufs; - ctx->tag = (ngx_hunk_tag_t) &ngx_http_output_filter_module; + ctx->tag = (ngx_hunk_tag_t) &ngx_http_copy_filter_module; - ctx->output_filter = (ngx_output_chain_filter_pt) - ngx_http_top_body_filter; + ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter; ctx->filter_ctx = r; } - rc = ngx_output_chain(ctx, in); - - if (rc == NGX_ERROR) { - - /* NGX_ERROR could be returned by any filter */ - - r->connection->write->error = 1; - } - - return rc; + return ngx_output_chain(ctx, in); } -static void *ngx_http_output_filter_create_conf(ngx_conf_t *cf) +static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf) { - ngx_http_output_filter_conf_t *conf; + ngx_http_copy_filter_conf_t *conf; ngx_test_null(conf, - ngx_palloc(cf->pool, sizeof(ngx_http_output_filter_conf_t)), + ngx_palloc(cf->pool, sizeof(ngx_http_copy_filter_conf_t)), NULL); conf->bufs.num = 0; @@ -113,13 +105,23 @@ static void *ngx_http_output_filter_crea } -static char *ngx_http_output_filter_merge_conf(ngx_conf_t *cf, - void *parent, void *child) +static char *ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, + void *parent, void *child) { - ngx_http_output_filter_conf_t *prev = parent; - ngx_http_output_filter_conf_t *conf = child; + ngx_http_copy_filter_conf_t *prev = parent; + ngx_http_copy_filter_conf_t *conf = child; ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 1, 32768); return NULL; } + + +static ngx_int_t ngx_http_copy_filter_init(ngx_cycle_t *cycle) +{ + ngx_http_next_filter = ngx_http_top_body_filter; + ngx_http_top_body_filter = ngx_http_copy_filter; + + return NGX_OK; +} + diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -658,6 +658,27 @@ int ngx_http_send_header(ngx_http_reques } +ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in) +{ + ngx_int_t rc; + + if (r->connection->write->error) { + return NGX_ERROR; + } + + rc = ngx_http_top_body_filter(r, in); + + if (rc == NGX_ERROR) { + + /* NGX_ERROR could be returned by any filter */ + + r->connection->write->error = 1; + } + + return rc; +} + + int ngx_http_redirect(ngx_http_request_t *r, int redirect) { /* STUB */ diff --git a/src/http/ngx_http_filter.h b/src/http/ngx_http_filter.h --- a/src/http/ngx_http_filter.h +++ b/src/http/ngx_http_filter.h @@ -5,6 +5,7 @@ #define NGX_HTTP_FILTER_NEED_IN_MEMORY 1 #define NGX_HTTP_FILTER_SSI_NEED_IN_MEMORY 2 #define NGX_HTTP_FILTER_NEED_TEMP 4 +#define NGX_HTTP_FILTER_ALLOW_RANGES 8 typedef int (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r);