Annotation of libwww/Library/src/HTProxy.c, revision 2.10

2.1       frystyk     1: /*                                                                  HTProxy.c
                      2: **     GATEWAY AND PROXY MANAGER
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.10    ! frystyk     6: **     @(#) $Id: Date Author State $
2.1       frystyk     7: **
                      8: **     Replaces the old env variables for gateways and proxies. However for
                      9: **     backward compatibility there is a function that reads the env variables
                     10: **     at start up. Note that there is a difference between a proxy and a
                     11: **     gateway!
                     12: **
                     13: ** Authors
                     14: **     HF      Henrik Frystyk, frystyk@w3.org
                     15: ** History
                     16: **       4 Jun 95 Written on a rainy day
                     17: */
                     18: 
                     19: #if !defined(HT_DIRECT_WAIS) && !defined(HT_DEFAULT_WAIS_GATEWAY)
                     20: #define HT_DEFAULT_WAIS_GATEWAY "http://www.w3.org:8001/"
                     21: #endif
                     22: 
                     23: /* Library include files */
2.9       frystyk    24: #include "sysdep.h"
2.1       frystyk    25: #include "HTUtils.h"
                     26: #include "HTString.h"
                     27: #include "HTList.h"
                     28: #include "HTParse.h"
2.6       frystyk    29: #include "HTWWWStr.h"
2.1       frystyk    30: #include "HTProxy.h"                                    /* Implemented here */
                     31: 
                     32: /* Variables and typedefs local to this module */
                     33: 
                     34: typedef struct _HTProxy {
                     35:     char *     access;
                     36:     char *     url;                              /* URL of Gateway or Proxy */
                     37: } HTProxy;
                     38: 
                     39: typedef struct _HTHostlist {
                     40:     char *     access;
                     41:     char *     host;                                 /* Host or domain name */
                     42:     unsigned   port;
                     43: } HTHostList;
                     44: 
                     45: PRIVATE HTList * proxies = NULL;                   /* List of proxy servers */
                     46: PRIVATE HTList * gateways = NULL;                       /* List of gateways */
                     47: PRIVATE HTList * noproxy = NULL;   /* Don't proxy on these hosts and domains */
                     48: 
                     49: #if 0
                     50: PRIVATE HTList * onlyproxy = NULL;  /* Proxy only on these hosts and domains */
                     51: #endif
                     52: 
                     53: /* ------------------------------------------------------------------------- */
                     54: 
2.4       frystyk    55: /*
2.1       frystyk    56: **     Existing entries are replaced with new ones
                     57: */
2.9       frystyk    58: PRIVATE BOOL add_object (HTList * list, const char * access, const char * url)
2.1       frystyk    59: {
                     60:     HTProxy *me;
                     61:     if (!list || !access || !url || !*url)
                     62:        return NO;
2.7       frystyk    63:     if ((me = (HTProxy *) HT_CALLOC(1, sizeof(HTProxy))) == NULL)
                     64:        HT_OUTOFMEM("add_object");
2.1       frystyk    65:     StrAllocCopy(me->access, access);                      /* Access method */
                     66:     {
                     67:        char *ptr = me->access;
                     68:        while ((*ptr = TOLOWER(*ptr))) ptr++;
                     69:     }
                     70:     me->url = HTParse(url, "", PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION);
                     71:     if (*(me->url+strlen(me->url)-1) != '/')
                     72:        StrAllocCat(me->url, "/");
                     73:     me->url = HTSimplify(&me->url);
                     74: 
                     75:     /* See if we already have this one */
                     76:     {
                     77:        HTList *cur = list;
                     78:        HTProxy *pres;
                     79:        while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
                     80:            if (!strcmp(pres->access, me->access))
                     81:                break;                                 /* We already have it */
                     82:        }
                     83:        if (pres) {
2.3       frystyk    84:            if (PROT_TRACE)
2.8       eric       85:                HTTrace("HTProxy..... replacing for `%s\' access %s\n",
2.1       frystyk    86:                        me->url, me->access);
2.7       frystyk    87:            HT_FREE(pres->access);
                     88:            HT_FREE(pres->url);
2.1       frystyk    89:            HTList_removeObject(list, (void *) pres);
2.7       frystyk    90:            HT_FREE(pres);
2.1       frystyk    91:        }
2.3       frystyk    92:        if (PROT_TRACE)
2.8       eric       93:            HTTrace("HTProxy..... adding for `%s\' access %s\n",
2.1       frystyk    94:                    me->url, me->access);
                     95:        HTList_addObject(list, (void *) me);
                     96:     }
                     97:     return YES;
                     98: }
                     99: 
