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

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) {
2.3     ! frystyk    84:            if (PROT_TRACE)
2.1       frystyk    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:        }
2.3     ! frystyk    92:        if (PROT_TRACE)
2.1       frystyk    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 */
2.3     ! frystyk   206:     if (PROT_TRACE)
2.1       frystyk   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=='.')) {
2.3     ! frystyk   304:                            if (PROT_TRACE)
2.1       frystyk   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);
2.2       frystyk   323:                if (PROT_TRACE)
                    324:                    fprintf(TDEST, "GetProxy.... Found: `%s\'\n", pres->url);
2.1       frystyk   325:                break;
                    326:            }
                    327:        }
                    328:     }
                    329:     FREE(access);
                    330:     return proxy;
                    331: #else
                    332:     return NULL
                    333: #endif /* !HT_NO_PROXY */
                    334:     }
                    335: 
                    336: 
                    337: /*                                                     HTProxy_getGateway
                    338: **
                    339: **     This function evaluates the lists of registered gateways and if
                    340: **     one is found for the actual access method then it is returned
                    341: **
                    342: **     Returns: gateway If OK (must be freed by caller)
                    343: **              NULL    If no gateway is found or error
                    344: */
                    345: PUBLIC char * HTProxy_getGateway ARGS1(CONST char *, url)
                    346: {
                    347: #ifndef HT_NO_PROXY
                    348:     char * access;
                    349:     char * gateway = NULL;
                    350:     if (!url || !gateways)
                    351:        return NULL;
                    352:     access = HTParse(url, "", PARSE_ACCESS);
                    353: 
                    354:     /* Check if we have a gateway registered for this access method */
                    355:     {
                    356:        HTList *cur = gateways;
                    357:        HTProxy *pres;
                    358:        while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
                    359:            if (!strcmp(pres->access, access)) {
                    360:                StrAllocCopy(gateway, pres->url);
2.2       frystyk   361:                if (PROT_TRACE)
                    362:                    fprintf(TDEST, "GetGateway.. Found: `%s\'\n", pres->url);
2.1       frystyk   363:                break;
                    364:            }
                    365:        }
                    366:     }
                    367:     FREE(access);
                    368:     return gateway;
                    369: #else
                    370:     return NULL
                    371: #endif /* !HT_NO_PROXY */
                    372: }
                    373: 
                    374: 
                    375: /*
                    376: **     This function maintains backwards compatibility with the old 
                    377: **     environment variables and searches for the most common values:
                    378: **     http, ftp, news, wais, and gopher
                    379: */
                    380: PUBLIC void HTProxy_getEnvVar NOARGS
                    381: {
                    382: #ifndef HT_NO_PROXY
                    383:     char buf[80];
                    384:     static CONST char *accesslist[] = {
                    385:        "http",
                    386:        "ftp",
                    387:        "news",
                    388:        "wais",
                    389:        "gopher",
                    390:        NULL
                    391:     };
                    392:     CONST char **access = accesslist;
                    393:     while (*access) {
                    394:        char *gateway=NULL;
                    395:        char *proxy=NULL;
                    396: 
                    397:        /* search for proxy gateways */
                    398:        strcpy(buf, *access);
                    399:        strcat(buf, "_proxy");
                    400:        if ((proxy = (char *) getenv(buf)) && *proxy)
                    401:            HTProxy_setProxy(*access, proxy);
                    402: 
                    403:        /* search for gateway servers */
                    404:        strcpy(buf, "WWW_");
                    405:        strcat(buf, *access);
                    406:        strcat(buf, "_GATEWAY");
                    407:        if ((gateway = (char *) getenv(buf)) && *gateway)
                    408:            HTProxy_setGateway(*access, gateway);
                    409:        ++access;
                    410:     }
                    411: 
                    412:     /* Search for `noproxy' directive */
                    413:     {
                    414:        char *noproxy = getenv("no_proxy");
                    415:        if (noproxy && *noproxy) {
                    416:            char *str = NULL;
                    417:            char *strptr;
                    418:            char *name;
                    419:            StrAllocCopy(str, noproxy);          /* Get copy we can mutilate */
                    420:            strptr = str;
                    421:            while ((name = HTNextField(&strptr)) != NULL) {
                    422:                char *portstr = strchr(name, ':');
                    423:                unsigned port=0;
                    424:                if (portstr) {
                    425:                    *portstr++ = '\0';
                    426:                    if (*portstr) port = (unsigned) atoi(portstr);
                    427:                }
                    428: 
                    429:                /* Register it for all access methods */
                    430:                HTProxy_setNoProxy(name, NULL, port);
                    431:            }
                    432:            free(str);
                    433:        }
                    434:     }
                    435: #endif /* !HT_NO_PROXY */
                    436: }
                    437: 

Webmaster