Annotation of libwww/Library/src/HTMIMPrs.c, revision 2.4

2.1       eric        1: /*                                                                    HTAtom.c
                      2: **     HTHashList: hash indexed array of MIME header parsers
                      3: **
                      4: **     (c) COPYRIGHT MIT 1996.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.4     ! frystyk     6: **     @(#) $Id: HTMIMPrs.c,v 2.3 1996/06/07 04:40:03 eric Exp $
2.1       eric        7: **
                      8: **      See HTHshLst.html for a description of HashLists.
                      9: **
                     10: ** Authors:
                     11: **     EGP     Eric Prud'hommeaux w3
                     12: **
                     13: */
                     14: 
                     15: /* Library include files */
                     16: #include "sysdep.h"
                     17: #include "HTUtils.h"
                     18: #include "HTString.h"
                     19: #include "HTMIMPrs.h"
                     20: 
2.4     ! frystyk    21: #define HT_MAX_NO_CACHE                6
        !            22: #define DEFAULT_HASH_SIZE      11
        !            23: 
2.1       eric       24: struct _HTMIMEParseEl{
2.4     ! frystyk    25:     HTMIMEParseEl *    next;
        !            26:     const char *       token;
        !            27:     BOOL               caseSensitive;
        !            28:     HTParserCallback *         pFunk;
2.1       eric       29: };
                     30: 
2.4     ! frystyk    31: PRIVATE char * no_cache_headers[HT_MAX_NO_CACHE] =
        !            32: {
        !            33:     "connection",
        !            34:     "keep-alive",
        !            35:     "public",
        !            36:     "proxy-authenticate",
        !            37:     "transfer-encoding",
        !            38:     "upgrade"
        !            39: };
2.1       eric       40: 
                     41: PRIVATE HTMIMEParseEl * HTMIMEParseEl_new(HTMIMEParseEl ** pBefore, 
                     42:                                          const char * token, 
                     43:                                          BOOL caseSensitive, 
                     44:                                          HTParserCallback * callback)
                     45: {
                     46:     HTMIMEParseEl * ret;
                     47:     if ((ret = (HTMIMEParseEl *) HT_MALLOC(sizeof(HTMIMEParseEl))) == NULL)
                     48:         HT_OUTOFMEM("HTMIMEParseEl");
                     49:     ret->next = *pBefore;
                     50:     *pBefore = ret;
                     51:     if ((ret->token = (char *) HT_MALLOC(strlen(token)+1)) == NULL)
                     52:         HT_OUTOFMEM("token");
2.2       eric       53:     strcpy((char *)ret->token, token);
2.1       eric       54:     ret->caseSensitive = caseSensitive;
                     55:     ret->pFunk = callback;
                     56:     
                     57:     return ret;
                     58: }
                     59: 
                     60: PRIVATE int HTMIMEParseEl_delete(HTMIMEParseEl * me, HTMIMEParseEl ** pBefore)
                     61: {
                     62:     *pBefore = me->next;
                     63:     HT_FREE(me);
                     64:     return HT_OK;
                     65: }
                     66: 
                     67: PRIVATE int HTMIMEParseSet_hash(HTMIMEParseSet * me, const char * token)
                     68: {
                     69:     int ret;
                     70:     const char * p;
                     71: 
                     72:     for (p=token, ret=0; *p; p++) {
                     73:         char ch;
                     74:         ch = *(unsigned char *) p;
                     75:        ch = tolower(ch);
                     76:         ret = (ret * 3 +(ch)) % me->size;
                     77:     }
                     78:     return ret;
                     79: }
                     80: 
                     81: PUBLIC HTMIMEParseSet * HTMIMEParseSet_new(int hashSize)
                     82: {
                     83:     HTMIMEParseSet * me;
                     84: 
                     85:     if ((me = (HTMIMEParseSet *) HT_CALLOC(1, sizeof(HTMIMEParseSet))) == NULL)
                     86:         HT_OUTOFMEM("HTMIMEParseSet");
                     87:     me->size = hashSize;
2.4     ! frystyk    88: 
        !            89:     /*
        !            90:     **  Using the hash size we have, calculate the constant set of headers that a cache
        !            91:     **  should never cache
        !            92:     */
        !            93:     {
        !            94:        int cnt = 0;
        !            95:        for (; cnt < HT_MAX_NO_CACHE; cnt++)
        !            96:            *(me->no_cache+cnt) = HTMIMEParseSet_hash(me, *(no_cache_headers+cnt));
        !            97:     }
2.1       eric       98:     return me;
                     99: }
                    100: 
