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