2.4       frystyk   100: PRIVATE BOOL remove_allObjects (HTList * list)
2.1       frystyk   101: {
                    102:     if (list) {
                    103:        HTList *cur = list;
                    104:        HTProxy *pres;
                    105:        while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
2.7       frystyk   106:            HT_FREE(pres->access);
                    107:            HT_FREE(pres->url);
                    108:            HT_FREE(pres);
2.1       frystyk   109:        }
                    110:        return YES;
                    111:     }
                    112:     return NO;
                    113: }
                    114: 
2.4       frystyk   115: /*     Add an entry to a list of host names
                    116: **     ------------------------------------
                    117: **     Existing entries are replaced with new ones
                    118: */
2.9       frystyk   119: PRIVATE BOOL add_hostname (HTList * list, const char * host,
                    120:                           const char * access, unsigned port)
2.4       frystyk   121: {
                    122:     HTHostList *me;
                    123:     if (!list || !host || !*host)
                    124:        return NO;
2.7       frystyk   125:     if ((me = (HTHostList *) HT_CALLOC(1, sizeof(HTHostList))) == NULL)
                    126:         HT_OUTOFMEM("add_hostname");
2.4       frystyk   127:     if (access) {
                    128:        char *ptr;
                    129:        StrAllocCopy(me->access, access);                   /* Access method */
                    130:        ptr = me->access;
                    131:        while ((*ptr = TOLOWER(*ptr))) ptr++;
                    132:     }
                    133:     StrAllocCopy(me->host, host);                              /* Host name */
                    134:     {
                    135:        char *ptr = me->host;
                    136:        while ((*ptr = TOLOWER(*ptr))) ptr++;
                    137:     }
                    138:     me->port = port;                                         /* Port number */
                    139:     if (PROT_TRACE)
2.8       eric      140:        HTTrace("HTHostList.. adding `%s\' to list\n", me->host);
2.4       frystyk   141:     HTList_addObject(list, (void *) me);
                    142:     return YES;
                    143: }
2.1       frystyk   144: 
2.4       frystyk   145: PRIVATE BOOL remove_AllHostnames (HTList * list)
                    146: {
                    147:     if (list) {
                    148:        HTList *cur = list;
                    149:        HTHostList *pres;
                    150:        while ((pres = (HTHostList *) HTList_nextObject(cur)) != NULL) {
2.7       frystyk   151:            HT_FREE(pres->access);
                    152:            HT_FREE(pres->host);
                    153:            HT_FREE(pres);
2.4       frystyk   154:        }
                    155:        return YES;
                    156:     }
                    157:     return NO;
                    158: }
                    159: 
                    160: /*     HTProxy_add
                    161: **     -----------
2.1       frystyk   162: **     Registers a proxy as the server to contact for a specific
                    163: **     access method. `proxy' should be a fully valid name, like
                    164: **     "http://proxy.w3.org:8001" but domain name is not required.
                    165: **     If an entry exists for this access then delete it and use the 
                    166: **     ne one. Returns YES if OK, else NO
                    167: */
2.9       frystyk   168: PUBLIC BOOL HTProxy_add (const char * access, const char * proxy)
2.1       frystyk   169: {
                    170:     if (!proxies)
                    171:        proxies = HTList_new();    
2.4       frystyk   172:     return add_object(proxies, access, proxy);
2.1       frystyk   173: }
                    174: 
2.4       frystyk   175: /*
2.1       frystyk   176: **     Removes all registered proxies
                    177: */
2.4       frystyk   178: PUBLIC BOOL HTProxy_deleteAll (void)
2.1       frystyk   179: {
2.4       frystyk   180:     if (remove_allObjects(proxies)) {
2.1       frystyk   181:        HTList_delete(proxies);
                    182:        proxies = NULL;
                    183:        return YES;
                    184:     }
                    185:     return NO;
                    186: }
                    187: 
2.4       frystyk   188: /*     HTGateway_add
                    189: **     -------------
2.1       frystyk   190: **     Registers a gateway as the server to contact for a specific
                    191: **     access method. `gateway' should be a fully valid name, like
                    192: **     "http://gateway.w3.org:8001" but domain name is not required.
                    193: **     If an entry exists for this access then delete it and use the 
                    194: **     ne one. Returns YES if OK, else NO
                    195: */
2.9       frystyk   196: PUBLIC BOOL HTGateway_add (const char * access, const char * gate)
2.1       frystyk   197: {
                    198:     if (!gateways)
                    199:        gateways = HTList_new();
2.4       frystyk   200:     return add_object(gateways, access, gate);
2.1       frystyk   201: }
                    202: 
