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/http
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-11-25 23:44:56 +0300
committerIgor Sysoev <igor@sysoev.ru>2003-11-25 23:44:56 +0300
commita8fa0a6a37b6e90324e0dcbf4733324199623841 (patch)
tree1a7edec9aa04946afc22299bf587823488fb492f /src/http
parentd9d0ca12688034d481e2f1f5cf13a098338ec31d (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.c2
-rw-r--r--src/http/modules/ngx_http_not_modified_filter.c6
-rw-r--r--src/http/modules/ngx_http_range_filter.c22
-rw-r--r--src/http/modules/ngx_http_static_handler.c36
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_cache.c5
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.c32
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_upstream.c21
-rw-r--r--src/http/ngx_http_busy_lock.c2
-rw-r--r--src/http/ngx_http_cache.c244
-rw-r--r--src/http/ngx_http_cache.h48
-rw-r--r--src/http/ngx_http_core_module.c166
-rw-r--r--src/http/ngx_http_core_module.h8
-rw-r--r--src/http/ngx_http_header_filter.c2
-rw-r--r--src/http/ngx_http_log_handler.c2
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);
}