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