📄 mod_disk_cache.c
字号:
}static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *bb){ apr_bucket *e; apr_status_t rv; disk_cache_object_t *dobj = (disk_cache_object_t *) h->cache_obj->vobj; disk_cache_conf *conf = ap_get_module_config(r->server->module_config, &disk_cache_module); /* We write to a temp file and then atomically rename the file over * in file_cache_el_final(). */ if (!dobj->tfd) { rv = apr_file_mktemp(&dobj->tfd, dobj->tempfile, APR_CREATE | APR_WRITE | APR_BINARY | APR_BUFFERED | APR_EXCL, r->pool); if (rv != APR_SUCCESS) { return rv; } dobj->file_size = 0; } for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e)) { const char *str; apr_size_t length, written; apr_bucket_read(e, &str, &length, APR_BLOCK_READ); rv = apr_file_write_full(dobj->tfd, str, length, &written); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "cache_disk: Error when writing cache file for URL %s", h->cache_obj->key); /* Remove the intermediate cache file and return non-APR_SUCCESS */ file_cache_errorcleanup(dobj, r); return APR_EGENERAL; } dobj->file_size += written; if (dobj->file_size > conf->maxfs) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "cache_disk: URL %s failed the size check (%lu>%lu)", h->cache_obj->key, (unsigned long)dobj->file_size, (unsigned long)conf->maxfs); /* Remove the intermediate cache file and return non-APR_SUCCESS */ file_cache_errorcleanup(dobj, r); return APR_EGENERAL; } } /* Was this the final bucket? If yes, close the temp file and perform * sanity checks. */ if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { if (h->cache_obj->info.len <= 0) { /* If the target value of the content length is unknown * (h->cache_obj->info.len <= 0), check if connection has been * aborted by client to avoid caching incomplete request bodies. * * This can happen with large responses from slow backends like * Tomcat via mod_jk. */ if (r->connection->aborted) { ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, "disk_cache: Discarding body for URL %s " "because connection has been aborted.", h->cache_obj->key); /* Remove the intermediate cache file and return non-APR_SUCCESS */ file_cache_errorcleanup(dobj, r); return APR_EGENERAL; } /* XXX Fixme: file_size isn't constrained by size_t. */ h->cache_obj->info.len = dobj->file_size; } else if (h->cache_obj->info.len != dobj->file_size) { /* "Content-Length" and actual content disagree in size. Log that. */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "disk_cache: URL %s failed the size check (%lu != %lu)", h->cache_obj->key, (unsigned long)h->cache_obj->info.len, (unsigned long)dobj->file_size); /* Remove the intermediate cache file and return non-APR_SUCCESS */ file_cache_errorcleanup(dobj, r); return APR_EGENERAL; } if (dobj->file_size < conf->minfs) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "cache_disk: URL %s failed the size check (%lu<%lu)", h->cache_obj->key, (unsigned long)dobj->file_size, (unsigned long)conf->minfs); /* Remove the intermediate cache file and return non-APR_SUCCESS */ file_cache_errorcleanup(dobj, r); return APR_EGENERAL; } /* All checks were fine. Move tempfile to final destination */ /* Link to the perm file, and close the descriptor */ file_cache_el_final(dobj, r); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "disk_cache: Body for URL %s cached.", dobj->name); } return APR_SUCCESS;}static void *create_config(apr_pool_t *p, server_rec *s){ disk_cache_conf *conf = apr_pcalloc(p, sizeof(disk_cache_conf)); /* XXX: Set default values */ conf->dirlevels = DEFAULT_DIRLEVELS; conf->dirlength = DEFAULT_DIRLENGTH; conf->space = DEFAULT_CACHE_SIZE; conf->maxfs = DEFAULT_MAX_FILE_SIZE; conf->minfs = DEFAULT_MIN_FILE_SIZE; conf->expirychk = 1; conf->cache_root = NULL; conf->cache_root_len = 0; return conf;}/* * mod_disk_cache configuration directives handlers. */static const char*set_cache_root(cmd_parms *parms, void *in_struct_ptr, const char *arg){ disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); conf->cache_root = arg; conf->cache_root_len = strlen(arg); /* TODO: canonicalize cache_root and strip off any trailing slashes */ return NULL;}static const char*set_cache_size(cmd_parms *parms, void *in_struct_ptr, const char *arg){ disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); conf->space = atoi(arg); return NULL;}static const char*set_cache_gcint(cmd_parms *parms, void *in_struct_ptr, const char *arg){/* disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module);*/ /* XXX */ return NULL;}/* * Consider eliminating the next two directives in favor of * Ian's prime number hash... * key = hash_fn( r->uri) * filename = "/key % prime1 /key %prime2/key %prime3" */static const char*set_cache_dirlevels(cmd_parms *parms, void *in_struct_ptr, const char *arg){ disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); int val = atoi(arg); if (val < 1) return "CacheDirLevels value must be an integer greater than 0"; if (val * conf->dirlength > CACHEFILE_LEN) return "CacheDirLevels*CacheDirLength value must not be higher than 20"; conf->dirlevels = val; return NULL;}static const char*set_cache_dirlength(cmd_parms *parms, void *in_struct_ptr, const char *arg){ disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); int val = atoi(arg); if (val < 1) return "CacheDirLength value must be an integer greater than 0"; if (val * conf->dirlevels > CACHEFILE_LEN) return "CacheDirLevels*CacheDirLength value must not be higher than 20"; conf->dirlength = val; return NULL;}static const char*set_cache_exchk(cmd_parms *parms, void *in_struct_ptr, int flag){ disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); conf->expirychk = flag; return NULL;}static const char*set_cache_minfs(cmd_parms *parms, void *in_struct_ptr, const char *arg){ disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); conf->minfs = atoi(arg); return NULL;}static const char*set_cache_maxfs(cmd_parms *parms, void *in_struct_ptr, const char *arg){ disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); conf->maxfs = atoi(arg); return NULL;}static const char*set_cache_minetm(cmd_parms *parms, void *in_struct_ptr, const char *arg){ /* XXX disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); */ return NULL;}static const char*set_cache_gctime(cmd_parms *parms, void *in_struct_ptr, const char *arg){ /* XXX disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); */ return NULL;}static const char*add_cache_gcclean(cmd_parms *parms, void *in_struct_ptr, const char *arg, const char *arg1){ /* XXX disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); */ return NULL;}static const char*add_cache_gcclnun(cmd_parms *parms, void *in_struct_ptr, const char *arg, const char *arg1){ /* XXX disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); */ return NULL;}static const char*set_cache_maxgcmem(cmd_parms *parms, void *in_struct_ptr, const char *arg){ /* XXX disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, &disk_cache_module); */ return NULL;}static const command_rec disk_cache_cmds[] ={ AP_INIT_TAKE1("CacheRoot", set_cache_root, NULL, RSRC_CONF, "The directory to store cache files"), AP_INIT_TAKE1("CacheSize", set_cache_size, NULL, RSRC_CONF, "The maximum disk space used by the cache in KB"), AP_INIT_TAKE1("CacheGcInterval", set_cache_gcint, NULL, RSRC_CONF, "The interval between garbage collections, in hours"), AP_INIT_TAKE1("CacheDirLevels", set_cache_dirlevels, NULL, RSRC_CONF, "The number of levels of subdirectories in the cache"), AP_INIT_TAKE1("CacheDirLength", set_cache_dirlength, NULL, RSRC_CONF, "The number of characters in subdirectory names"), AP_INIT_FLAG("CacheExpiryCheck", set_cache_exchk, NULL, RSRC_CONF, "on if cache observes Expires date when seeking files"), AP_INIT_TAKE1("CacheMinFileSize", set_cache_minfs, NULL, RSRC_CONF, "The minimum file size to cache a document"), AP_INIT_TAKE1("CacheMaxFileSize", set_cache_maxfs, NULL, RSRC_CONF, "The maximum file size to cache a document"), AP_INIT_TAKE1("CacheTimeMargin", set_cache_minetm, NULL, RSRC_CONF, "The minimum time margin to cache a document"), AP_INIT_TAKE1("CacheGcDaily", set_cache_gctime, NULL, RSRC_CONF, "The time of day for garbage collection (24 hour clock)"), AP_INIT_TAKE2("CacheGcUnused", add_cache_gcclnun, NULL, RSRC_CONF, "The time in hours to retain unused file that match a url"), AP_INIT_TAKE2("CacheGcClean", add_cache_gcclean, NULL, RSRC_CONF, "The time in hours to retain unchanged files that match a url"), AP_INIT_TAKE1("CacheGcMemUsage", set_cache_maxgcmem, NULL, RSRC_CONF, "The maximum kilobytes of memory used for garbage collection"), {NULL}};static const cache_provider cache_disk_provider ={ &remove_entity, &store_headers, &store_body, &recall_headers, &recall_body, &create_entity, &open_entity, &remove_url,};static void disk_cache_register_hook(apr_pool_t *p){ /* cache initializer */ ap_register_provider(p, CACHE_PROVIDER_GROUP, "disk", "0", &cache_disk_provider);}module AP_MODULE_DECLARE_DATA disk_cache_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-directory config structure */ NULL, /* merge per-directory config structures */ create_config, /* create per-server config structure */ NULL, /* merge per-server config structures */ disk_cache_cmds, /* command apr_table_t */ disk_cache_register_hook /* register hooks */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -