# HG changeset patch # User Igor Sysoev # Date 1065627174 0 # Node ID 656d468f4ead3d38acc68d299615cdec05ad69ad # Parent e32405df0e77aa18863fec155e23d9b06646c3d2 nginx-0.0.1-2003-10-08-19:32:54 import diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -859,6 +859,60 @@ char *ngx_conf_set_sec_slot(ngx_conf_t * } +char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *p = conf; + + int len, scale; + char last; + ngx_str_t *value; + ngx_bufs_t *bufs; + + + bufs = (ngx_bufs_t *) (p + cmd->offset); + + if (bufs->num) { + return "is duplicate"; + } + + value = (ngx_str_t *) cf->args->elts; + + bufs->num = ngx_atoi(value[1].data, value[1].len); + if (bufs->num == NGX_ERROR || bufs->num == 0) { + return "invalid value"; + } + + len = value[2].len; + last = value[2].data[len - 1]; + + switch (last) { + case 'K': + case 'k': + len--; + scale = 1024; + break; + + case 'M': + case 'm': + len--; + scale = 1024 * 1024; + break; + + default: + scale = 1; + } + + bufs->size = ngx_atoi(value[2].data, len); + if (bufs->size == NGX_ERROR || bufs->size == 0) { + return "invalid value"; + } + + bufs->size *= scale; + + return NGX_CONF_OK; +} + + char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { return "unsupported on this platform"; diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -175,6 +175,17 @@ struct ngx_conf_s { } \ } +#define ngx_conf_merge_bufs_value(conf, prev, default_num, default_size) \ + if (conf.num == 0) { \ + if (prev.num) { \ + conf.num = prev.num; \ + conf.size = prev.size; \ + } else { \ + conf.num = default_num; \ + conf.size = default_size; \ + } \ + } + #define addressof(addr) ((int) &addr) @@ -193,6 +204,7 @@ char *ngx_conf_set_num_slot(ngx_conf_t * char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); char *ngx_conf_set_core_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h --- a/src/core/ngx_hunk.h +++ b/src/core/ngx_hunk.h @@ -64,6 +64,12 @@ struct ngx_chain_s { }; +typedef struct { + int num; + ssize_t size; +} ngx_bufs_t; + + #define NGX_CHAIN_ERROR (ngx_chain_t *) NGX_ERROR diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c --- a/src/http/modules/ngx_http_gzip_filter.c +++ b/src/http/modules/ngx_http_gzip_filter.c @@ -7,10 +7,9 @@ typedef struct { - int enable; - int hunk_size; - int hunks; - int no_buffer; + int enable; + ngx_bufs_t bufs; + int no_buffer; } ngx_http_gzip_conf_t; @@ -51,18 +50,11 @@ static ngx_command_t ngx_http_gzip_filt offsetof(ngx_http_gzip_conf_t, enable), NULL}, - {ngx_string("gzip_hunk_size"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, + {ngx_string("gzip_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_gzip_conf_t, hunk_size), - NULL}, - - {ngx_string("gzip_hunks"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_gzip_conf_t, hunks), + offsetof(ngx_http_gzip_conf_t, bufs), NULL}, {ngx_string("gzip_no_buffer"), @@ -173,7 +165,7 @@ static int ngx_http_gzip_header_filter(n static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { - int rc, wbits, mem_level, zin, zout; + int rc, wbits, mem_level, zin, zout, last; struct gztrailer *trailer; ngx_hunk_t *h; ngx_chain_t *ce; @@ -240,6 +232,8 @@ static int ngx_http_gzip_body_filter(ngx } } + last = NGX_NONE; + for ( ;; ) { for ( ;; ) { @@ -285,11 +279,12 @@ static int ngx_http_gzip_body_filter(ngx ctx->out_hunk = ctx->free->hunk; ctx->free = ctx->free->next; - } else if (ctx->hunks < conf->hunks) { + } else if (ctx->hunks < conf->bufs.num) { ngx_test_null(ctx->out_hunk, - ngx_create_temp_hunk(r->pool, conf->hunk_size, + ngx_create_temp_hunk(r->pool, conf->bufs.size, 0, 0), ngx_http_gzip_error(ctx)); + ctx->out_hunk->type |= NGX_HUNK_RECYCLED; ctx->hunks++; } else { @@ -297,7 +292,7 @@ static int ngx_http_gzip_body_filter(ngx } ctx->zstream.next_out = (unsigned char *) ctx->out_hunk->pos; - ctx->zstream.avail_out = conf->hunk_size; + ctx->zstream.avail_out = conf->bufs.size; } ngx_log_debug(r->connection->log, "deflate(): %08x %08x %d %d %d" _ @@ -318,7 +313,7 @@ ngx_log_debug(r->connection->log, "DEFLA ctx->in_hunk->pos = (char *) ctx->zstream.next_in; if (ctx->zstream.avail_out == 0) { - ctx->out_hunk->last += conf->hunk_size; + ctx->out_hunk->last += conf->bufs.size; ngx_add_hunk_to_chain(ce, ctx->out_hunk, r->pool, ngx_http_gzip_error(ctx)); *ctx->last_out = ce; @@ -409,15 +404,13 @@ ngx_log_debug(r->connection->log, "DEFLA } } - if (ctx->out == NULL) { - if (ctx->in || ctx->zstream.avail_in) { - return NGX_AGAIN; - } else { - return NGX_OK; - } + if (ctx->out == NULL && last != NGX_NONE) { + return last; } - if (next_body_filter(r, ctx->out) == NGX_ERROR) { + last = next_body_filter(r, ctx->out); + + if (last == NGX_ERROR) { return ngx_http_gzip_error(ctx); } @@ -463,8 +456,7 @@ static void *ngx_http_gzip_create_conf(n NGX_CONF_ERROR); conf->enable = NGX_CONF_UNSET; - conf->hunk_size = NGX_CONF_UNSET; - conf->hunks = NGX_CONF_UNSET; +/* conf->bufs.num = 0; */ conf->no_buffer = NGX_CONF_UNSET; return conf; @@ -478,9 +470,8 @@ static char *ngx_http_gzip_merge_conf(ng ngx_http_gzip_conf_t *conf = child; ngx_conf_merge_value(conf->enable, prev->enable, 0); - ngx_conf_merge_size_value(conf->hunk_size, prev->hunk_size, + ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, /* STUB: PAGE_SIZE */ 4096); - ngx_conf_merge_value(conf->hunks, prev->hunks, 4); ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0); return NGX_CONF_OK; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -101,8 +101,12 @@ static char conn_close_header[] = "Conne static int ngx_http_proxy_translate_handler(ngx_http_request_t *r) { +#if 0 r->handler = ngx_http_proxy_handler; return NGX_OK; +#else + return NGX_DECLINED; +#endif } diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -5,15 +5,26 @@ typedef struct { - ssize_t hunk_size; + ngx_bufs_t bufs; } ngx_http_output_filter_conf_t; typedef struct { - ngx_hunk_t *hunk; /* the temporary hunk to copy */ - ngx_chain_t *incoming; - ngx_chain_t in; /* one chain entry for input */ - ngx_chain_t out; /* one chain entry for output */ + + /* + * NOTE: we do not need now to store hunk in ctx, + * it's needed for the future NGX_FILE_AIO_READ support only + */ + + ngx_hunk_t *hunk; + + ngx_chain_t *in; + ngx_chain_t *out; + ngx_chain_t **last_out; + ngx_chain_t *free; + ngx_chain_t *busy; + + int hunks; } ngx_http_output_filter_ctx_t; @@ -25,11 +36,11 @@ static char *ngx_http_output_filter_merg static ngx_command_t ngx_http_output_filter_commands[] = { - {ngx_string("output_buffer"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, + {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, hunk_size), + offsetof(ngx_http_output_filter_conf_t, bufs), NULL}, ngx_null_command @@ -58,7 +69,7 @@ ngx_module_t ngx_http_output_filter_mod }; -#define next_filter (*ngx_http_top_body_filter) +#define ngx_next_filter (*ngx_http_top_body_filter) #define need_to_copy(r, hunk) \ (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) \ @@ -67,11 +78,12 @@ ngx_module_t ngx_http_output_filter_mod && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))) + int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) { - int rc; + int rc, last; ssize_t size; - ngx_chain_t *ce, *le; + ngx_chain_t out, *ce, **le; ngx_http_output_filter_ctx_t *ctx; ngx_http_output_filter_conf_t *conf; @@ -81,120 +93,86 @@ int ngx_http_output_filter(ngx_http_requ if (ctx == NULL) { ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module, sizeof(ngx_http_output_filter_ctx_t), NGX_ERROR); + ctx->last_out = &ctx->out; } - /* the short path for the case when the chain ctx->incoming is empty - and there is no hunk or the hunk does not require the copy */ - if (ctx->incoming == NULL) { + /* + * the short path for the case when the chain ctx->in is empty + * and there's no hunk or the hunk does not require the copy + */ + + if (ctx->in == NULL) { if (hunk == NULL) { - return next_filter(r, NULL); + return ngx_next_filter(r, NULL); } - /* we do not need to copy the incoming hunk to our hunk */ if (!need_to_copy(r, hunk)) { - ctx->out.hunk = hunk; - ctx->out.next = NULL; - return next_filter(r, &ctx->out); - } - } - - /* add the incoming hunk to the chain ctx->incoming */ - if (hunk) { - - /* the output of the only hunk is common case so we have - the special chain entry ctx->in for it */ - if (ctx->incoming == NULL) { - ctx->in.hunk = hunk; - ctx->in.next = NULL; - ctx->incoming = &ctx->in; - - } else { - for (ce = ctx->incoming; ce->next; ce = ce->next) { /* void */ ; } - ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR); + out.hunk = hunk; + out.next = NULL; + return ngx_next_filter(r, &out); } } - /* allocate our hunk if it's needed */ - if (ctx->hunk == NULL) { - - conf = ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_output_filter_module); - - if (hunk->type & NGX_HUNK_LAST) { - if (hunk->type & NGX_HUNK_IN_MEMORY) { - size = hunk->last - hunk->pos; - } else { - size = (size_t) (hunk->file_last - hunk->file_pos); - } - - if (size > conf->hunk_size) { - size = conf->hunk_size; - } + /* add the incoming hunk to the chain ctx->in */ - } else { - size = conf->hunk_size; - } + if (hunk) { + le = &ctx->in; - ngx_test_null(ctx->hunk, - ngx_create_temp_hunk(r->pool, size, 50, 50), - NGX_ERROR); - ctx->hunk->type |= NGX_HUNK_RECYCLED; - - - /* our hunk is still busy */ - } else if (ctx->hunk->pos < ctx->hunk->last) { - rc = next_filter(r, NULL); - - if (rc == NGX_ERROR || rc == NGX_AGAIN) { - return rc; + for (ce = ctx->in; ce; ce = ce->next) { + le = &ce->next; } - /* NGX_OK */ -#if 1 - /* set our hunk free */ - ctx->hunk->pos = ctx->hunk->last = ctx->hunk->start; -#endif + ngx_add_hunk_to_chain(ce, hunk, r->pool, NGX_ERROR); + *le = ce; } -#if (NGX_SUPPRESS_WARN) - le = NULL; -#endif + conf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_output_filter_module); + + last = NGX_NONE; + + for ( ;; ) { + + while (ctx->in) { + + if (!need_to_copy(r, ctx->in->hunk)) { - /* process the chain ctx->incoming */ - do { - /* find the hunks that do not need to be copied ... */ - for (ce = ctx->incoming; ce; ce = ce->next) { - if (need_to_copy(r, ce->hunk)) { - break; - } - le = ce; - } + /* move the chain entry to the chain ctx->out */ + + ce = ctx->in; + ctx->in = ce->next; - /* ... and pass them to the next filter */ - if (ctx->incoming != ce) { + *ctx->last_out = ce; + ctx->last_out = &ce->next; + ce->next = NULL; - ctx->out.hunk = ctx->incoming->hunk; - ctx->out.next = ctx->incoming->next; - ctx->incoming = ce; - le->next = NULL; - - rc = next_filter(r, &ctx->out); - if (rc == NGX_ERROR || rc == NGX_AGAIN) { - return rc; + continue; } - /* NGX_OK */ - if (ctx->incoming == NULL) { - return rc; - } - } + if (ctx->hunk == NULL) { + + /* get the free hunk */ + + if (ctx->free) { + ctx->hunk = ctx->free->hunk; + ctx->free = ctx->free->next; - /* copy the first hunk or its part from the chain ctx->incoming - to our hunk and pass it to the next filter */ - do { - rc = ngx_http_output_filter_copy_hunk(ctx->hunk, - ctx->incoming->hunk); + } else if (ctx->hunks < conf->bufs.num) { + ngx_test_null(ctx->hunk, + ngx_create_temp_hunk(r->pool, conf->bufs.size, + 0, 0), + NGX_ERROR); + ctx->hunk->type |= NGX_HUNK_RECYCLED; + ctx->hunks++; + + } else { + break; + } + } + + rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk); + if (rc == NGX_ERROR) { return rc; } @@ -205,42 +183,35 @@ int ngx_http_output_filter(ngx_http_requ } #endif - if (ctx->incoming->hunk->type & NGX_HUNK_IN_MEMORY) { - size = ctx->incoming->hunk->last - ctx->incoming->hunk->pos; + if (ctx->in->hunk->type & NGX_HUNK_IN_MEMORY) { + size = ctx->in->hunk->last - ctx->in->hunk->pos; } else { - size = (size_t) (ctx->incoming->hunk->file_last - - ctx->incoming->hunk->file_pos); + size = (size_t) (ctx->in->hunk->file_last + - ctx->in->hunk->file_pos); } - /* delete the completed hunk from the incoming chain */ + /* delete the completed hunk from the chain ctx->in */ + if (size == 0) { - ctx->incoming = ctx->incoming->next; + ctx->in = ctx->in->next; } - ctx->out.hunk = ctx->hunk; - ctx->out.next = NULL; - - rc = next_filter(r, &ctx->out); - if (rc == NGX_ERROR || rc == NGX_AGAIN) { - return rc; - } + ngx_add_hunk_to_chain(ce, ctx->hunk, r->pool, NGX_ERROR); + *ctx->last_out = ce; + ctx->last_out = &ce->next; + ctx->hunk = NULL; + } - /* NGX_OK */ -#if 1 - /* set our hunk free */ - ctx->hunk->pos = ctx->hunk->last = ctx->hunk->start; -#endif + if (ctx->out == NULL && last != NGX_NONE) { + return last; + } - /* repeat until we will have copied the whole first hunk from - the chain ctx->incoming */ - - } while (size); + last = ngx_next_filter(r, ctx->out); - /* repeat until we will have processed the whole chain ctx->incoming */ - } while (ctx->incoming); - - return NGX_OK; + ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out); + ctx->last_out = &ctx->out; + } } @@ -319,7 +290,7 @@ static void *ngx_http_output_filter_crea ngx_palloc(cf->pool, sizeof(ngx_http_output_filter_conf_t)), NULL); - conf->hunk_size = NGX_CONF_UNSET; + conf->bufs.num = 0; return conf; } @@ -331,7 +302,7 @@ static char *ngx_http_output_filter_merg ngx_http_output_filter_conf_t *prev = parent; ngx_http_output_filter_conf_t *conf = child; - ngx_conf_merge_size_value(conf->hunk_size, prev->hunk_size, 32768); + ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 2, 32768); return NULL; } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -2,20 +2,6 @@ #define _NGX_HTTP_REQUEST_H_INCLUDED_ -#if 0 -#include - -#include -#include -#include -#include -#include -#include -#include - -#endif - - #define NGX_HTTP_VERSION_9 9 #define NGX_HTTP_VERSION_10 1000 #define NGX_HTTP_VERSION_11 1001 @@ -28,6 +14,9 @@ #define NGX_HTTP_CONN_KEEP_ALIVE 1 +#define NGX_NONE 1 + + #define NGX_HTTP_PARSE_HEADER_DONE 1 #define NGX_HTTP_PARSE_INVALID_METHOD 10 #define NGX_HTTP_PARSE_INVALID_REQUEST 11