2.2       eric      101: PUBLIC int HTMIMEParseSet_deleteAll (HTMIMEParseSet * me)
2.1       eric      102: {
2.2       eric      103:     int i;
                    104:     HTMIMEParseEl * pEl, * next;
                    105:     
                    106:     for (i=0; i<me->size; i++)
                    107:        for (pEl = me->parsers[i]; pEl; pEl = next) {
                    108:            next = pEl->next;
                    109:            HT_FREE(pEl);
                    110:        }
                    111: 
                    112:     for (pEl = me->parsers[i]; pEl; pEl = next) {
                    113:         next = pEl->next;
                    114:        HT_FREE(pEl);
                    115:     }
2.1       eric      116:     HT_FREE(me);
                    117:     return HT_OK;
                    118: }
                    119: 
                    120: PUBLIC HTMIMEParseEl * HTMIMEParseSet_add (HTMIMEParseSet * me, 
                    121:                                           const char * token, 
                    122:                                           BOOL caseSensitive, 
                    123:                                           HTParserCallback * callback)
                    124: {
                    125:     int hash;
                    126: 
                    127:     /*         Insure hash list
                    128:     */
                    129:     if (!me->parsers) {
                    130:         if (!me->size)
                    131:            me->size = DEFAULT_HASH_SIZE;
                    132:        if ((me->parsers = (HTMIMEParseEl **) HT_CALLOC(me->size, sizeof(HTMIMEParseEl *))) == NULL)
                    133:            HT_OUTOFMEM("HTMIME parsers");
                    134:     }
                    135:     hash = HTMIMEParseSet_hash(me, token);
                    136: 
                    137:     /*         Add a new entry
                    138:     */
                    139:     return HTMIMEParseEl_new(&me->parsers[hash], token, 
                    140:                             caseSensitive, callback);
                    141: }
                    142: 
                    143: 
                    144: PUBLIC HTMIMEParseEl * HTMIMEParseSet_addRegex (HTMIMEParseSet * me, 
                    145:                                                const char * token, 
                    146:                                                BOOL caseSensitive, 
                    147:                                                HTParserCallback * callback)
                    148: {
                    149:     return HTMIMEParseEl_new(&me->regexParsers, token, 
                    150:                             caseSensitive, callback);
                    151: }
                    152: 
2.2       eric      153: PUBLIC int HTMIMEParseSet_delete (HTMIMEParseSet * me, const char * token)
2.1       eric      154: {
                    155:     int hash, i;
                    156:     HTMIMEParseEl * pEl, ** last;
                    157:     
                    158:     hash = HTMIMEParseSet_hash(me, token);
                    159: 
                    160:     pEl = me->parsers[hash];
                    161:     last = &me->parsers[hash];
                    162:     for (i = 0; i < 2; i++) { /* do both  */
                    163:         for (; pEl; last = &pEl->next, pEl = pEl->next) {
                    164:            if ((pEl->caseSensitive && !strcmp(pEl->token, token)) || 
                    165:                (!pEl->caseSensitive && !strcasecomp(pEl->token, token))) {
                    166:                return HTMIMEParseEl_delete(pEl, last);
                    167:            }
                    168:        }
                    169:        pEl = me->regexParsers;
                    170:        last = &me->regexParsers;
                    171:     }
                    172:     return HT_ERROR;
                    173: }
                    174: 
                    175: /*
                    176: **     Search registered parsers to find suitable one for this token
                    177: **     If a parser isn't found, the function returns HT_OK
                    178: */
                    179: PUBLIC int HTMIMEParseSet_dispatch (HTMIMEParseSet * me, HTRequest * request, 
2.4     ! frystyk   180:                                    char * token, char * value, BOOL * pFound,
        !           181:                                    BOOL CacheFilter)
2.1       eric      182: {
2.2       eric      183:     int hash;
2.1       eric      184:     HTMIMEParseEl * pEl;
                    185:     
                    186:     if (pFound) *pFound = NO;
2.2       eric      187: 
2.4     ! frystyk   188:     /*
        !           189:     **
        !           190:     */
2.1       eric      191:     hash = HTMIMEParseSet_hash(me, token);
2.4     ! frystyk   192: 
        !           193:     /*
        !           194:     **  Add the name-value pair to the list of headers that we want to cache.
        !           195:     **  We do not at this point in time look into whether there are cache
        !           196:     **  directives preventing us from caching the headers. This is done at
        !           197:     **  write time.
        !           198:     */
        !           199:     if (CacheFilter) {
        !           200:        int cnt = 0;
        !           201:        for (; cnt < HT_MAX_NO_CACHE; cnt++)
        !           202:            if (hash == *(me->no_cache+cnt)) break;
        !           203:        if (cnt == HT_MAX_NO_CACHE) HTRequest_addHeaders(request, token, value);
        !           204:     }
        !           205: 
2.2       eric      206:     for (pEl = me->parsers[hash]; pEl; pEl = pEl->next) {
                    207:         if ((pEl->caseSensitive && !strcmp(pEl->token, token)) || 
                    208:            (!pEl->caseSensitive && !strcasecomp(pEl->token, token))) {
                    209:            if (pFound) *pFound = YES;
                    210:            if (!pEl->pFunk) return HT_OK; /* registered with no callback*/
                    211:            return (*pEl->pFunk)(request, token, value);
                    212:        }
                    213:     }
2.1       eric      214: 
2.2       eric      215:     for (pEl = me->regexParsers; pEl; pEl = pEl->next) {
2.3       eric      216:         if ((pEl->caseSensitive && HTStrMatch(pEl->token, token)) || 
                    217:            (!pEl->caseSensitive && HTStrCaseMatch(pEl->token, token))) {
2.2       eric      218:            if (pFound) *pFound = YES;
                    219:            if (!pEl->pFunk) return HT_OK; /* registered with no callback*/
                    220:            return (*pEl->pFunk)(request, token, value);
2.1       eric      221:        }
                    222:     }
2.2       eric      223: 
2.1       eric      224:     return HT_OK;
                    225: }
                    226: 

Webmaster