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
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-11-28 11:40:40 +0300
committerIgor Sysoev <igor@sysoev.ru>2003-11-28 11:40:40 +0300
commit877df63f345e48bc2cb61dde86a207748051b81a (patch)
treea27f94499f27c0d079a6c7bbd3a33318e01345db /src
parent764543e73426fd00741483ff830cf09bfb73752f (diff)
nginx-0.0.1-2003-11-28-11:40:40 import
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_config.h5
-rw-r--r--src/http/modules/ngx_http_index_handler.c152
-rw-r--r--src/http/modules/ngx_http_static_handler.c2
-rw-r--r--src/http/ngx_http_cache.c158
-rw-r--r--src/http/ngx_http_cache.h14
-rw-r--r--src/os/unix/ngx_linux_sendfile_chain.c11
6 files changed, 301 insertions, 41 deletions
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 7e8c1b86d..ccb653b98 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -29,6 +29,11 @@
#endif
+/* STUB: ngx_mutex.h */
+#define ngx_mutex_lock(m)
+#define ngx_mutex_unlock(m)
+
+
/* STUB: autoconf */
typedef int ngx_int_t;
typedef u_int ngx_uint_t;
diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c
index e31bf3d09..ad3062436 100644
--- a/src/http/modules/ngx_http_index_handler.c
+++ b/src/http/modules/ngx_http_index_handler.c
@@ -5,8 +5,9 @@
typedef struct {
- ngx_array_t indices;
- size_t max_index_len;
+ ngx_array_t indices;
+ size_t max_index_len;
+ ngx_http_cache_hash_t *cache;
} ngx_http_index_conf_t;
@@ -19,10 +20,10 @@ typedef struct {
#define NGX_HTTP_DEFAULT_INDEX "index.html"
-static int ngx_http_index_test_dir(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx);
-static int ngx_http_index_error(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx, ngx_err_t err);
+static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
+ ngx_http_index_ctx_t *ctx);
+static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
+ ngx_http_index_ctx_t *ctx, ngx_err_t err);
static int ngx_http_index_init(ngx_cycle_t *cycle);
static void *ngx_http_index_create_conf(ngx_conf_t *cf);
@@ -32,16 +33,23 @@ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static ngx_command_t ngx_http_index_commands[] = {
+static ngx_command_t ngx_http_index_commands[] = {
- {ngx_string("index"),
- NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_index_set_index,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL},
+ { ngx_string("index"),
+ NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_http_index_set_index,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
- ngx_null_command
+ { ngx_string("index_cache"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
+ ngx_http_set_cache_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_index_conf_t, cache),
+ NULL },
+
+ ngx_null_command
};
@@ -81,19 +89,48 @@ ngx_module_t ngx_http_index_module = {
int ngx_http_index_handler(ngx_http_request_t *r)
{
- int rc;
char *name, *file;
+ uint32_t crc;
+ ngx_int_t rc;
ngx_str_t redirect, *index;
ngx_err_t err;
ngx_fd_t fd;
+ ngx_http_cache_t *cache;
ngx_http_index_ctx_t *ctx;
- ngx_http_index_conf_t *icf;
+ ngx_http_index_conf_t *ilcf;
ngx_http_core_loc_conf_t *clcf;
if (r->uri.data[r->uri.len - 1] != '/') {
return NGX_DECLINED;
}
+ ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
+
+ if (ilcf->cache) {
+ cache = ngx_http_cache_get(ilcf->cache, &r->uri, &crc);
+
+ngx_log_debug(r->connection->log, "index cache get: %x" _ cache);
+
+ if (cache && ilcf->cache->update >= ngx_cached_time - cache->updated) {
+
+ cache->accessed = ngx_cached_time;
+
+ redirect.len = cache->data.value.len;
+ if (!(redirect.data = ngx_palloc(r->pool, redirect.len + 1))) {
+ ngx_http_cache_unlock(ilcf->cache, cache);
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ ngx_memcpy(redirect.data, cache->data.value.data, redirect.len + 1);
+ ngx_http_cache_unlock(ilcf->cache, cache);
+
+ return ngx_http_internal_redirect(r, &redirect, NULL);
+ }
+
+ } else {
+ cache = NULL;
+ }
+
ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
if (ctx == NULL) {
ngx_http_create_ctx(r, ctx, ngx_http_index_module,
@@ -101,12 +138,11 @@ int ngx_http_index_handler(ngx_http_request_t *r)
NGX_HTTP_INTERNAL_SERVER_ERROR);
}
- icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (r->path.data == NULL) {
r->path_allocated = clcf->doc_root.len + r->uri.len
- + icf->max_index_len;
+ + ilcf->max_index_len;
ngx_test_null(r->path.data,
ngx_palloc(r->pool, r->path_allocated),
NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -121,8 +157,8 @@ int ngx_http_index_handler(ngx_http_request_t *r)
file = redirect.data + r->uri.len;
}
- index = icf->indices.elts;
- for (/* void */; ctx->index < icf->indices.nelts; ctx->index++) {
+ index = ilcf->indices.elts;
+ for (/* void */; ctx->index < ilcf->indices.nelts; ctx->index++) {
if (index[ctx->index].data[0] == '/') {
name = index[ctx->index].data;
@@ -185,6 +221,58 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
+ index[ctx->index].len;
}
+ if (ilcf->cache) {
+
+ if (cache) {
+ if (redirect.len == cache->data.value.len
+ && ngx_memcmp(cache->data.value.data, redirect.data,
+ redirect.len) == 0)
+ {
+ cache->accessed = ngx_cached_time;
+ cache->updated = ngx_cached_time;
+ ngx_http_cache_unlock(ilcf->cache, cache);
+
+ return ngx_http_internal_redirect(r, &redirect, NULL);
+
+ } else {
+ if (redirect.len > cache->data.value.len) {
+ ngx_free(cache->data.value.data);
+ cache->data.value.data = NULL;
+ }
+ }
+ }
+
+ if (cache == NULL) {
+ cache = ngx_http_cache_alloc(ilcf->cache, &r->uri, crc,
+ r->connection->log);
+ }
+
+ngx_log_debug(r->connection->log, "index cache alloc: %x" _ cache);
+
+ if (cache) {
+ cache->fd = NGX_INVALID_FILE;
+ cache->accessed = ngx_cached_time;
+ cache->last_modified = 0;
+ cache->updated = ngx_cached_time;
+
+ cache->data.value.len = redirect.len;
+ if (cache->data.value.data == NULL) {
+ cache->data.value.data = ngx_alloc(redirect.len + 1,
+ r->connection->log);
+ if (cache->data.value.data == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+ ngx_memcpy(cache->data.value.data, redirect.data,
+ redirect.len + 1);
+ }
+ }
+
+ if (cache) {
+ ngx_http_cache_unlock(ilcf->cache, cache);
+ }
+
return ngx_http_internal_redirect(r, &redirect, NULL);
}
@@ -192,8 +280,8 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
}
-static int ngx_http_index_test_dir(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx)
+static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
+ ngx_http_index_ctx_t *ctx)
{
ngx_err_t err;
@@ -228,8 +316,8 @@ ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data);
}
-static int ngx_http_index_error(ngx_http_request_t *r,
- ngx_http_index_ctx_t *ctx, ngx_err_t err)
+static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
+ ngx_http_index_ctx_t *ctx, ngx_err_t err)
{
if (err == NGX_EACCES) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
@@ -273,6 +361,8 @@ static void *ngx_http_index_create_conf(ngx_conf_t *cf)
NGX_CONF_ERROR);
conf->max_index_len = 0;
+ conf->cache = NULL;
+
return conf;
}
@@ -317,6 +407,10 @@ static char *ngx_http_index_merge_conf(ngx_conf_t *cf,
conf->max_index_len = prev->max_index_len;
}
+ if (conf->cache == NULL) {
+ conf->cache = prev->cache;
+ }
+
return NGX_CONF_OK;
}
@@ -326,14 +420,14 @@ static char *ngx_http_index_merge_conf(ngx_conf_t *cf,
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{
- ngx_http_index_conf_t *icf = conf;
+ ngx_http_index_conf_t *ilcf = conf;
int i;
ngx_str_t *index, *value;
value = cf->args->elts;
- if (value[1].data[0] == '/' && icf->indices.nelts == 0) {
+ if (value[1].data[0] == '/' && ilcf->indices.nelts == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"first index \"%s\" in \"%s\" directive "
"must not be absolute",
@@ -349,12 +443,12 @@ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
return NGX_CONF_ERROR;
}
- ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR);
+ ngx_test_null(index, ngx_push_array(&ilcf->indices), NGX_CONF_ERROR);
index->len = value[i].len;
index->data = value[i].data;
- if (icf->max_index_len < index->len + 1) {
- icf->max_index_len = index->len + 1;
+ if (ilcf->max_index_len < index->len + 1) {
+ ilcf->max_index_len = index->len + 1;
}
}
diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c
index 42dd14a21..651f6d741 100644
--- a/src/http/modules/ngx_http_static_handler.c
+++ b/src/http/modules/ngx_http_static_handler.c
@@ -97,7 +97,7 @@ ngx_log_debug(r->connection->log, "cache get: %x" _ cache);
if (cache
&& ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
- || ccf->open_files->check_time >= ngx_time() - cache->updated))
+ || ccf->open_files->update >= ngx_cached_time - cache->updated))
{
cache->refs++;
r->file.fd = cache->fd;
diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c
index b1cd52c54..f5ef9206c 100644
--- a/src/http/ngx_http_cache.c
+++ b/src/http/ngx_http_cache.c
@@ -88,8 +88,9 @@ ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *cache,
*crc = ngx_crc(key->data, key->len);
- c = cache->elts
- + *crc % cache->hash * cache->nelts * sizeof(ngx_http_cache_t);
+ c = cache->elts + *crc % cache->hash * cache->nelts;
+
+ ngx_mutex_lock(&cache->mutex);
for (i = 0; i < cache->nelts; i++) {
if (c[i].crc == *crc
@@ -97,10 +98,13 @@ ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *cache,
&& ngx_rstrncmp(c[i].key.data, key->data, key->len) == 0)
{
c[i].refs++;
+ ngx_mutex_unlock(&cache->mutex);
return &c[i];
}
}
+ ngx_mutex_unlock(&cache->mutex);
+
return NULL;
}
@@ -113,24 +117,28 @@ ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache,
ngx_uint_t i;
ngx_http_cache_t *c, *found;
- old = ngx_time() + 1;
+ old = ngx_cached_time + 1;
found = NULL;
- c = cache->elts
- + crc % cache->hash * cache->nelts * sizeof(ngx_http_cache_t);
+ c = cache->elts + crc % cache->hash * cache->nelts;
+
+ ngx_mutex_lock(&cache->mutex);
for (i = 0; i < cache->nelts; i++) {
- if (c[i].key.data == NULL) {
+ if (c[i].refs > 0) {
+ /* a busy entry */
+ continue;
+ }
+ if (c[i].key.data == NULL) {
/* a free entry is found */
-
found = &c[i];
break;
}
- /* looking for the oldest cache entry that is not been using */
+ /* looking for the oldest cache entry */
- if (c[i].refs == 0 && old > c[i].accessed) {
+ if (old > c[i].accessed) {
old = c[i].accessed;
found = &c[i];
@@ -148,6 +156,7 @@ ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache,
if (found->key.data == NULL) {
found->key.data = ngx_alloc(key->len, log);
if (found->key.data == NULL) {
+ ngx_mutex_unlock(&cache->mutex);
return NULL;
}
}
@@ -157,9 +166,12 @@ ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache,
found->crc = crc;
found->key.len = key->len;
found->refs = 1;
+ found->count = 0;
found->deleted = 0;
}
+ ngx_mutex_unlock(&cache->mutex);
+
return found;
}
@@ -380,6 +392,11 @@ static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
ngx_http_cache_conf_t *conf = child;
if (conf->open_files == NULL) {
+ conf->open_files = prev->open_files;
+ }
+
+#if 0
+ if (conf->open_files == NULL) {
if (prev->open_files) {
conf->open_files = prev->open_files;
@@ -402,6 +419,129 @@ static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
}
}
}
+#endif
+
+ return NGX_CONF_OK;
+}
+
+
+char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ char *p = conf;
+
+ ngx_int_t i, dup, invalid;
+ ngx_str_t *value, line;
+ ngx_http_cache_hash_t *ch, **chp;
+
+ chp = (ngx_http_cache_hash_t **) (p + cmd->offset);
+ if (*chp) {
+ return "is duplicate";
+ }
+
+ if (!(ch = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t)))) {
+ return NGX_CONF_ERROR;
+ }
+ *chp = ch;
+
+ dup = 0;
+ invalid = 0;
+
+ value = cf->args->elts;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (value[i].data[1] != '=') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid value \"%s\"", value[i].data);
+ return NGX_CONF_ERROR;
+ }
+
+ switch (value[i].data[0]) {
+
+ case 'h':
+ if (ch->hash) {
+ dup = 1;
+ break;
+ }
+
+ ch->hash = ngx_atoi(value[i].data + 2, value[i].len - 2);
+ if (ch->hash == (size_t) NGX_ERROR || ch->hash == 0) {
+ invalid = 1;
+ break;
+ }
+
+ continue;
+
+ case 'n':
+ if (ch->nelts) {
+ dup = 1;
+ break;
+ }
+
+ ch->nelts = ngx_atoi(value[i].data + 2, value[i].len - 2);
+ if (ch->nelts == (size_t) NGX_ERROR || ch->nelts == 0) {
+ invalid = 1;
+ break;
+ }
+
+ continue;
+
+ case 'l':
+ if (ch->life) {
+ dup = 1;
+ break;
+ }
+
+ line.len = value[i].len - 2;
+ line.data = value[i].data + 2;
+
+ ch->life = ngx_parse_time(&line, 1);
+ if (ch->life == NGX_ERROR || ch->life == 0) {
+ invalid = 1;
+ break;
+ }
+
+ continue;
+
+ case 'u':
+ if (ch->update) {
+ dup = 1;
+ break;
+ }
+
+ line.len = value[i].len - 2;
+ line.data = value[i].data + 2;
+
+ ch->update = ngx_parse_time(&line, 1);
+ if (ch->update == NGX_ERROR || ch->update == 0) {
+ invalid = 1;
+ break;
+ }
+
+ continue;
+
+ default:
+ invalid = 1;
+ }
+
+ if (dup) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "duplicate value \"%s\"", value[i].data);
+ return NGX_CONF_ERROR;
+ }
+
+ if (invalid) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid value \"%s\"", value[i].data);
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ ch->elts = ngx_pcalloc(cf->pool,
+ ch->hash * ch->nelts * sizeof(ngx_http_cache_t));
+ if (ch->elts == NULL) {
+ return NGX_CONF_ERROR;
+ }
return NGX_CONF_OK;
}
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
index 768ab0f56..aa9d28970 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -44,8 +44,8 @@ typedef struct {
ngx_http_cache_t *elts;
size_t hash;
size_t nelts;
- time_t life_time;
- time_t check_time;
+ time_t life;
+ time_t update;
ngx_pool_t *pool;
} ngx_http_cache_hash_t;
@@ -74,6 +74,13 @@ typedef struct {
} ngx_http_cache_conf_t;
+#define ngx_http_cache_unlock(ch, ce) \
+ ngx_mutex_lock(&ch->mutex); \
+ ce->refs--; \
+ ngx_mutex_unlock(&ch->mutex);
+
+
+
#define NGX_HTTP_CACHE_STALE 1
#define NGX_HTTP_CACHE_AGED 2
#define NGX_HTTP_CACHE_THE_SAME 3
@@ -93,6 +100,9 @@ ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache,
int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
ngx_dir_t *dir);
+char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+
+
extern ngx_module_t ngx_http_cache_module;
diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c
index 9b311b21e..d96d93df7 100644
--- a/src/os/unix/ngx_linux_sendfile_chain.c
+++ b/src/os/unix/ngx_linux_sendfile_chain.c
@@ -4,6 +4,17 @@
#include <ngx_event.h>
+/*
+ * On Linux up to 2.4.21 sendfile() (syscall #187) works with 32-bit
+ * offsets only and the including <sys/sendfile.h> breaks building
+ * if off_t is 64 bit wide. So we use own sendfile() definition where
+ * offset paramter is int32_t. It allows to use sendfile() with
+ * the file parts below 2G.
+ *
+ * Linux 2.4.21 has a new sendfile64() syscall #239.
+ */
+
+
ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
{
int rc;