2.4       frystyk   203: /*
2.1       frystyk   204: **     Removes all registered gateways
                    205: */
2.4       frystyk   206: PUBLIC BOOL HTGateway_deleteAll (void)
2.1       frystyk   207: {
2.4       frystyk   208:     if (remove_allObjects(gateways)) {
2.1       frystyk   209:        HTList_delete(gateways);
                    210:        gateways = NULL;
                    211:        return YES;
                    212:     }
                    213:     return NO;
                    214: }
                    215: 
2.4       frystyk   216: /*     HTNoProxy_add
                    217: **     -------------
2.1       frystyk   218: **     Registers a host name or a domain as a place where no proxy should
                    219: **     be contacted - for example a very fast link. If `port' is '0' then
                    220: **     it applies to all ports and if `access' is NULL then it applies to
                    221: **     to all access methods.
                    222: **
                    223: **     Examples:       w3.org
                    224: **                     www.close.com
                    225: */
2.9       frystyk   226: PUBLIC BOOL HTNoProxy_add (const char * host, const char * access,
2.4       frystyk   227:                           unsigned port)
2.1       frystyk   228: {
                    229:     if (!noproxy)
                    230:        noproxy = HTList_new();    
2.4       frystyk   231:     return add_hostname(noproxy, host, access, port);
2.1       frystyk   232: }
                    233: 
2.4       frystyk   234: /*     HTNoProxy_deleteAll
                    235: **     -------------------
2.1       frystyk   236: **     Removes all registered no_proxy directives
                    237: */
2.4       frystyk   238: PUBLIC BOOL HTNoProxy_deleteAll (void)
2.1       frystyk   239: {
2.4       frystyk   240:     if (remove_AllHostnames(noproxy)) {
2.1       frystyk   241:        HTList_delete(noproxy);
                    242:        noproxy = NULL;
                    243:        return YES;
                    244:     }
                    245:     return NO;
                    246: }
                    247: 
2.4       frystyk   248: /*     HTProxy_find
                    249: **     ------------
2.1       frystyk   250: **     This function evaluates the lists of registered proxies and if
                    251: **     one is found for the actual access method and it is not registered
                    252: **     in the `noproxy' list, then a URL containing the host to be contacted
                    253: **     is returned to the caller. This string must be freed be the caller.
                    254: **
                    255: **     Returns: proxy  If OK (must be freed by caller)
                    256: **              NULL   If no proxy is found or error
                    257: */
2.9       frystyk   258: PUBLIC char * HTProxy_find (const char * url)
2.1       frystyk   259: {
                    260:     char * access;
                    261:     char * proxy = NULL;
                    262:     if (!url || !proxies)
                    263:        return NULL;
                    264:     access = HTParse(url, "", PARSE_ACCESS);
                    265: 
                    266:     /* First check if the host (if any) is registered in the noproxy list */
                    267:     if (noproxy) {
                    268:        char *host = HTParse(url, "", PARSE_HOST);
                    269:        char *ptr;
                    270:        unsigned port=0;
                    271:        if ((ptr = strchr(host, ':')) != NULL) {
                    272:            *ptr++ = '\0';                                  /* Chop off port */
                    273:            if (*ptr) port = (unsigned) atoi(ptr);
                    274:        }
                    275:        if (*host) {                               /* If we have a host name */
                    276:            HTList *cur = noproxy;
                    277:            HTHostList *pres;
                    278:            while ((pres = (HTHostList *) HTList_nextObject(cur)) != NULL) {
                    279:                if (!pres->access ||
                    280:                    (pres->access && !strcmp(pres->access, access))) {
                    281:                    if (pres->port == port) {
                    282:                        char *np = pres->host+strlen(pres->host);
                    283:                        char *hp = host+strlen(host);
                    284:                        while (np>=pres->host && hp>=host && (*np--==*hp--));
                    285:                        if (np==pres->host-1 && (hp==host-1 || *hp=='.')) {
2.3       frystyk   286:                            if (PROT_TRACE)
2.8       eric      287:                                HTTrace("GetProxy.... No proxy directive found: `%s\'\n", pres->host);
2.7       frystyk   288:                            HT_FREE(access);
2.1       frystyk   289:                            return NULL;
                    290:                        }
                    291:                    }
                    292:                }
                    293:            }
                    294:        }
2.7       frystyk   295:        HT_FREE(host);
2.1       frystyk   296:     }
                    297: 
                    298:     /* Now check if we have a proxy registered for this access method */
                    299:     {
                    300:        HTList *cur = proxies;
                    301:        HTProxy *pres;
                    302:        while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
                    303:            if (!strcmp(pres->access, access)) {
                    304:                StrAllocCopy(proxy, pres->url);
2.2       frystyk   305:                if (PROT_TRACE)
2.8       eric      306:                    HTTrace("GetProxy.... Found: `%s\'\n", pres->url);
2.1       frystyk   307:                break;
                    308:            }
                    309:        }
                    310:     }
