diff options
author | Igor Sysoev <igor@sysoev.ru> | 2009-03-23 13:14:51 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2009-03-23 13:14:51 +0000 |
commit | 52859f2f1309fc8452f1cf182b712ae2d72bc40c (patch) | |
tree | f87d424675f857d0dcebdc80ce3828389d75a69b /src/http/ngx_http_cache.c | |
parent | 1af7090b5091ebbee1cd9354fe8a702e601a8ce0 (diff) | |
download | nginx-52859f2f1309fc8452f1cf182b712ae2d72bc40c.tar.gz nginx-52859f2f1309fc8452f1cf182b712ae2d72bc40c.zip |
a prelimiary proxy cache support
Diffstat (limited to 'src/http/ngx_http_cache.c')
-rw-r--r-- | src/http/ngx_http_cache.c | 576 |
1 files changed, 0 insertions, 576 deletions
diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c deleted file mode 100644 index 8471459af..000000000 --- a/src/http/ngx_http_cache.c +++ /dev/null @@ -1,576 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_http.h> - - -#if 0 - -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 */ - - NULL, /* create location configuration */ - NULL /* 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 process */ -}; - -#endif - - -static ngx_int_t ngx_http_cache_create(ngx_http_request_t *r) -{ - ngx_str_t *key; - - if (!(r->cache = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)))) { - return NGX_ERROR; - } - - if (ngx_array_init(&r->cache->key, r->pool, 5, sizeof(ngx_str_t)) - == NGX_ERROR) - { - return NGX_ERROR; - } - - /* preallocate the primary key */ - - if (!(key = ngx_array_push(&r->cache->key))) { - return NGX_ERROR; - } - - key->len = 0; - key->data = NULL; - - /* - * we use offsetof() because sizeof() pads the struct size to the int size - */ - - r->cache->header_size = offsetof(ngx_http_cache_header_t, key); - - r->cache->log = r->connection->log; - r->cache->file.log = r->connection->log; - - return NGX_OK; -} - - -ngx_int_t ngx_http_cache_get(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) -{ - ngx_str_t *key; - ngx_http_cache_t *c; - - if (r->cache == NULL) { - if (ngx_http_cache_create(r) == NGX_ERROR) { - return NGX_ABORT; - } - } - - c = r->cache; - key = c->key.elts; - - if (ctx->primary) { - key[0] = ctx->key; - c->header_size += ctx->key.len; - c->key_len += ctx->key.len; - c->buf = ctx->buf; - - } else { - if (key[0].len == 0) { - key[0] = r->uri; - c->header_size += r->uri.len; - c->key_len += ctx->key.len; - } - - if (!(key = ngx_array_push(&r->cache->key))) { - return NGX_ABORT; - } - - c->header_size += ctx->key.len; - c->key_len += ctx->key.len; - } - -#if 0 - - if (ctx->memory) { - ngx_http_memory_cache_get(r, ctx); - } - -#endif - - if (ctx->file) { - return ngx_http_file_cache_get(r, ctx); - } - - return NGX_DECLINED; -} - - -#if 0 - - -ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *hash, - ngx_http_cleanup_t *cleanup, - ngx_str_t *key, uint32_t *crc) -{ - ngx_uint_t i; - ngx_http_cache_t *c; - - *crc = ngx_crc(key->data, key->len); - - c = hash->elts + *crc % hash->hash * hash->nelts; - - if (ngx_mutex_lock(&hash->mutex) == NGX_ERROR) { - return (void *) NGX_ERROR; - } - - for (i = 0; i < hash->nelts; i++) { - if (c[i].crc == *crc - && c[i].key.len == key->len - && ngx_rstrncmp(c[i].key.data, key->data, key->len) == 0) - { -#if 0 - if (c[i].expired) { - ngx_mutex_unlock(&hash->mutex); - return (void *) NGX_AGAIN; - } -#endif - - c[i].refs++; - - if ((!(c[i].notify && (ngx_event_flags & NGX_USE_KQUEUE_EVENT))) - && (ngx_cached_time - c[i].updated >= hash->update)) - { - c[i].expired = 1; - } - - ngx_mutex_unlock(&hash->mutex); - - if (cleanup) { - cleanup->data.cache.hash = hash; - cleanup->data.cache.cache = &c[i]; - cleanup->valid = 1; - cleanup->cache = 1; - } - - return &c[i]; - } - } - - ngx_mutex_unlock(&hash->mutex); - - return NULL; -} - - -ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *hash, - ngx_http_cache_t *cache, - ngx_http_cleanup_t *cleanup, - ngx_str_t *key, uint32_t crc, - ngx_str_t *value, ngx_log_t *log) -{ - time_t old; - ngx_uint_t i; - ngx_http_cache_t *c; - - old = ngx_cached_time + 1; - - c = hash->elts + crc % hash->hash * hash->nelts; - - if (ngx_mutex_lock(&hash->mutex) == NGX_ERROR) { - return (void *) NGX_ERROR; - } - - if (cache == NULL) { - - /* allocate a new entry */ - - for (i = 0; i < hash->nelts; i++) { - if (c[i].refs > 0) { - /* a busy entry */ - continue; - } - - if (c[i].key.len == 0) { - /* a free entry is found */ - cache = &c[i]; - break; - } - - /* looking for the oldest cache entry */ - - if (old > c[i].accessed) { - - old = c[i].accessed; - cache = &c[i]; - } - } - - if (cache == NULL) { - ngx_mutex_unlock(&hash->mutex); - return NULL; - } - - ngx_http_cache_free(cache, key, value, log); - - if (cache->key.data == NULL) { - cache->key.data = ngx_alloc(key->len, log); - if (cache->key.data == NULL) { - ngx_http_cache_free(cache, NULL, NULL, log); - ngx_mutex_unlock(&hash->mutex); - return NULL; - } - } - - cache->key.len = key->len; - ngx_memcpy(cache->key.data, key->data, key->len); - - } else if (value) { - ngx_http_cache_free(cache, key, value, log); - } - - if (value) { - if (cache->data.value.data == NULL) { - cache->data.value.data = ngx_alloc(value->len, log); - if (cache->data.value.data == NULL) { - ngx_http_cache_free(cache, NULL, NULL, log); - ngx_mutex_unlock(&hash->mutex); - return NULL; - } - } - - cache->data.value.len = value->len; - ngx_memcpy(cache->data.value.data, value->data, value->len); - } - - cache->crc = crc; - cache->key.len = key->len; - - cache->refs = 1; - cache->count = 0; - - cache->deleted = 0; - cache->expired = 0; - cache->memory = 0; - cache->mmap = 0; - cache->notify = 0; - - if (cleanup) { - cleanup->data.cache.hash = hash; - cleanup->data.cache.cache = cache; - cleanup->valid = 1; - cleanup->cache = 1; - } - - ngx_mutex_unlock(&hash->mutex); - - return cache; -} - - -void ngx_http_cache_free(ngx_http_cache_t *cache, - ngx_str_t *key, ngx_str_t *value, ngx_log_t *log) -{ - if (cache->memory) { - if (cache->data.value.data - && (value == NULL || value->len > cache->data.value.len)) - { - ngx_free(cache->data.value.data); - cache->data.value.data = NULL; - } - } - - /* TODO: mmap */ - - cache->data.value.len = 0; - - if (cache->fd != NGX_INVALID_FILE) { - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, - "http cache close fd: %d", cache->fd); - - if (ngx_close_file(cache->fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - ngx_close_file_n " \"%s\" failed", - cache->key.data); - } - - cache->fd = NGX_INVALID_FILE; - } - - if (cache->key.data && (key == NULL || key->len > cache->key.len)) { - ngx_free(cache->key.data); - cache->key.data = NULL; - } - - cache->key.len = 0; - - cache->refs = 0; -} - - -void ngx_http_cache_lock(ngx_http_cache_hash_t *hash, ngx_http_cache_t *cache) -{ - if (ngx_mutex_lock(&hash->mutex) == NGX_ERROR) { - return; - } -} - - -void ngx_http_cache_unlock(ngx_http_cache_hash_t *hash, - ngx_http_cache_t *cache, ngx_log_t *log) -{ - if (ngx_mutex_lock(&hash->mutex) == NGX_ERROR) { - return; - } - - cache->refs--; - - if (cache->refs == 0 && cache->deleted) { - ngx_http_cache_free(cache, NULL, NULL, log); - } - - ngx_mutex_unlock(&hash->mutex); -} - - -#if 0 - -ngx_http_cache_add_file_event(ngx_http_cache_hash_t *hash, - ngx_http_cache_t *cache) -{ - ngx_event_t *ev; - ngx_http_cache_event_ctx_t *ctx; - - ev = &ngx_cycle->read_events[fd]; - ngx_memzero(ev, sizeof(ngx_event_t); - - ev->data = data; - ev->event_handler = ngx_http_cache_invalidate; - - return ngx_add_event(ev, NGX_VNODE_EVENT, 0); -} - - -void ngx_http_cache_invalidate(ngx_event_t *ev) -{ - ngx_http_cache_event_ctx_t *ctx; - - ctx = ev->data; - - ngx_http_cache_lock(&ctx->hash->mutex); - - if (ctx->cache->refs == 0) - ngx_http_cache_free(ctx->cache, NULL, NULL, ctx->log); - - } else { - ctx->cache->deleted = 1; - } - - ngx_http_cache_unlock(&ctx->hash->mutex); -} - -#endif - - -/* TODO: currently fd only */ - -ngx_int_t ngx_http_send_cached(ngx_http_request_t *r) -{ - ngx_int_t rc; - ngx_hunk_t *h; - ngx_chain_t out; - ngx_http_log_ctx_t *ctx; - - ctx = r->connection->log->data; - ctx->action = "sending response to client"; - - r->headers_out.status = NGX_HTTP_OK; - r->headers_out.content_length_n = r->cache->data.size; - r->headers_out.last_modified_time = r->cache->last_modified; - - if (ngx_http_set_content_type(r) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - /* we need to allocate all before the header would be sent */ - - if (!(h = ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)))) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (!(h->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)))) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - rc = ngx_http_send_header(r); - - if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { - return rc; - } - - h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST; - - h->file_pos = 0; - h->file_last = r->cache->data.size; - - h->file->fd = r->cache->fd; - h->file->log = r->connection->log; - - out.hunk = h; - out.next = NULL; - - return ngx_http_output_filter(r, &out); -} - - -char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *p = conf; - - ngx_int_t i, j, dup, invalid; - ngx_str_t *value, line; - ngx_http_cache_t *c; - 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; - } - - for (i = 0; i < (ngx_int_t) ch->hash; i++) { - c = ch->elts + i * ch->nelts; - - for (j = 0; j < (ngx_int_t) ch->nelts; j++) { - c[j].fd = NGX_INVALID_FILE; - } - } - - return NGX_CONF_OK; -} - - -#endif |