📄 cache.c
字号:
/* * Copyright (c) 1999-2000 Caucho Technology. All rights reserved. * * Caucho Technology permits redistribution, modification and use * of this file in source and binary form ("the Software") under the * Caucho Public License ("the License"). In particular, the following * conditions must be met: * * 1. Each copy or derived work of the Software must preserve the copyright * notice and this notice unmodified. * * 2. Redistributions of the Software in source or binary form must include * an unmodified copy of the License, normally in a plain ASCII text * * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and * may not be used to endorse products derived from this software. * "Resin" or "Caucho" may not appear in the names of products derived * from this software. * * 4. Caucho Technology requests that attribution be given to Resin * in any manner possible. We suggest using the "Resin Powered" * button or creating a "powered by Resin(tm)" link to * http://www.caucho.com for each page served by Resin. * * This Software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL Caucho OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES. */#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <pthread.h>#include "cse.h"#include "proxy.h"struct cache_t { pthread_mutex_t lock; int capacity; int mask; cache_entry_t **entries;};cache_t *cache_create(int initial_capacity){ int capacity; cache_t *cache; int size; for (capacity = 32; capacity < initial_capacity; capacity *= 2) { } cache = cse_malloc(sizeof(cache_t)); memset(cache, 0, sizeof(cache_t)); pthread_mutex_init(&cache->lock, 0); cache->capacity = capacity; cache->mask = capacity - 1; size = capacity * sizeof(cache_entry_t *); cache->entries = (cache_entry_t **) cse_malloc(size); memset(cache->entries, 0, size); return cache;}static cache_entry_t *cache_entry_create(char *host, char *uri){ cache_entry_t *entry; entry = cse_malloc(sizeof(cache_entry_t)); memset(entry, 0, sizeof(cache_entry_t)); entry->host = strdup(host); entry->uri = strdup(uri); entry->fd = -1; return entry; }static cache_entry_t *cache_get(cache_t *cache, request_t *req, int *p_fill){ int hash = 37; cache_entry_t *old_entry = 0; cache_entry_t *entry = 0; char *host = req->host; char *uri = req->uri; int i; if (! host) host = ""; if (! uri) uri = ""; for (i = 0; host[i]; i++) hash = 65521 * hash + host[i] + 19; for (i = 0; uri[i]; i++) hash = 65521 * hash + uri[i] + 19; hash = hash & cache->mask; pthread_mutex_lock(&cache->lock); entry = cache->entries[hash]; if (! entry) { entry = cache_entry_create(host, uri); cache->entries[hash] = entry; entry->use_count++; entry->is_cacheable = 1; } else if (entry->host && ! strcmp(entry->host, host) && entry->uri && ! strcmp(entry->uri, uri)) { if (entry->is_cacheable) entry->use_count++; else entry = 0; } else { old_entry = entry; old_entry->is_dead = 1; entry = cache_entry_create(host, uri); cache->entries[hash] = entry; entry->use_count++; entry->is_cacheable = 1; } pthread_mutex_unlock(&cache->lock); return entry;}intcache_fill(cache_t *cache, request_t *req, response_t *res){ int fill = 0; cache_entry_t *entry; entry = cache_get(cache, req, &fill); if (! entry || entry->is_dead) return 0; else if (entry->data) { cse_rprintf(res, "HTTP/1.0 200 OK"); cse_rwrite(res, entry->headers, entry->header_size); cse_flush_headers(res, entry->length); cse_rwrite(res, entry->data, entry->length); return 1; } else if (entry->cache_file) { int fd; char buf[8192]; char *data; int sublen; int len; fd = open(entry->cache_file, O_RDONLY); if (fd < 0) { entry->is_cacheable = 0; return 0; } cse_rprintf(res, "HTTP/1.0 200 OK"); cse_rwrite(res, entry->headers, entry->header_size); cse_flush_headers(res, entry->length); entry->data = cse_malloc(entry->length); sublen = entry->length; data = entry->data; while (sublen > 0 && (len = read(fd, data, entry->length)) > 0) { cse_rwrite(res, data, len); sublen -= len; data += len; } close(fd); return 1; } else if (entry->is_cacheable) res->entry = entry; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -