mirror of
https://github.com/nginx/nginx.git
synced 2024-11-29 01:09:53 +08:00
nginx-0.0.1-2003-11-28-11:40:40 import
This commit is contained in:
parent
764543e734
commit
877df63f34
@ -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;
|
||||
|
@ -7,6 +7,7 @@
|
||||
typedef struct {
|
||||
ngx_array_t indices;
|
||||
size_t max_index_len;
|
||||
ngx_http_cache_hash_t *cache;
|
||||
} ngx_http_index_conf_t;
|
||||
|
||||
|
||||
@ -19,9 +20,9 @@ typedef struct {
|
||||
#define NGX_HTTP_DEFAULT_INDEX "index.html"
|
||||
|
||||
|
||||
static int ngx_http_index_test_dir(ngx_http_request_t *r,
|
||||
static ngx_int_t 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,
|
||||
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);
|
||||
@ -34,12 +35,19 @@ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
|
||||
static ngx_command_t ngx_http_index_commands[] = {
|
||||
|
||||
{ngx_string("index"),
|
||||
{ ngx_string("index"),
|
||||
NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
|
||||
ngx_http_index_set_index,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL},
|
||||
NULL },
|
||||
|
||||
{ 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,7 +280,7 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
|
||||
}
|
||||
|
||||
|
||||
static int ngx_http_index_test_dir(ngx_http_request_t *r,
|
||||
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,7 +316,7 @@ ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data);
|
||||
}
|
||||
|
||||
|
||||
static int ngx_http_index_error(ngx_http_request_t *r,
|
||||
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) {
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user