?? htcookie.c
字號(hào):
/*** SIMPLE HTTP COOKIE FILTER HANDLER**** (c) COPYRIGHT MIT 1999.** Please first read the full copyright statement in the file COPYRIGH.** @(#) $Id: HTCookie.c,v 2.5 1999/07/31 01:30:16 raff Exp $**** Written based on Jim Raven's code sent to the <www-lib@w3.org> list**** History:** JR: Sent code to the list** HFN: Made a libwww module***//* Library include files */#include "wwwsys.h"#include "WWWUtil.h"#include "WWWCore.h"#include "WWWHTTP.h"#include "WWWMIME.h"#include "HTCookie.h" /* Implemented here *//* Interface to persistent cookie jar */PRIVATE HTCookieSetCallback * SetCookie = NULL;PRIVATE void * SetCookieContext = NULL;PRIVATE HTCookieFindCallback * FindCookie = NULL;PRIVATE void * FindCookieContext = NULL;/* Are cookies enabled */PRIVATE BOOL baking_cookies = NO;/* Our cookies */struct _HTCookie { char * name; char * value; char * domain; char * path; time_t expiration; BOOL secure;};/* Hold all cookies found for a single request */typedef struct _HTCookieHolder { HTRequest * request; HTList * cookies;} HTCookieHolder;/* List of current cookie holders */PRIVATE HTList * cookie_holder = NULL;/* What should we do with cookies? */PRIVATE HTCookieMode CookieMode = HT_COOKIE_PROMPT | HT_COOKIE_ACCEPT | HT_COOKIE_SEND;/* ------------------------------------------------------------------------- */PRIVATE HTCookie * HTCookie_new (void){ HTCookie * me = NULL; if ((me = (HTCookie *) HT_CALLOC(1, sizeof(HTCookie))) == NULL) HT_OUTOFMEM("HTCookie_new"); return me;} PRIVATE BOOL HTCookie_delete (HTCookie * me){ if (me) { HT_FREE(me->name); HT_FREE(me->value); HT_FREE(me->domain); HT_FREE(me->path); HT_FREE(me); return YES; } return NO;}PUBLIC BOOL HTCookie_setName (HTCookie * me, const char * name){ if (me && name) { me->name = StrAllocCopy(me->name, name); return YES; } return NO;}PUBLIC char * HTCookie_name (HTCookie * me){ return me ? me->name : NULL;}PUBLIC BOOL HTCookie_setValue (HTCookie * me, const char * value){ if (me && value) { me->value = StrAllocCopy(me->value, value); return YES; } return NO;}PUBLIC char * HTCookie_value (HTCookie * me){ return me ? me->value : NULL;}PUBLIC BOOL HTCookie_setDomain (HTCookie * me, const char * domain){ if (me && domain) { me->domain = StrAllocCopy(me->domain, domain); return YES; } return NO;}PUBLIC char * HTCookie_domain (HTCookie * me){ return me ? me->domain : NULL;}PUBLIC BOOL HTCookie_setPath (HTCookie * me, const char * path){ if (me && path) { me->path = StrAllocCopy(me->path, path); return YES; } return NO;}PUBLIC char * HTCookie_path (HTCookie * me){ return me ? me->path : NULL;}PUBLIC time_t HTCookie_setExpiration (HTCookie * me, time_t expiration){ if (me) { me->expiration = expiration; return YES; } return NO;}PUBLIC time_t HTCookie_expiration (HTCookie * me){ return me ? me->expiration : -1;}PUBLIC time_t HTCookie_setSecure (HTCookie * me, BOOL secure){ if (me) { me->secure = secure; return YES; } return NO;}PUBLIC BOOL HTCookie_isSecure (HTCookie * me){ return me ? me->secure : NO;}/* ------------------------------------------------------------------------- */PRIVATE BOOL HTCookieHolder_addCookie (HTRequest * request, HTCookie * cookie){ if (request && cookie) { HTList * cur = cookie_holder; HTCookieHolder * pres = NULL; /* Make sure that we have a cookie holder list */ if (!cookie_holder) cookie_holder = HTList_new(); /* See if we already have a cookie holder for this request */ while ((pres = (HTCookieHolder *) HTList_nextObject(cur))) { if (pres->request == request) break; } /* If found then use existing cookie holder, otherwise create new one */ if (!pres) { if ((pres = (HTCookieHolder *) HT_CALLOC(1, sizeof(HTCookieHolder))) == NULL) HT_OUTOFMEM("HTCookieHolder_newCookie"); pres->request = request; pres->cookies = HTList_new(); /* Add to cookie holder list */ HTList_addObject(cookie_holder, pres); } /* Now add the cookie */ HTList_addObject(pres->cookies, cookie); return YES; } return NO;}PRIVATE HTCookieHolder * HTCookieHolder_find (HTRequest * request){ if (request) { HTList * cur = cookie_holder; HTCookieHolder * pres = NULL; while ((pres = (HTCookieHolder *) HTList_nextObject(cur))) { if (pres->request == request) return pres; } } return NULL;}PRIVATE BOOL HTCookieHolder_delete (HTCookieHolder * me){ if (me) { if (me->cookies) { HTList * cookies = me->cookies; HTCookie * cookie; while ((cookie = (HTCookie *) HTList_nextObject(cookies))) HTCookie_delete(cookie); HTList_delete(me->cookies); } HTList_removeObject(cookie_holder, me); HT_FREE(me); return YES; } return NO;}PRIVATE BOOL HTCookieHolder_deleteAll (void){ if (cookie_holder) { HTList * cur = cookie_holder; HTCookieHolder * pres = NULL; while ((pres = (HTCookieHolder *) HTList_nextObject(cur))) { HTCookieHolder_delete(pres); } HTList_delete(cookie_holder); cookie_holder = NULL; return YES; } return NO;}/* ------------------------------------------------------------------------- *//*** MIME header parser for the Set-Cookie header field. We parse the cookies** and create HTCookie objects and store them in the cookie holder so that** the cookie after filter can deal with them accordingly.*/PRIVATE int HTCookie_parseSetCookie (HTRequest * request, HTResponse * response, char * token, char * value){ char * cookie_name = HTNextField(&value); char * cookie_value = HTNextField(&value); if (cookie_name && *cookie_name && cookie_value) { HTCookie * cookie = HTCookie_new(); char * param_pair; HTCookie_setName(cookie, cookie_name); HTCookie_setValue(cookie, cookie_value); /* Add the cookie to our holder */ HTCookieHolder_addCookie(request, cookie); /* Parse cookie parameters */ while ((param_pair = HTNextParam(&value))) { char * tok = HTNextField(¶m_pair); char * val = param_pair; if (tok) { if (!strcasecomp(tok, "expires") && val && *val) { HTTRACE(STREAM_TRACE, "Cookie...... Expires `%s\'\n" _ val); HTCookie_setExpiration(cookie, HTParseTime(val, NULL, YES)); } else if (!strcasecomp(tok, "domain") && val && *val) { HTTRACE(STREAM_TRACE, "Cookie...... Domain `%s\'\n" _ val); HTCookie_setDomain(cookie, val); } else if (!strcasecomp(tok, "path") && val && *val) { HTTRACE(STREAM_TRACE, "Cookie...... Path `%s\'\n" _ val); HTCookie_setPath(cookie, val); } else if (!strcasecomp(tok, "secure")) { HTTRACE(STREAM_TRACE, "Cookie...... Secure `%s\'\n" _ val); HTCookie_setSecure(cookie, YES); } else HTTRACE(STREAM_TRACE, "Cookie...... Unknown `%s\' with value `%s\'\n" _ tok _ val ? val : "<null>"); } } } return HT_OK;}/*** Check whether the application provides us with a cookie or more.*/PRIVATE int HTCookie_beforeFilter (HTRequest * request, void * param, int mode){ if ((CookieMode & HT_COOKIE_SEND) && FindCookie) { HTAssocList * cookies = (*FindCookie)(request, FindCookieContext); if (cookies) { HTChunk * cookie_header = HTChunk_new(64); HTAssocList * cur = cookies; HTAssoc * pres; BOOL first=YES; while ((pres = (HTAssoc *) HTAssocList_nextObject(cur))) { if (!first) HTChunk_putc(cookie_header, ';'); HTChunk_puts(cookie_header, HTAssoc_name(pres)); HTChunk_putc(cookie_header, '='); HTChunk_puts(cookie_header, HTAssoc_value(pres)); first = NO; } HTRequest_addExtraHeader(request, "Cookie", HTChunk_data(cookie_header)); HTChunk_delete(cookie_header); /* Also delete the association list */ HTAssocList_delete(cookies); } } return HT_OK;}/*** Check the response to see if we got a cookie or more.** If so then figure out what to do with it (prompt user, store, etc.)*/PRIVATE int HTCookie_afterFilter (HTRequest * request, HTResponse * response, void * param, int status){ if ((CookieMode & HT_COOKIE_ACCEPT) && SetCookie) { HTCookieHolder * holder = HTCookieHolder_find(request); if (holder) { HTList * cookies = holder->cookies; HTCookie * pres; while ((pres = (HTCookie *) HTAssocList_nextObject(cookies))) { /* Should we check to see if hosts match? */ if (CookieMode & (HT_COOKIE_SAME_HOST|HT_COOKIE_SAME_DOMAIN)) { char * cookie_host = HTCookie_domain(pres); if (cookie_host) { int res; char * addr = HTAnchor_address((HTAnchor *) HTRequest_anchor(request)); char * host = HTParse(addr, "", PARSE_HOST); if (CookieMode & HT_COOKIE_SAME_DOMAIN) res = tailcasecomp(cookie_host, host); else res = strcasecomp(cookie_host, host); if (res != 0) { HTTRACE(APP_TRACE, "Cookie...... Host `%s\' doesn't match what is sent in cookie `%s\'\n" _ host _ cookie_host); HT_FREE(addr); continue; } HT_FREE(addr); } } /* Should we prompt the user? */ if (CookieMode & HT_COOKIE_PROMPT) { HTAlertCallback * prompt = HTAlert_find(HT_A_CONFIRM); if (prompt) { if ((*prompt)(request, HT_A_CONFIRM, HT_MSG_ACCEPT_COOKIE, NULL, NULL, NULL) != YES) continue; } else continue; } /* Call the application with our new cookie */ (*SetCookie)(request, pres, SetCookieContext); } /* Delete cookie holder */ HTCookieHolder_delete(holder); } } return HT_OK;}/* ------------------------------------------------------------------------- *//*** Start and stop the cookie engine*/PUBLIC BOOL HTCookie_init (void){ if (!baking_cookies) { /* Register the SetCookie header parser */ HTHeader_addParser("Set-Cookie", NO, HTCookie_parseSetCookie); /* Register the cookie before and after filters */ HTNet_addBefore(HTCookie_beforeFilter, "http://*", NULL, HT_FILTER_MIDDLE); HTNet_addAfter(HTCookie_afterFilter, "http://*", NULL, HT_ALL, HT_FILTER_MIDDLE); baking_cookies = YES; return YES; } return NO;}PUBLIC BOOL HTCookie_terminate (void){ /* Unregister Set-Cookie header parser */ HTHeader_deleteParser("Set-Cookie"); /* Unregister the cookie before and after filters */ HTNet_deleteBefore(HTCookie_beforeFilter); HTNet_deleteAfter(HTCookie_afterFilter); /* Delete all pending cookies */ HTCookieHolder_deleteAll(); baking_cookies = NO; return YES;}PUBLIC BOOL HTCookie_setCookieMode (HTCookieMode mode){ CookieMode = mode; return YES;}PUBLIC HTCookieMode HTCookie_cookieMode (void){ return CookieMode;}/*** Callbacks can be used by the application to set and retrieve cookies** from a persistent cookie jar as libwww doesn't provide a persistent** storage for this kind of thing and they probably should be secured** anyway.*/PUBLIC BOOL HTCookie_setCallbacks (HTCookieSetCallback * setCookie, void * setCookieContext, HTCookieFindCallback * findCookie, void * findCookieContext){ if (setCookie && findCookie) { HTTRACE(APP_TRACE, "Cookie...... Registering cookie callbacks\n"); SetCookie = setCookie; SetCookieContext = setCookieContext; FindCookie = findCookie; FindCookieContext = findCookieContext; return YES; } return NO;}PUBLIC BOOL HTCookie_deleteCallbacks (void){ HTTRACE(APP_TRACE, "Cookie...... Unregistering cookie callbacks\n"); SetCookie = NULL; SetCookieContext = NULL; FindCookie = NULL; FindCookieContext = NULL; return YES;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -