diff options
author | Igor Sysoev <igor@sysoev.ru> | 2003-11-25 23:44:56 +0300 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2003-11-25 23:44:56 +0300 |
commit | a8fa0a6a37b6e90324e0dcbf4733324199623841 (patch) | |
tree | 1a7edec9aa04946afc22299bf587823488fb492f /src/http | |
parent | d9d0ca12688034d481e2f1f5cf13a098338ec31d (diff) |
nginx-0.0.1-2003-11-25-23:44:56 import
Diffstat (limited to 'src/http')
-rw-r--r-- | src/http/modules/ngx_http_chunked_filter.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_not_modified_filter.c | 6 | ||||
-rw-r--r-- | src/http/modules/ngx_http_range_filter.c | 22 | ||||
-rw-r--r-- | src/http/modules/ngx_http_static_handler.c | 36 | ||||
-rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_cache.c | 5 | ||||
-rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.c | 32 | ||||
-rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_upstream.c | 21 | ||||
-rw-r--r-- | src/http/ngx_http_busy_lock.c | 2 | ||||
-rw-r--r-- | src/http/ngx_http_cache.c | 244 | ||||
-rw-r--r-- | src/http/ngx_http_cache.h | 48 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.c | 166 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.h | 8 | ||||
-rw-r--r-- | src/http/ngx_http_header_filter.c | 2 | ||||
-rw-r--r-- | src/http/ngx_http_log_handler.c | 2 |
14 files changed, 490 insertions, 106 deletions
diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c index 5e7bd28be..ed7b460c1 100644 --- a/src/http/modules/ngx_http_chunked_filter.c +++ b/src/http/modules/ngx_http_chunked_filter.c @@ -87,7 +87,7 @@ static int ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in) } ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR); - len = ngx_snprintf(chunk, 11, SIZEX_FMT CRLF, size); + len = ngx_snprintf(chunk, 11, SIZE_T_X_FMT CRLF, size); ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; diff --git a/src/http/modules/ngx_http_not_modified_filter.c b/src/http/modules/ngx_http_not_modified_filter.c index c62375253..11cc21cb9 100644 --- a/src/http/modules/ngx_http_not_modified_filter.c +++ b/src/http/modules/ngx_http_not_modified_filter.c @@ -58,11 +58,13 @@ static int ngx_http_not_modified_header_filter(ngx_http_request_t *r) if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) { r->headers_out.status = NGX_HTTP_NOT_MODIFIED; - r->headers_out.content_length_n = -1; - r->headers_out.content_length = NULL; r->headers_out.content_type->key.len = 0; r->headers_out.content_type = NULL; + r->headers_out.content_length_n = -1; + r->headers_out.content_length = NULL; +#if 0 r->headers_out.accept_ranges->key.len = 0; +#endif } return ngx_http_next_header_filter(r); diff --git a/src/http/modules/ngx_http_range_filter.c b/src/http/modules/ngx_http_range_filter.c index 11b7d0f13..bf28fe123 100644 --- a/src/http/modules/ngx_http_range_filter.c +++ b/src/http/modules/ngx_http_range_filter.c @@ -215,7 +215,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r) r->headers_out.content_range->value.len = ngx_snprintf(r->headers_out.content_range->value.data, - 8 + 20 + 1, "bytes */" OFF_FMT, + 8 + 20 + 1, "bytes */" OFF_T_FMT, r->headers_out.content_length_n); r->headers_out.content_length_n = -1; @@ -247,11 +247,11 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r) /* "Content-Range: bytes SSSS-EEEE/TTTT" header */ r->headers_out.content_range->value.len = - ngx_snprintf(r->headers_out.content_range->value.data, - 6 + 20 + 1 + 20 + 1 + 20 + 1, - "bytes " OFF_FMT "-" OFF_FMT "/" OFF_FMT, - range->start, range->end - 1, - r->headers_out.content_length_n); + ngx_snprintf(r->headers_out.content_range->value.data, + 6 + 20 + 1 + 20 + 1 + 20 + 1, + "bytes " OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT, + range->start, range->end - 1, + r->headers_out.content_length_n); r->headers_out.content_length_n = range->end - range->start; @@ -336,11 +336,11 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r) /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */ range[i].content_range.len = - ngx_snprintf(range[i].content_range.data, - 20 + 1 + 20 + 1 + 20 + 5, - OFF_FMT "-" OFF_FMT "/" OFF_FMT CRLF CRLF, - range[i].start, range[i].end - 1, - r->headers_out.content_length_n); + ngx_snprintf(range[i].content_range.data, + 20 + 1 + 20 + 1 + 20 + 5, + OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT CRLF CRLF, + range[i].start, range[i].end - 1, + r->headers_out.content_length_n); len += ctx->boundary_header.len + range[i].content_range.len + (size_t) (range[i].end - range[i].start); diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c index 69f1a1417..80af26672 100644 --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -44,6 +44,8 @@ int ngx_http_static_translate_handler(ngx_http_request_t *r) int rc, level; char *location, *last; ngx_err_t err; + ngx_http_cache_ctx_t ctx; + ngx_http_cache_conf_t *ccf; ngx_http_core_loc_conf_t *clcf; if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { @@ -73,7 +75,7 @@ int ngx_http_static_translate_handler(ngx_http_request_t *r) return NGX_HTTP_FORBIDDEN; } - /* "+ 2" is for trailing '/' in redirect and '\0' */ + /* "+ 2" is for trailing '/' in possible redirect and '\0' */ ngx_test_null(r->file.name.data, ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2), NGX_HTTP_INTERNAL_SERVER_ERROR); @@ -85,6 +87,38 @@ int ngx_http_static_translate_handler(ngx_http_request_t *r) ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data); + + /* STUB */ + ccf = NULL; + ctx.key.len = 0; + +#if 0 + ccf = ngx_http_get_module_loc_conf(r, ngx_http_cache_module); + + if (ccf->open_files) { + ctx->hash = ccf->open_files; + ctx->key = r->file.name; + + cache = ngx_http_cache_get_data(r, ctx); + + if (cache + && ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) + || ccf->hash->life_time >= ngx_time() - cache->updated)) + { + cache->refs++; + r->file.fd = cache->fd; + r->file.name = cache->key; + r->content_handler = ngx_http_static_handler; + + return NGX_OK; + } + + } else { + cache = NULL; + } + +#endif + #if (WIN9X) if (ngx_win32_version < NGX_WIN_NT) { diff --git a/src/http/modules/proxy/ngx_http_proxy_cache.c b/src/http/modules/proxy/ngx_http_proxy_cache.c index 05fec3a19..9661cff96 100644 --- a/src/http/modules/proxy/ngx_http_proxy_cache.c +++ b/src/http/modules/proxy/ngx_http_proxy_cache.c @@ -86,6 +86,7 @@ static int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p, } if (rc == NGX_HTTP_CACHE_STALE || rc == NGX_HTTP_CACHE_AGED) { + p->state->expired = ngx_time() - p->cache->ctx.expires; p->header_in->pos = p->header_in->start + p->cache->ctx.header_size; if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) { @@ -487,6 +488,8 @@ int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p) out[i].hunk->type |= NGX_HUNK_LAST; } + r->file.fd = p->cache->ctx.file.fd; + return ngx_http_output_filter(r, out); } @@ -600,7 +603,7 @@ int ngx_http_proxy_update_cache(ngx_http_proxy_ctx_t *p) ep = p->upstream->event_pipe; -ngx_log_debug(p->request->connection->log, "LEN: " OFF_FMT ", " OFF_FMT _ +ngx_log_debug(p->request->connection->log, "LEN: " OFF_T_FMT ", " OFF_T_FMT _ p->cache->ctx.length _ ep->read_length); if (p->cache->ctx.length == -1) { diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 25f5b3371..e8b78f498 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -485,6 +485,10 @@ ngx_log_debug(r->connection->log, "CACHE FD: %d" _ p->cache->ctx.file.fd); r->file.fd = p->cache->ctx.file.fd; } + if (rc == 0 && r->main == NULL) { + rc = ngx_http_send_last(r); + } + ngx_http_finalize_request(r, rc); } @@ -586,15 +590,25 @@ static char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, char *buf, *buf++ = '/'; - *buf++ = '_'; + if (p->state->expired == 0) { + *buf++ = '-'; + + } else { + buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expired); + } *buf++ = '/'; - *buf++ = '_'; + if (p->state->bl_time == 0) { + *buf++ = '-'; + + } else { + buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->bl_time); + } *buf++ = '/'; - *buf++ = '_'; + *buf++ = '*'; *buf++ = ' '; @@ -617,15 +631,15 @@ static char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, char *buf, *buf++ = '/'; - if (p->state->reason >= NGX_HTTP_PROXY_CACHE_XAE) { + if (p->state->reason < NGX_HTTP_PROXY_CACHE_XAE) { *buf++ = '-'; } else { - buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_FMT, p->state->expires); + buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expires); } *buf++ = ' '; - *buf++ = '_'; + *buf++ = '*'; return buf; } @@ -833,9 +847,9 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, int i, len; char *err, *host; + in_addr_t addr; ngx_str_t *value; struct hostent *h; - u_int32_t addr; ngx_http_conf_ctx_t *ctx; ngx_http_core_loc_conf_t *clcf; @@ -869,6 +883,8 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, NGX_CONF_ERROR); ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1); + /* AF_INET only */ + addr = inet_addr(host); if (addr == INADDR_NONE) { @@ -894,7 +910,7 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, for (i = 0; h->h_addr_list[i] != NULL; i++) { lcf->peers->peers[i].host.data = host; lcf->peers->peers[i].host.len = lcf->upstream->host.len; - lcf->peers->peers[i].addr = *(u_int32_t *)(h->h_addr_list[i]); + lcf->peers->peers[i].addr = *(in_addr_t *)(h->h_addr_list[i]); lcf->peers->peers[i].port = lcf->upstream->port; len = INET_ADDRSTRLEN + lcf->upstream->port_text.len + 1; diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c index 1b1ca4493..d36cbee10 100644 --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -1017,8 +1017,7 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p) ep->hunk_to_file->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; if (ngx_event_flags & NGX_USE_AIO_EVENT) { - - /* the posted aio operation can currupt shadow buf */ + /* the posted aio operation can currupt a shadow buffer */ ep->single_buf = 1; } @@ -1126,26 +1125,38 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev) } if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) { + ngx_log_debug(ev->log, "http proxy upstream exit"); ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock); - ngx_http_proxy_close_connection(p); + ngx_http_proxy_finalize_request(p, 0); + return; } } + if (ep->downstream_error) { + ngx_log_debug(ev->log, "http proxy downstream error"); + if (!p->cachable && p->upstream->peer.connection) { + ngx_http_proxy_finalize_request(p, 0); + } + } + +#if 0 if (ep->downstream_done) { ngx_log_debug(ev->log, "http proxy downstream done"); - ngx_http_proxy_finalize_request(p, r->main ? 0 : ngx_http_send_last(r)); + ngx_http_proxy_finalize_request(p, 0); return; } if (ep->downstream_error) { + ngx_log_debug(ev->log, "http proxy downstream error"); if (!p->cachable && p->upstream->peer.connection) { ngx_http_proxy_close_connection(p); } if (p->upstream->peer.connection == NULL) { - ngx_http_close_connection(r->connection); + ngx_http_close_request(r); } } +#endif } diff --git a/src/http/ngx_http_busy_lock.c b/src/http/ngx_http_busy_lock.c index 901407824..b4fdefe64 100644 --- a/src/http/ngx_http_busy_lock.c +++ b/src/http/ngx_http_busy_lock.c @@ -205,7 +205,7 @@ char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd, dup = 0; invalid = 0; - value = (ngx_str_t *) cf->args->elts; + value = cf->args->elts; for (i = 1; i < cf->args->nelts; i++) { diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c index fd1a9d01e..7b9cd0489 100644 --- a/src/http/ngx_http_cache.c +++ b/src/http/ngx_http_cache.c @@ -13,11 +13,45 @@ #endif +static int ngx_crc(char *data, size_t len); + +static void *ngx_http_cache_create_conf(ngx_conf_t *cf); +static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, + void *parent, void *child); + + +static ngx_http_module_t ngx_http_cache_module_ctx = { + NULL, /* pre conf */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_cache_create_conf, /* create location configuration */ + ngx_http_core_merge_loc_conf /* merge location configuration */ +}; + + +ngx_module_t ngx_http_cache_module = { + NGX_MODULE, + &ngx_http_cache_module_ctx, /* module context */ + NULL, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init module */ + NULL /* init child */ +}; + + + int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) { MD5_CTX md5; - ctx->header_size = sizeof(ngx_http_cache_header_t) + ctx->key.len + 1; + /* we use offsetof() because sizeof() pads struct size to int size */ + ctx->header_size = offsetof(ngx_http_cache_header_t, key) + + ctx->key.len + 1; ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32; if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) { @@ -46,7 +80,83 @@ ngx_log_debug(r->connection->log, "FILE: %s" _ ctx->file.name.data); } -/* TODO: Win32 inode analogy */ +int ngx_http_cache_get_data(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) +{ + ngx_uint_t n, i; + + ctx->crc = ngx_crc(ctx->key.data, ctx->key.len); + + n = ctx->crc % ctx->hash->hash; + for (i = 0; i < ctx->hash->nelts; i++) { + if (ctx->hash->cache[n][i].crc == ctx->crc + && ctx->hash->cache[n][i].key.len == ctx->key.len + && ngx_rstrncmp(ctx->hash->cache[n][i].key.data, ctx->key.data, + ctx->key.len) == 0) + { + ctx->cache = ctx->hash->cache[n][i].data; + ctx->hash->cache[n][i].refs++; + return NGX_OK; + } + } + + return NGX_DECLINED; +} + + +ngx_http_cache_entry_t *ngx_http_cache_get_entry(ngx_http_request_t *r, + ngx_http_cache_ctx_t *ctx) +{ + time_t old; + ngx_uint_t n, i; + ngx_http_cache_entry_t *ce; + + old = ngx_time() + 1; + ce = NULL; + + n = ctx->crc % ctx->hash->hash; + for (i = 0; i < ctx->hash->nelts; i++) { + if (ctx->hash->cache[n][i].key.data == NULL) { + + /* a free entry is found */ + + ce = &ctx->hash->cache[n][i]; + break; + } + + if (ctx->hash->cache[n][i].refs == 0 + && old > ctx->hash->cache[n][i].accessed) + { + /* looking for the oldest cache entry that is not used right now */ + + old = ctx->hash->cache[n][i].accessed; + ce = &ctx->hash->cache[n][i]; + } + } + + if (ce) { + if (ce->key.data) { + if (ctx->key.len > ce->key.len) { + ngx_free(ce->key.data); + ce->key.data = NULL; + } + } + + if (ce->key.data) { + ce->key.data = ngx_alloc(ctx->key.len, r->connection->log); + if (ce->key.data == NULL) { + return NULL; + } + } + + ngx_memcpy(ce->key.data, ctx->key.data, ctx->key.len); + + ce->key.len = ctx->key.len; + ce->crc = ctx->crc; + } + + return ce; +} + int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq) { @@ -138,6 +248,48 @@ ngx_log_debug(ctx->log, "EXPIRED"); } +int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx, + ngx_str_t *temp_file) +{ + int retry; + ngx_err_t err; + + retry = 0; + + for ( ;; ) { + if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) { + return NGX_OK; + } + + err = ngx_errno; + +#if (WIN32) + if (err == NGX_EEXIST) { + if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool) + == NGX_ERROR) + { + return NGX_ERROR; + } + } +#endif + + if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) { + ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, + ngx_rename_file_n "(\"%s\", \"%s\") failed", + temp_file->data, ctx->file.name.data); + + return NGX_ERROR; + } + + if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) { + return NGX_ERROR; + } + + retry = 1; + } +} + + int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name, ngx_dir_t *dir) { @@ -182,45 +334,69 @@ int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name, } -int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx, - ngx_str_t *temp_file) +/* 32-bit crc16 */ + +static int ngx_crc(char *data, size_t len) { - int retry; - ngx_err_t err; + uint32_t sum; - retry = 0; + for (sum = 0; len; len--) { + /* + * gcc 2.95.2 x86 and icc 7.1.006 compile that operator + * into the single rol opcode. + * msvc 6.0sp2 compiles it into four opcodes. + */ + sum = sum >> 1 | sum << 31; - for ( ;; ) { - if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) { - return NGX_OK; - } + sum += *data++; + } - err = ngx_errno; + return sum; +} -#if (WIN32) - if (err == NGX_EEXIST) { - if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool) - == NGX_ERROR) - { - return NGX_ERROR; - } - } -#endif - if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) { - ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, - ngx_rename_file_n "(\"%s\", \"%s\") failed", - temp_file->data, ctx->file.name.data); +static void *ngx_http_cache_create_conf(ngx_conf_t *cf) +{ + ngx_http_cache_conf_t *conf; - return NGX_ERROR; - } + if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_conf_t)))) { + return NGX_CONF_ERROR; + } - if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) { - return NGX_ERROR; - } + return conf; +} - retry = 1; + +static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, + void *parent, void *child) +{ + ngx_http_cache_conf_t *prev = parent; + ngx_http_cache_conf_t *conf = child; + + if (conf->hash == NULL) { + if (prev->hash) { + conf->hash = prev->hash; + + } else { + conf->hash = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t)); + if (conf->hash == NULL) { + return NGX_CONF_ERROR; + } + + conf->hash->hash = NGX_HTTP_CACHE_HASH; + conf->hash->nelts = NGX_HTTP_CACHE_NELTS; + + conf->hash->cache = ngx_pcalloc(cf->pool, + NGX_HTTP_CACHE_HASH + * NGX_HTTP_CACHE_NELTS + * sizeof(ngx_http_cache_entry_t)); + if (conf->hash->cache == NULL) { + return NGX_CONF_ERROR; + } + } } + + return NGX_CONF_OK; } @@ -261,7 +437,7 @@ typedef struct { typedef struct { - u_int32_t crc; + uint32_t crc; ngx_str_t uri; ngx_http_cache_t *cache; } ngx_http_cache_hash_entry_t; @@ -269,7 +445,7 @@ typedef struct { typedef struct { ngx_http_cache_t *cache; - u_int32_t crc; + uint32_t crc; int n; } ngx_http_cache_handle_t; @@ -305,7 +481,7 @@ int ngx_http_cache_get(ngx_http_cache_hash_t *cache_hash, int ngx_crc(char *data, size_t len) { - u_int32_t sum; + uint32_t sum; for (sum = 0; len; len--) { /* diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h index 70a792842..6e8042df4 100644 --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -18,32 +18,52 @@ typedef struct { typedef struct { - u_int32_t crc; + uint32_t crc; ngx_str_t key; ngx_fd_t fd; off_t size; void *data; /* mmap, memory */ time_t accessed; time_t last_modified; - time_t updated; /* no needed with kqueue */ + time_t updated; /* no needed with kqueue */ int refs; int flags; } ngx_http_cache_entry_t; +#define NGX_HTTP_CACHE_HASH 1021 +#define NGX_HTTP_CACHE_NELTS 4 typedef struct { - ngx_file_t file; - ngx_str_t key; - u_char md5[16]; - ngx_path_t *path; - ngx_hunk_t *buf; - time_t expires; - time_t last_modified; - time_t date; - off_t length; - ssize_t header_size; - size_t file_start; - ngx_log_t *log; + ngx_http_cache_entry_t **cache; + size_t hash; + size_t nelts; + time_t life_time; + time_t check_time; + ngx_pool_t *pool; +} ngx_http_cache_hash_t; + + +typedef struct { + ngx_http_cache_hash_t *hash; +} ngx_http_cache_conf_t; + + +typedef struct { + ngx_http_cache_hash_t *hash; + ngx_http_cache_entry_t *cache; + ngx_file_t file; + ngx_str_t key; + uint32_t crc; + u_char md5[16]; + ngx_path_t *path; + ngx_hunk_t *buf; + time_t expires; + time_t last_modified; + time_t date; + off_t length; + ssize_t header_size; + size_t file_start; + ngx_log_t *log; } ngx_http_cache_ctx_t; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 086e57dd4..4018f4188 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -88,7 +88,7 @@ static ngx_command_t ngx_http_core_commands[] = { NULL}, {ngx_string("location"), - NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, + NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, ngx_location_block, NGX_HTTP_SRV_CONF_OFFSET, 0, @@ -368,19 +368,27 @@ static void ngx_http_run_phases(ngx_http_request_t *r) int ngx_http_find_location_config(ngx_http_request_t *r) { - int i, rc; + ngx_int_t i, rc, exact; ngx_str_t *auto_redirect; ngx_http_core_loc_conf_t *clcf, **clcfp; ngx_http_core_srv_conf_t *cscf; cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); auto_redirect = NULL; + exact = 0; clcfp = cscf->locations.elts; for (i = 0; i < cscf->locations.nelts; i++) { -#if 0 -ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data); + +#if 1 +ngx_log_debug(r->connection->log, "trans: %s: %d" _ + clcfp[i]->name.data _ clcfp[i]->exact_match); #endif + + if (clcfp[i]->regex) { + break; + } + if (clcfp[i]->auto_redirect && r->uri.len == clcfp[i]->name.len - 1 && ngx_strncmp(r->uri.data, clcfp[i]->name.data, @@ -406,6 +414,50 @@ ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); r->connection->log->file = clcf->err_log->file; r->connection->log->log_level = clcf->err_log->log_level; + + if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) { + exact = 1; + break; + } + } + } + + if (!exact && !auto_redirect) { + /* regex matches */ + + for (/* void */; i < cscf->locations.nelts; i++) { + +#if 1 +ngx_log_debug(r->connection->log, "trans: %s: %d" _ + clcfp[i]->name.data _ clcfp[i]->exact_match); +#endif + + if (!clcfp[i]->regex) { + continue; + } + + rc = ngx_regex_exec(clcfp[i]->regex, &r->uri); + + if (rc == NGX_DECLINED) { + continue; + } + + if (rc < 0) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + ngx_regex_exec_n + " failed: %d on \"%s\" using \"%s\"", + rc, r->uri.data, clcfp[i]->name.data); + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + /* match */ + + r->loc_conf = clcfp[i]->loc_conf; + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + r->connection->log->file = clcf->err_log->file; + r->connection->log->log_level = clcf->err_log->log_level; + + break; } } @@ -669,37 +721,58 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) } -static int ngx_cmp_locations(const void *first, const void *second) +static int ngx_cmp_locations(const void *one, const void *two) { - ngx_http_core_loc_conf_t *one = *(ngx_http_core_loc_conf_t **) first; - ngx_http_core_loc_conf_t *two = *(ngx_http_core_loc_conf_t **) second; + ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one; + ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two; + + ngx_int_t rc; + + if (first->regex && !second->regex) { + /* shift regex matches to the end */ + return 1; + } + + if (first->regex || second->regex) { + /* do not sort regex matches */ + return 0; + } + + rc = ngx_strcmp(first->name.data, second->name.data); - return ngx_strcmp(one->name.data, two->name.data); + if (rc == 0 && second->exact_match) { + /* an exact match must be before the same inclusive one */ + return 1; + } + + return rc; } static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { - int m; char *rv; - ngx_str_t *location; + ngx_int_t m; + ngx_str_t *value, err; ngx_http_module_t *module; ngx_conf_t pvcf; ngx_http_conf_ctx_t *ctx, *pvctx; ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf, **clcfp; + char errstr[NGX_MAX_CONF_ERRSTR]; - ngx_test_null(ctx, - ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), - NGX_CONF_ERROR); + if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) { + return NGX_CONF_ERROR; + } pvctx = (ngx_http_conf_ctx_t *) cf->ctx; ctx->main_conf = pvctx->main_conf; ctx->srv_conf = pvctx->srv_conf; - ngx_test_null(ctx->loc_conf, - ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), - NGX_CONF_ERROR); + ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); + if (ctx->loc_conf == NULL) { + return NGX_CONF_ERROR; + } for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_HTTP_MODULE) { @@ -709,20 +782,61 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) module = ngx_modules[m]->ctx; if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index], - module->create_loc_conf(cf), - NGX_CONF_ERROR); + ctx->loc_conf[ngx_modules[m]->ctx_index] = + module->create_loc_conf(cf); + if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) { + return NGX_CONF_ERROR; + } } } clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; - location = (ngx_str_t *) cf->args->elts; - clcf->name.len = location[1].len; - clcf->name.data = location[1].data; clcf->loc_conf = ctx->loc_conf; + value = (ngx_str_t *) cf->args->elts; + + if (cf->args->nelts == 3) { + if (value[1].len == 1 && value[1].data[0] == '=') { + clcf->name.len = value[2].len; + clcf->name.data = value[2].data; + clcf->exact_match = 1; + + } else if ((value[1].len == 1 && value[1].data[0] == '~') + || (value[1].len == 2 + && value[1].data[0] == '~' + && value[1].data[1] == '*')) + { + err.len = NGX_MAX_CONF_ERRSTR; + err.data = errstr; + + clcf->regex = ngx_regex_compile(&value[2], + value[1].len == 2 ? NGX_REGEX_CASELESS: 0, + cf->pool, &err); + + if (clcf->regex == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); + return NGX_CONF_ERROR; + } + + clcf->name.len = value[2].len; + clcf->name.data = value[2].data; + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid location modifier \"%s\"", + value[1].data); + return NGX_CONF_ERROR; + } + + } else { + clcf->name.len = value[1].len; + clcf->name.data = value[1].data; + } + cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; - ngx_test_null(clcfp, ngx_push_array(&cscf->locations), NGX_CONF_ERROR); + if (!(clcfp = ngx_push_array(&cscf->locations))) { + return NGX_CONF_ERROR; + } *clcfp = clcf; pvcf = *cf; @@ -911,6 +1025,10 @@ static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf) lcf->err_log = NULL; lcf->error_pages = NULL; + lcf->regex = NULL; + lcf->exact_match = 0; + lcf->auto_redirect = 0; + */ lcf->client_body_timeout = NGX_CONF_UNSET; @@ -1079,7 +1197,7 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - ls->addr = *(u_int32_t *)(h->h_addr_list[0]); + ls->addr = *(in_addr_t *)(h->h_addr_list[0]); } return NGX_CONF_OK; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 695d2e5c0..20f124c75 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -8,7 +8,7 @@ typedef struct { - u_int32_t addr; + in_addr_t addr; int port; int family; int flags; /* 'default' */ @@ -65,7 +65,7 @@ typedef struct { typedef struct { - u_int32_t addr; + in_addr_t addr; ngx_array_t names; /* array of ngx_http_server_name_t */ ngx_http_core_srv_conf_t *core_srv_conf; /* default server conf for this address:port */ @@ -128,6 +128,10 @@ typedef struct { int msie_padding; /* msie_padding */ ngx_array_t *error_pages; /* error_page */ + ngx_regex_t *regex; + + unsigned exact_match:1; + unsigned auto_redirect:1; ngx_log_t *err_log; diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c index 25107bf3e..6e39f45b8 100644 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -266,7 +266,7 @@ static int ngx_http_header_filter(ngx_http_request_t *r) #endif h->last += ngx_snprintf(h->last, /* 2^64 */ sizeof("Content-Length: 18446744073709551616" CRLF), - "Content-Length: " OFF_FMT CRLF, + "Content-Length: " OFF_T_FMT CRLF, r->headers_out.content_length_n); #if (NGX_HTTP_LOG_ALL_HEADERS_OUT) diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c index 9d4f65e9a..48ebd01a5 100644 --- a/src/http/ngx_http_log_handler.c +++ b/src/http/ngx_http_log_handler.c @@ -250,7 +250,7 @@ static char *ngx_http_log_status(ngx_http_request_t *r, char *buf, static char *ngx_http_log_length(ngx_http_request_t *r, char *buf, uintptr_t data) { - return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_FMT, + return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_T_FMT, r->connection->sent); } |