2.7       frystyk   311:     HT_FREE(access);
2.1       frystyk   312:     return proxy;
2.9       frystyk   313: }
2.1       frystyk   314: 
                    315: 
2.4       frystyk   316: /*     HTGateway_find
                    317: **     --------------
2.1       frystyk   318: **     This function evaluates the lists of registered gateways and if
                    319: **     one is found for the actual access method then it is returned
                    320: **
                    321: **     Returns: gateway If OK (must be freed by caller)
                    322: **              NULL    If no gateway is found or error
                    323: */
2.9       frystyk   324: PUBLIC char * HTGateway_find (const char * url)
2.1       frystyk   325: {
                    326:     char * access;
                    327:     char * gateway = NULL;
                    328:     if (!url || !gateways)
                    329:        return NULL;
                    330:     access = HTParse(url, "", PARSE_ACCESS);
                    331: 
                    332:     /* Check if we have a gateway registered for this access method */
                    333:     {
                    334:        HTList *cur = gateways;
                    335:        HTProxy *pres;
                    336:        while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
                    337:            if (!strcmp(pres->access, access)) {
                    338:                StrAllocCopy(gateway, pres->url);
2.2       frystyk   339:                if (PROT_TRACE)
2.8       eric      340:                    HTTrace("GetGateway.. Found: `%s\'\n", pres->url);
2.1       frystyk   341:                break;
                    342:            }
                    343:        }
                    344:     }
2.7       frystyk   345:     HT_FREE(access);
2.1       frystyk   346:     return gateway;
                    347: }
                    348: 
                    349: 
                    350: /*
                    351: **     This function maintains backwards compatibility with the old 
                    352: **     environment variables and searches for the most common values:
                    353: **     http, ftp, news, wais, and gopher
                    354: */
2.4       frystyk   355: PUBLIC void HTProxy_getEnvVar (void)
2.1       frystyk   356: {
                    357:     char buf[80];
2.9       frystyk   358:     static const char *accesslist[] = {
2.1       frystyk   359:        "http",
                    360:        "ftp",
                    361:        "news",
                    362:        "wais",
                    363:        "gopher",
                    364:        NULL
                    365:     };
2.9       frystyk   366:     const char **access = accesslist;
2.1       frystyk   367:     while (*access) {
                    368:        char *gateway=NULL;
                    369:        char *proxy=NULL;
                    370: 
                    371:        /* search for proxy gateways */
                    372:        strcpy(buf, *access);
                    373:        strcat(buf, "_proxy");
                    374:        if ((proxy = (char *) getenv(buf)) && *proxy)
2.4       frystyk   375:            HTProxy_add(*access, proxy);
2.1       frystyk   376: 
                    377:        /* search for gateway servers */
                    378:        strcpy(buf, "WWW_");
                    379:        strcat(buf, *access);
                    380:        strcat(buf, "_GATEWAY");
                    381:        if ((gateway = (char *) getenv(buf)) && *gateway)
2.4       frystyk   382:            HTGateway_add(*access, gateway);
2.1       frystyk   383:        ++access;
                    384:     }
                    385: 
                    386:     /* Search for `noproxy' directive */
                    387:     {
                    388:        char *noproxy = getenv("no_proxy");
                    389:        if (noproxy && *noproxy) {
                    390:            char *str = NULL;
                    391:            char *strptr;
                    392:            char *name;
                    393:            StrAllocCopy(str, noproxy);          /* Get copy we can mutilate */
                    394:            strptr = str;
                    395:            while ((name = HTNextField(&strptr)) != NULL) {
                    396:                char *portstr = strchr(name, ':');
                    397:                unsigned port=0;
                    398:                if (portstr) {
                    399:                    *portstr++ = '\0';
                    400:                    if (*portstr) port = (unsigned) atoi(portstr);
                    401:                }
                    402: 
                    403:                /* Register it for all access methods */
2.4       frystyk   404:                HTNoProxy_add(name, NULL, port);
2.1       frystyk   405:            }
2.7       frystyk   406:            HT_FREE(str);
2.1       frystyk   407:        }
                    408:     }
                    409: }
                    410: 

Webmaster