Annotation of libwww/Library/src/HTPEP.c, revision 2.3

2.1       frystyk     1: /*
                      2: **     PEP ENGINE
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.3     ! frystyk     6: **     @(#) $Id: HTPEP.c,v 2.2 1996/08/19 18:30:55 frystyk Exp $
2.1       frystyk     7: **
                      8: **
                      9: ** AUTHORS:
                     10: **     HFN     Henrik Frystyk
                     11: **
                     12: ** HISTORY:
                     13: **     July 96 HFN     Written first version
                     14: */
                     15: 
                     16: /* Library include files */
                     17: #include "sysdep.h"
                     18: #include "WWWUtil.h"
                     19: #include "WWWCore.h"
                     20: #include "HTPEP.h"                                      /* Implemented here */
                     21: 
                     22: #define HASH_SIZE              67                        /* Arbitrary prime */
                     23: #define PEP_NAME               "w3c-pep"            /* Name of the PEP tree */
                     24: #define DEFAULT_PORT           80                    /* Concentrate on HTTP */
                     25: 
                     26: struct _HTPEPModule {
                     27:     char *             name;
                     28:     HTNetCallback *    before;
                     29:     HTNetCallback *    after;
                     30:     HTUTree_gc *       gc;
                     31: };
                     32: 
                     33: typedef struct _HTPEPElement {
                     34:     char *             name;
                     35:     void *             context;
                     36: } HTPEPElement;
                     37: 
                     38: PRIVATE HTList ** HTModules;              /* List of registered PEP modules */
                     39: 
                     40: /* ------------------------------------------------------------------------- */
                     41: /*                             PEP MODULE MANAGEMENT                        */
                     42: /* ------------------------------------------------------------------------- */
                     43: 
                     44: PRIVATE BOOL delete_module (HTPEPModule * module)
                     45: {
                     46:     if (module) {
                     47:        HT_FREE(module->name);
                     48:        HT_FREE(module);
                     49:        return YES;
                     50:     }
                     51:     return NO;
                     52: }
                     53: 
                     54: /*
                     55: **     Case sensitive search for module
                     56: */
                     57: PRIVATE HTPEPModule * find_module (const char * name, HTList ** hashlist)
                     58: {
                     59:     HTPEPModule * pres = NULL;
                     60:     *hashlist = NULL;
                     61:     if (!name) {
                     62:        if (APP_TRACE) HTTrace("PEP Engine.. Bad argument\n");
                     63:        return NULL;
                     64:     }
                     65: 
                     66:     /* Find a hash for this PEP module */
                     67:     {
                     68:        int hash = 0;
                     69:        const char * ptr;
                     70:        for (ptr=name; *ptr; ptr++)
                     71:            hash = (int) ((hash * 3 + (*(unsigned char *) ptr)) % HASH_SIZE);
                     72:        if (!HTModules) {
                     73:            if ((HTModules = (HTList **) HT_CALLOC(HASH_SIZE,
                     74:                                                   sizeof(HTList *))) == NULL)
                     75:                HT_OUTOFMEM("find_module");
                     76:        }
                     77:        if (!HTModules[hash])
                     78:            HTModules[hash] = *hashlist = HTList_new();
                     79:        else
                     80:            *hashlist = HTModules[hash];
                     81:     }
                     82: 
                     83:     /* Search the existing list to see if we already have this entry */
                     84:     {
                     85:        HTList * cur = *hashlist;
                     86:        while ((pres = (HTPEPModule *) HTList_nextObject(cur))) {
                     87:            if (!strcmp(pres->name, name)) return pres;
                     88:        }
                     89:     }
                     90:     return NULL;
                     91: }
                     92: 
                     93: PUBLIC HTPEPModule * HTPEP_newModule (const char *     name,
                     94:                                      HTNetCallback *   before,
                     95:                                      HTNetCallback *   after,
                     96:                                      HTUTree_gc *      gc)
                     97: {
                     98:     if (name) {
                     99:        HTList * hashlist = NULL;
                    100:        HTPEPModule * pres = find_module(name, &hashlist);
                    101: 
                    102:        /* If found then update entry - else create a new one */
                    103:        if (!pres) {
                    104:            if (!(pres = (HTPEPModule *) HT_CALLOC(1, sizeof(HTPEPModule))))
                    105:                HT_OUTOFMEM("HTPEP_newModule");
                    106:            StrAllocCopy(pres->name, name);
                    107:            pres->before = before;
                    108:            pres->after = after;
                    109:            pres->gc = gc;
                    110: 
                    111:            /* Add the new PEP Module to the hash table */
                    112:            HTList_addObject(hashlist, (void *) pres);
                    113:            if (APP_TRACE) HTTrace("PEP Engine.. Created module %p\n", pres);
                    114:        } else {
                    115:            if (APP_TRACE) HTTrace("PEP Engine.. Found module %p\n", pres);
                    116:        }
                    117:        return pres;
                    118:     } else {
                    119:        if (APP_TRACE) HTTrace("PEP Engine.. Bad argument\n");
                    120:        return NULL;
                    121:     }
                    122: }
                    123: 
                    124: PUBLIC HTPEPModule * HTPEP_findModule (const char * name)
                    125: {
                    126:     if (name) {
                    127:        HTList * hashlist = NULL;
                    128:        HTPEPModule * pres = find_module(name, &hashlist);
                    129:        if (APP_TRACE)
                    130:            HTTrace("PEP Engine.. did %sfind %s\n", pres ? "" : "NOT ", name);
                    131:        return pres;
                    132:     } else {
                    133:        if (APP_TRACE) HTTrace("PEP Engine.. Bad augument\n");
                    134:     }
                    135:     return NULL;
                    136: }
                    137: 
                    138: PUBLIC BOOL HTPEP_deleteModule (const char * name)
                    139: {
                    140:     if (name) {
                    141:        HTList * hashlist = NULL;
                    142:        HTPEPModule * pres = find_module(name, &hashlist);
                    143:        if (pres) {
                    144:            HTList_removeObject(hashlist, pres);
                    145:            if (APP_TRACE) HTTrace("PEP Engine.. deleted %p\n", pres);
                    146:            delete_module(pres);
                    147:            return YES;
                    148:        }
                    149:     }
                    150:     return NO;
                    151: }
                    152: 
                    153: PUBLIC BOOL HTPEP_deleteAllModules (void)
                    154: {
                    155:     if (HTModules) {
                    156:        int cnt;
                    157:        HTList * cur;
                    158:        for (cnt=0; cnt<HASH_SIZE; cnt++) {
                    159:            if ((cur = HTModules[cnt])) { 
                    160:                HTPEPModule * pres;
                    161:                while ((pres = (HTPEPModule *) HTList_nextObject(cur)))
                    162:                    delete_module(pres);
                    163:            }
                    164:            HTList_delete(HTModules[cnt]);
                    165:        }
                    166:        HT_FREE(HTModules);
                    167:        return YES;
                    168:     }
                    169:     return NO;
                    170: }
                    171: 
                    172: /* ------------------------------------------------------------------------- */
                    173: /*                         HANDLE THE PEP URL TREE                          */
                    174: /* ------------------------------------------------------------------------- */
                    175: 
                    176: /*
                    177: **     A PEP element is a particular PEP procotol associated with a
                    178: **     particular point in the URL tree. The name is the name of the
                    179: **     protocol known to be able to handle this context. This protocol
                    180: **     must have been registered as a PEP module.
                    181: */
                    182: PRIVATE HTPEPElement * HTPEP_newElement (const char * name, void * context)
                    183: {
                    184:     if (name) {
                    185:        HTPEPElement * me;
                    186:        if ((me = (HTPEPElement *) HT_CALLOC(1, sizeof(HTPEPElement))) == NULL)
                    187:            HT_OUTOFMEM("HTPEPElement_new");
                    188:        StrAllocCopy(me->name, name);
                    189:        me->context = context;
                    190:        if (APP_TRACE) HTTrace("PEP Engine.. Created element %p\n", me);
                    191:        return me;
                    192:     }
                    193:     return NULL;
                    194: }
                    195: 
                    196: PRIVATE BOOL HTPEP_deleteElement (HTPEPElement * me)
                    197: {
                    198:     if (me) {
                    199:        if (APP_TRACE) HTTrace("PEP Engine.. Deleted element %p\n", me);
                    200:        HT_FREE(me->name);
                    201:        HT_FREE(me);
                    202:        return YES;
                    203:     }
                    204:     return NO;
                    205: }
                    206: 
                    207: /*
                    208: **     A PEP list is a list of PEP elements and the "thing" we store in the
                    209: **     PEP URL Tree
                    210: */
                    211: PRIVATE HTList * HTPEP_newList (void)
                    212: {
                    213:     HTList * me = HTList_new();
                    214:     if (APP_TRACE) HTTrace("PEP Engine.. Created list %p\n", me);
                    215:     return me;
                    216: }
                    217: 
                    218: PRIVATE int HTPEP_deleteList (void * context)
                    219: {
                    220:     HTList * list = (HTList *) context;
                    221:     if (list) {
                    222:        HTPEPElement * pres;
                    223:        while ((pres = (HTPEPElement *) HTList_nextObject(list)))
                    224:            HTPEP_deleteElement(pres);
                    225:        if (APP_TRACE) HTTrace("PEP Engine.. Deleted list %p\n", list);
                    226:        HTList_delete(list);
                    227:        return YES;
                    228:     }
                    229:     return NO;
                    230: }
                    231: 
                    232: /*
                    233: **     Find a PEP List
                    234: **     ---------------
                    235: **     Seaches the set PEP tree for a match. We do the following:
                    236: **
                    237: **             1) Find the PEP tree for this host
                    238: **             2) See if there is a realm match
                    239: **             3) See if there is a template match for URL
                    240: **
                    241: **     Return the node found else NULL which means that we don't have any
                    242: **     authentication information to hook on to this request or response
                    243: */
                    244: PRIVATE HTList * HTPEP_findList (const char * realm, const char * url)
                    245: {
                    246:     HTUTree * tree;
                    247:     if (!url) {
                    248:        if (APP_TRACE) HTTrace("PEP Engine.. Bad argument\n");
                    249:        return NULL;
                    250:     }
                    251:     if (APP_TRACE) HTTrace("PEP Engine.. Looking for info on `%s'\n", url);
                    252: 
                    253:     /* Find a URLTree for this URL (if any) */
                    254:     {
                    255:        char * host = HTParse(url, "", PARSE_HOST);
                    256:        char * colon = strchr(host, ':');
                    257:        int port = DEFAULT_PORT;
                    258:        if (colon ) {
                    259:            *(colon++) = '\0';                       /* Chop off port number */
                    260:            port = atoi(colon);
                    261:        }       
                    262:        tree = HTUTree_find(PEP_NAME, host, port);
                    263:        HT_FREE(host);
                    264:        if (!tree) {
                    265:            if (APP_TRACE) HTTrace("PEP Engine.. No information\n");
                    266:            return NULL;
                    267:        }
                    268:     }
                    269: 
                    270:     /* Find a matchind PEP element (if any)) */
                    271:     {
                    272:        char * path = HTParse(url, "", PARSE_PATH);
                    273:        HTList * list = (HTList *) HTUTree_findNode(tree, realm, path);
                    274:        HT_FREE(path);
                    275:        return list;
                    276:     }
                    277:     return NULL;                                                /* No match */
                    278: }
                    279: 
                    280: /*     Add a PEP element to the URL tree
                    281: **     ---------------------------------
                    282: **     Add a protocol context to the PEP tree
                    283: */
                    284: PUBLIC BOOL HTPEP_addNode (const char * protocol,
                    285:                           const char * realm, const char * url,
                    286:                           void * context)
                    287: {
                    288:     HTUTree * tree = NULL;
                    289:     HTPEPModule * module = NULL;
                    290:     if (!protocol || !url) {
                    291:        if (APP_TRACE) HTTrace("PEP Engine.. Bad argument\n");
                    292:        return NO;
                    293:     }
                    294:     if (APP_TRACE) HTTrace("PEP Engine.. Adding info for `%s'\n", url);
                    295: 
                    296:     /* Find the PEP module with this name */
                    297:     if ((module = HTPEP_findModule(protocol)) == NULL) {
                    298:        if (APP_TRACE) HTTrace("PEP Engine.. Module `%s\' not registered\n",
                    299:                               protocol ? protocol : "<null>");
                    300:        return NO;
                    301:     }
                    302: 
                    303:     /* Find an existing PEP tree or create a new one */
                    304:     {
                    305:        char * host = HTParse(url, "", PARSE_HOST);
                    306:        char * colon = strchr(host, ':');
                    307:        int port = DEFAULT_PORT;
                    308:        if (colon ) {
                    309:            *(colon++) = '\0';                       /* Chop off port number */
                    310:            port = atoi(colon);
                    311:        }
                    312:        tree = HTUTree_new(PEP_NAME, host, port, HTPEP_deleteList);
                    313:        HT_FREE(host);
                    314:        if (!tree) {
                    315:            if (APP_TRACE) HTTrace("PEP Engine.. Can't create tree\n");
                    316:            return NO;
                    317:        }
                    318:     }
                    319: 
                    320:     /* Find a matching PEP element or create a new one */
                    321:     {
                    322:        char * path = HTParse(url, "", PARSE_PATH);
                    323:        HTList * list = NULL;
                    324:        HTPEPElement * element = HTPEP_newElement(protocol, context);
                    325: 
                    326:        /*
                    327:        ** If existing list not found then create a new list and add it
                    328:        ** to the tree
                    329:        */
                    330:        if ((list = (HTList *) HTUTree_findNode(tree, realm, path)) == NULL) {
                    331:            list = HTPEP_newList();
                    332:            HTUTree_addNode(tree, realm, path, list);
                    333:        }
                    334:        HT_FREE(path);
                    335: 
                    336:        /* Now add the new element */
                    337:        return HTList_addObject(list, element);
                    338:     }
                    339: }
                    340: 
                    341: /* ------------------------------------------------------------------------- */
                    342: /*                                PEP ENGINE                                */
                    343: /* ------------------------------------------------------------------------- */
                    344: 
                    345: /*     HTPEP_beforeFilter
                    346: **     ------------------
                    347: **     Return YES or whatever callback returns
                    348: */
                    349: PUBLIC int HTPEP_beforeFilter (HTRequest * request, void * param, int status)
                    350: {
                    351:     int ret = HT_OK;
                    352:     char * url = HTAnchor_physical(HTRequest_anchor(request));
                    353:     const char * realm = HTRequest_realm(request);
2.2       frystyk   354:     HTList * list = HTPEP_findList(realm, url);
2.1       frystyk   355:     if (list) {
                    356:        HTPEPElement * pres;
2.2       frystyk   357:        if (APP_TRACE)
                    358:            HTTrace("PEP Engine.. Calling BEFORE protocols %p\n", list);
2.1       frystyk   359:        while ((pres = (HTPEPElement *) HTList_nextObject(list))) {
                    360:            HTPEPModule * module = HTPEP_findModule(pres->name);
                    361:            if (module) {
                    362:                ret = (*module->before)(request, pres->context, status);
                    363:                if (ret != HT_OK) break;
                    364:            }
                    365:        }
                    366:     }
2.2       frystyk   367:     return HT_OK;
2.1       frystyk   368: }
                    369: 
                    370: /*     HTPEP_afterFilter
                    371: **     -----------------
                    372: **     Return YES or whatever callback returns
                    373: */
2.2       frystyk   374: PUBLIC int HTPEP_afterFilter (HTRequest * request, void * param, int status)
2.1       frystyk   375: {
                    376:     int ret = HT_OK;
2.3     ! frystyk   377:     HTAssocList * protocols = HTRequest_serverExtension(request);
2.1       frystyk   378:     if (protocols) {
                    379:        HTPEPElement * pres;
2.2       frystyk   380:        if (APP_TRACE)
                    381:            HTTrace("PEP Engine.. Calling AFTER protocols %p\n", protocols);
2.1       frystyk   382:        while ((pres = (HTPEPElement *) HTList_nextObject(protocols))) {
                    383:            HTPEPModule * module = HTPEP_findModule(pres->name);
                    384:            if (module) {
                    385:                ret = (*module->after)(request, pres->context, status);
                    386:                if (ret != HT_OK) break;
                    387:            }
                    388:        }
                    389:     }
2.2       frystyk   390:     return HT_OK;
2.1       frystyk   391: }

Webmaster