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

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

Webmaster