nginx-0.0.1-2003-11-28-11:40:40 import

This commit is contained in:
Igor Sysoev 2003-11-28 08:40:40 +00:00
parent 764543e734
commit 877df63f34
6 changed files with 301 additions and 41 deletions

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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].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;
}
@ -379,6 +391,11 @@ static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
ngx_http_cache_conf_t *prev = parent;
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;
}

View File

@ -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;

View File

@ -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;