⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htcache.c

📁 Open VXI. This is a open source.
💻 C
📖 第 1 页 / 共 5 页
字号:
		HTChunk_clear(me->buffer);		continue;	    }	} else if (*b == CR) {	    me->EOLstate = EOL_FCR;	} else if (*b == LF) {	    me->EOLstate = EOL_FLF;			       /* Line found */	} else	    HTChunk_putc(me->buffer, *b);	l--; b++;    }    return HT_OK;}PRIVATE int HTCacheIndex_put_character (HTStream * me, char c){    return HTCacheIndex_put_block(me, &c, 1);}PRIVATE int HTCacheIndex_put_string (HTStream * me, const char * s){    return HTCacheIndex_put_block(me, s, (int) strlen(s));}PRIVATE int HTCacheIndex_flush (HTStream * me){    if (me) {	char * flush = HTChunk_data(me->buffer);	if (flush) HTCacheIndex_parseLine(flush);	HTChunk_clear(me->buffer);    }    return HT_OK;}PRIVATE int HTCacheIndex_free (HTStream * me){    if (me) {	int status = HTCacheIndex_flush(me);	HTTRACE(APP_TRACE, "Cache Index. FREEING....\n");	HTChunk_delete(me->buffer);	HT_FREE(me);	return status;    }    return HT_ERROR;}PRIVATE int HTCacheIndex_abort (HTStream * me, HTList * e){    if (me) {	int status = HT_ERROR;	HTTRACE(APP_TRACE, "Cache Index. ABORTING...\n");	HTChunk_delete(me->buffer);	HT_FREE(me);	return status;    }    return HT_ERROR;}/*	Structured Object Class**	-----------------------*/PRIVATE const HTStreamClass HTCacheIndexClass ={		    "CacheIndexParser",    HTCacheIndex_flush,    HTCacheIndex_free,    HTCacheIndex_abort,    HTCacheIndex_put_character,    HTCacheIndex_put_string,    HTCacheIndex_put_block};PRIVATE HTStream * HTCacheIndexReader (HTRequest *	request){    HTStream * me;    if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)	HT_OUTOFMEM("HTCacheIndexs");    me->isa = &HTCacheIndexClass;    me->request = request;    me->buffer = HTChunk_new(512);    me->EOLstate = EOL_BEGIN;    return me;}/***	Read the saved set of cached entries from disk. we only allow the index**	ro be read when there is no entries in memory. That way we can ensure**	consistancy.*/PUBLIC BOOL HTCacheIndex_read (const char * cache_root){    BOOL status = NO;    if (cache_root && CacheTable == NULL) {	BOOL wasInteractive;	char * file = cache_index_name(cache_root);	char * index = HTLocalToWWW(file, "cache:");	HTAnchor * anchor = HTAnchor_findAddress(index);		HTRequest * request = HTRequest_new();	HTRequest_setPreemptive(request, YES);	HTRequest_setOutputFormat(request, WWW_SOURCE);	/* Make sure we don't use any filters */	HTRequest_addBefore(request, NULL, NULL, NULL, 0, YES);	HTRequest_addAfter(request, NULL, NULL, NULL, HT_ALL, 0, YES);	/* Set the output */    	HTRequest_setOutputStream(request, HTCacheIndexReader(request));	HTRequest_setAnchor(request, anchor);	HTAnchor_setFormat((HTParentAnchor *) anchor, HTAtom_for("www/cache-index"));	wasInteractive = HTAlert_interactive();	HTAlert_setInteractive(NO);	status = HTLoad(request, NO);	HTAlert_setInteractive(wasInteractive);	HTRequest_delete(request);	HT_FREE(file);	HT_FREE(index);    }    return status;}/* ------------------------------------------------------------------------- *//*  			      CACHE PARAMETERS				     *//* ------------------------------------------------------------------------- */PRIVATE BOOL create_cache_root (const char * cache_root){    struct stat stat_info;    char * loc = NULL;    char * cur = NULL;    BOOL create = NO;    if (!cache_root) return NO;    StrAllocCopy(loc, cache_root);			 /* Get our own copy */#ifdef WWW_MSWINDOWS    cur = *(loc+1) == ':' ? loc+3 : loc+1;#else    cur = loc+1;#endif    while ((cur = strchr(cur, DIR_SEPARATOR_CHAR))) {	*cur = '\0';	if (create || HT_STAT(loc, &stat_info) == -1) {	    create = YES;		   /* To avoid doing stat()s in vain */	    HTTRACE(CACHE_TRACE, "Cache....... Creating dir `%s\'\n" _ loc);	    if (MKDIR(loc, 0777) < 0) {		HTTRACE(CACHE_TRACE, "Cache....... can't create\n");		HT_FREE(loc);		return NO;	    }	} else {	    HTTRACE(CACHE_TRACE, "Cache....... dir `%s\' already exists\n" _ loc);	}	*cur++ = DIR_SEPARATOR_CHAR;    }    HT_FREE(loc);    return YES;}/***	If `cache_root' is NULL then the current value (might be a define)**	Should we check if the cache_root is actually OK? I think not!*/PRIVATE BOOL HTCacheMode_setRoot (const char * cache_root){    if (cache_root) {        if ((HTCacheRoot = HTWWWToLocal(cache_root, "file:", NULL)) == NULL)            return NO;        if (*(HTCacheRoot+strlen(HTCacheRoot)-1) != DIR_SEPARATOR_CHAR)	    StrAllocCat(HTCacheRoot, DIR_SEPARATOR_STR);    } else {	/*	**  If no cache root has been indicated then look for a suitable	**  location.	*/	char * addr = NULL;	char * cr = (char *) getenv("WWW_CACHE");	if (!cr) cr = (char *) getenv("TMP");	if (!cr) cr = (char *) getenv("TEMP");	if (!cr) cr = HT_CACHE_LOC;	addr = HTLocalToWWW(cr, NULL);	if (*(addr+strlen(addr)-1) != DIR_SEPARATOR_CHAR)	    StrAllocCat(addr, DIR_SEPARATOR_STR);	StrAllocCat(addr, HT_CACHE_ROOT);	if (*(addr+strlen(addr)-1) != DIR_SEPARATOR_CHAR)	    StrAllocCat(addr, DIR_SEPARATOR_STR);        if ((HTCacheRoot = HTWWWToLocal(addr, "file:", NULL)) == NULL) {            HT_FREE(addr);            return NO;        }        HT_FREE(addr);    }    if (create_cache_root(HTCacheRoot) == NO) return NO;    HTTRACE(CACHE_TRACE, "Cache Root.. Local root set to `%s\'\n" _ HTCacheRoot);    return YES;}/***	Return the value of the cache root. The cache root can only be**	set through the HTCacheInit() function*/PUBLIC char * HTCacheMode_getRoot (void){    return HTLocalToWWW(HTCacheRoot, NULL);}/***	As this is a single user cache, we have to lock it when in use.*/PRIVATE FILE *locked_open_file = {NULL};PRIVATE BOOL HTCache_getSingleUserLock (const char * root){    if (root && !locked_open_file) {	FILE * fp;	char * location = NULL;	if ((location = (char *)	     HT_MALLOC(strlen(root) + strlen(HT_CACHE_LOCK) + 1)) == NULL)	    HT_OUTOFMEM("HTCache_getLock");	strcpy(location, root);	strcat(location, HT_CACHE_LOCK);	if ((fp = fopen(location, "r")) != NULL) {	    HTAlertCallback *cbf = HTAlert_find(HT_A_CONFIRM);	    HTTRACE(CACHE_TRACE, "Cache....... In `%s\' is already in use\n" _ root);	    fclose(fp);            if (cbf) {                BOOL result = (*cbf)(NULL, HT_A_CONFIRM,                                     HT_MSG_CACHE_LOCK,NULL,location,NULL);                if (result == YES) {                    REMOVE(location);                } else {                    HT_FREE(location);                    return NO;                }            } else {                HT_FREE(location);                return NO;                }	}	if ((fp = fopen(location, "w")) == NULL) {	    HTTRACE(CACHE_TRACE, "Cache....... Can't open `%s\' for writing\n" _ location);	    HT_FREE(location);	    return NO;	}	locked_open_file = fp;	HT_FREE(location);	return YES;    }    return NO;}/***	Release the single user lock*/PRIVATE BOOL HTCache_deleteSingleUserLock (const char * root){    if (root) {	char * location = NULL;	if ((location = (char *)	     HT_MALLOC(strlen(root) + strlen(HT_CACHE_LOCK) + 1)) == NULL)	    HT_OUTOFMEM("HTCache_deleteLock");	strcpy(location, root);	strcat(location, HT_CACHE_LOCK);	/* under UNIX you can remove an open file, not so under NT */	if (locked_open_file) {		fclose(locked_open_file);	    locked_open_file = NULL;	}	REMOVE(location);	HT_FREE(location);	return YES;    }    return NO;}/***	If `cache_root' is NULL then reuse old value or use HT_CACHE_ROOT.**	An empty string will make '/' as cache root**	We can only enable the cache if the HTSecure flag is not set. This**	is for example the case if using an application as a telnet shell.*/PUBLIC BOOL HTCacheInit (const char * cache_root, int size){    if (!HTLib_secure() && !HTCacheRoot) {	/*	**  Find an appropriate root for the cache	*/	if (HTCacheMode_setRoot(cache_root) != YES) return NO;	/*	**  Set the max size of the cache 	*/	HTCacheMode_setMaxSize(size);	/*	**  Set a lock on the cache so that multiple users	**  don't step on each other.	*/	if (HTCache_getSingleUserLock(HTCacheRoot) == NO)	    return NO;	/*	**  Look for the cache index and read the contents	*/	HTCacheIndex_read(HTCacheRoot);	/*	**  Register the cache before and after filters	*/	HTNet_addBefore(HTCacheFilter, "http://*", NULL, HT_FILTER_MIDDLE);	HTNet_addAfter(HTCacheUpdateFilter, "http://*", NULL,		       HT_NOT_MODIFIED, HT_FILTER_MIDDLE);		/*	**  Register the cache AFTER filter for checking whether        **  we should invalidate the cached entry	*/	HTNet_addAfter(HTCacheCheckFilter, "http://*",	NULL, HT_ALL,		       HT_FILTER_MIDDLE);	/*	**  Do caching from now on	*/	HTCacheEnable = YES;	HTCacheInitialized = YES;	return YES;    }    return NO;}/***	Turns off the cache and updates entries on disk.*/PUBLIC BOOL HTCacheTerminate (void){    if (HTCacheInitialized) {	/*	**  Write the index to file	*/	HTCacheIndex_write(HTCacheRoot);	/*	**  Unregister the cache before and after filters	*/	HTNet_deleteBefore(HTCacheFilter);	HTNet_deleteAfter(HTCacheUpdateFilter);	HTNet_deleteAfter(HTCacheCheckFilter);	/*	**  Remove the global cache lock.	*/	HTCache_deleteSingleUserLock(HTCacheRoot);	/*	**  Cleanup memory by deleting all HTCache objects	*/	HTCache_deleteAll();	/*	**  Don't do anymore caching from now on	*/	HT_FREE(HTCacheRoot);	HTCacheEnable = NO;	return YES;    }    return NO;}/***	The cache can be temporarily suspended by using the enable/disable**	flag. This does not prevent the cache from being enabled/disable at**	a later point in time.*/PUBLIC void HTCacheMode_setEnabled (BOOL mode){    HTCacheEnable = mode;}PUBLIC BOOL HTCacheMode_enabled (void){    return HTCacheEnable;}PUBLIC void HTCacheMode_setProtected (BOOL mode){    HTCacheProtected = mode;}PUBLIC BOOL HTCacheMode_protected (void){    return HTCacheProtected;}/***  We can set the cache to operate in disconnected mode in which we only**  return (valid) responses from the cache. Disconnected mode does not**  automatically deliver stale documents as this must be declared **  explicitly. */PUBLIC void HTCacheMode_setDisconnected (HTDisconnectedMode mode){    DisconnectedMode = mode;}PUBLIC HTDisconnectedMode HTCacheMode_disconnected (void){    return DisconnectedMode;}PUBLIC BOOL HTCacheMode_isDisconnected (HTReload mode){    return (DisconnectedMode != HT_DISCONNECT_NONE);}/***  Set the mode for how we handle Expires header from the local history**  list. The following modes are available:****	HT_EXPIRES_IGNORE : No update in the history list**	HT_EXPIRES_NOTIFY : The user is notified but no reload**	HT_EXPIRES_AUTO   : Automatic reload*/PUBLIC void HTCacheMode_setExpires (HTExpiresMode mode){    HTExpMode = mode;}PUBLIC HTExpiresMode HTCacheMode_expires (void){    return HTExpMode;}/***  Cache size management. We set the default cache size to 20M.**  We set the minimum size to 5M in order not to get into weird**  problems while writing the cache. The size is indicated in Mega**  bytes*/PUBLIC BOOL HTCacheMode_setMaxSize (int size){    long new_size = size < HT_MIN_CACHE_TOTAL_SIZE ?	HT_MIN_CACHE_TOTAL_SIZE*MEGA : size*MEGA;    long old_size = HTCacheTotalSize;    HTCacheTotalSize = new_size;    HTCacheFolderSize = HTCacheTotalSize/HT_CACHE_FOLDER_PCT;    HTCacheGCBuffer = HTCacheTotalSize/HT_CACHE_GC_PCT;    if (new_size < old_size) HTCacheGarbage();    HTTRACE(CACHE_TRACE, "Cache....... Total cache size: %ld with %ld bytes for metainformation and folders and at least %ld bytes free after every gc\n" _ 		HTCacheTotalSize _ HTCacheFolderSize _ HTCacheGCBuffer);    return YES;}PUBLIC int HTCacheMode_maxSize (void){    return HTCacheTotalSize / MEGA;}/***  How big can a single cached entry be in Mbytes. The default is 3M**  */PUBLIC BOOL HTCacheMode_setMaxCacheEntrySize (int size){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -