Annotation of libwww/Library/src/HTProxy.c, revision 2.5
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:
2.4 frystyk 53: /*
2.1 frystyk 54: ** Existing entries are replaced with new ones
55: */
2.4 frystyk 56: PRIVATE BOOL add_object (HTList * list, CONST char * access, CONST char * url)
2.1 frystyk 57: {
58: HTProxy *me;
59: if (!list || !access || !url || !*url)
60: return NO;
61: if ((me = (HTProxy *) calloc(1, sizeof(HTProxy))) == NULL)
2.4 frystyk 62: outofmem(__FILE__, "add_object");
2.1 frystyk 63: StrAllocCopy(me->access, access); /* Access method */
64: {
65: char *ptr = me->access;
66: while ((*ptr = TOLOWER(*ptr))) ptr++;
67: }
68: me->url = HTParse(url, "", PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION);
69: if (*(me->url+strlen(me->url)-1) != '/')
70: StrAllocCat(me->url, "/");
71: me->url = HTSimplify(&me->url);
72:
73: /* See if we already have this one */
74: {
75: HTList *cur = list;
76: HTProxy *pres;
77: while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
78: if (!strcmp(pres->access, me->access))
79: break; /* We already have it */
80: }
81: if (pres) {
2.3 frystyk 82: if (PROT_TRACE)
2.5 ! frystyk 83: TTYPrint(TDEST, "HTProxy..... replacing for `%s\' access %s\n",
2.1 frystyk 84: me->url, me->access);
85: FREE(pres->access);
86: FREE(pres->url);
87: HTList_removeObject(list, (void *) pres);
88: free(pres);
89: }
2.3 frystyk 90: if (PROT_TRACE)
2.5 ! frystyk 91: TTYPrint(TDEST, "HTProxy..... adding for `%s\' access %s\n",
2.1 frystyk 92: me->url, me->access);
93: HTList_addObject(list, (void *) me);
94: }
95: return YES;
96: }
97:
2.4 frystyk 98: PRIVATE BOOL remove_allObjects (HTList * list)
2.1 frystyk 99: {
100: if (list) {
101: HTList *cur = list;
102: HTProxy *pres;
103: while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
104: FREE(pres->access);
105: FREE(pres->url);
106: free(pres);
107: }
108: return YES;
109: }
110: return NO;
111: }
112:
2.4 frystyk 113: /* Add an entry to a list of host names
114: ** ------------------------------------
115: ** Existing entries are replaced with new ones
116: */
117: PRIVATE BOOL add_hostname (HTList * list, CONST char * host,
118: CONST char * access, unsigned port)
119: {
120: HTHostList *me;
121: if (!list || !host || !*host)
122: return NO;
123: if ((me = (HTHostList *) calloc(1, sizeof(HTHostList))) == NULL)
124: outofmem(__FILE__, "add_hostname");
125: if (access) {
126: char *ptr;
127: StrAllocCopy(me->access, access); /* Access method */
128: ptr = me->access;
129: while ((*ptr = TOLOWER(*ptr))) ptr++;
130: }
131: StrAllocCopy(me->host, host); /* Host name */
132: {
133: char *ptr = me->host;
134: while ((*ptr = TOLOWER(*ptr))) ptr++;
135: }
136: me->port = port; /* Port number */
137: if (PROT_TRACE)
2.5 ! frystyk 138: TTYPrint(TDEST, "HTHostList.. adding `%s\' to list\n", me->host);
2.4 frystyk 139: HTList_addObject(list, (void *) me);
140: return YES;
141: }
2.1 frystyk 142:
2.4 frystyk 143: PRIVATE BOOL remove_AllHostnames (HTList * list)
144: {
145: if (list) {
146: HTList *cur = list;
147: HTHostList *pres;
148: while ((pres = (HTHostList *) HTList_nextObject(cur)) != NULL) {
149: FREE(pres->access);
150: FREE(pres->host);
151: free(pres);
152: }
153: return YES;
154: }
155: return NO;
156: }
157:
158: /* HTProxy_add
159: ** -----------
2.1 frystyk 160: ** Registers a proxy as the server to contact for a specific
161: ** access method. `proxy' should be a fully valid name, like
162: ** "http://proxy.w3.org:8001" but domain name is not required.
163: ** If an entry exists for this access then delete it and use the
164: ** ne one. Returns YES if OK, else NO
165: */
2.4 frystyk 166: PUBLIC BOOL HTProxy_add (CONST char * access, CONST char * proxy)
2.1 frystyk 167: {
168: if (!proxies)
169: proxies = HTList_new();
2.4 frystyk 170: return add_object(proxies, access, proxy);
2.1 frystyk 171: }
172:
2.4 frystyk 173: /*
2.1 frystyk 174: ** Removes all registered proxies
175: */
2.4 frystyk 176: PUBLIC BOOL HTProxy_deleteAll (void)
2.1 frystyk 177: {
2.4 frystyk 178: if (remove_allObjects(proxies)) {
2.1 frystyk 179: HTList_delete(proxies);
180: proxies = NULL;
181: return YES;
182: }
183: return NO;
184: }
185:
2.4 frystyk 186: /* HTGateway_add
187: ** -------------
2.1 frystyk 188: ** Registers a gateway as the server to contact for a specific
189: ** access method. `gateway' should be a fully valid name, like
190: ** "http://gateway.w3.org:8001" but domain name is not required.
191: ** If an entry exists for this access then delete it and use the
192: ** ne one. Returns YES if OK, else NO
193: */
2.4 frystyk 194: PUBLIC BOOL HTGateway_add (CONST char * access, CONST char * gate)
2.1 frystyk 195: {
196: if (!gateways)
197: gateways = HTList_new();
2.4 frystyk 198: return add_object(gateways, access, gate);
2.1 frystyk 199: }
200:
2.4 frystyk 201: /*
2.1 frystyk 202: ** Removes all registered gateways
203: */
2.4 frystyk 204: PUBLIC BOOL HTGateway_deleteAll (void)
2.1 frystyk 205: {
2.4 frystyk 206: if (remove_allObjects(gateways)) {
2.1 frystyk 207: HTList_delete(gateways);
208: gateways = NULL;
209: return YES;
210: }
211: return NO;
212: }
213:
2.4 frystyk 214: /* HTNoProxy_add
215: ** -------------
2.1 frystyk 216: ** Registers a host name or a domain as a place where no proxy should
217: ** be contacted - for example a very fast link. If `port' is '0' then
218: ** it applies to all ports and if `access' is NULL then it applies to
219: ** to all access methods.
220: **
221: ** Examples: w3.org
222: ** www.close.com
223: */
2.4 frystyk 224: PUBLIC BOOL HTNoProxy_add (CONST char * host, CONST char * access,
225: unsigned port)
2.1 frystyk 226: {
227: if (!noproxy)
228: noproxy = HTList_new();
2.4 frystyk 229: return add_hostname(noproxy, host, access, port);
2.1 frystyk 230: }
231:
2.4 frystyk 232: /* HTNoProxy_deleteAll
233: ** -------------------
2.1 frystyk 234: ** Removes all registered no_proxy directives
235: */
2.4 frystyk 236: PUBLIC BOOL HTNoProxy_deleteAll (void)
2.1 frystyk 237: {
2.4 frystyk 238: if (remove_AllHostnames(noproxy)) {
2.1 frystyk 239: HTList_delete(noproxy);
240: noproxy = NULL;
241: return YES;
242: }
243: return NO;
244: }
245:
2.4 frystyk 246: /* HTProxy_find
247: ** ------------
2.1 frystyk 248: ** This function evaluates the lists of registered proxies and if
249: ** one is found for the actual access method and it is not registered
250: ** in the `noproxy' list, then a URL containing the host to be contacted
251: ** is returned to the caller. This string must be freed be the caller.
252: **
253: ** Returns: proxy If OK (must be freed by caller)
254: ** NULL If no proxy is found or error
255: */
2.4 frystyk 256: PUBLIC char * HTProxy_find (CONST char * url)
2.1 frystyk 257: {
258: #ifndef HT_NO_PROXY
259: char * access;
260: char * proxy = NULL;
261: if (!url || !proxies)
262: return NULL;
263: access = HTParse(url, "", PARSE_ACCESS);
264:
265: /* First check if the host (if any) is registered in the noproxy list */
266: if (noproxy) {
267: char *host = HTParse(url, "", PARSE_HOST);
268: char *ptr;
269: unsigned port=0;
270: if ((ptr = strchr(host, ':')) != NULL) {
271: *ptr++ = '\0'; /* Chop off port */
272: if (*ptr) port = (unsigned) atoi(ptr);
273: }
274: if (*host) { /* If we have a host name */
275: HTList *cur = noproxy;
276: HTHostList *pres;
277: while ((pres = (HTHostList *) HTList_nextObject(cur)) != NULL) {
278: if (!pres->access ||
279: (pres->access && !strcmp(pres->access, access))) {
280: if (pres->port == port) {
281: char *np = pres->host+strlen(pres->host);
282: char *hp = host+strlen(host);
283: while (np>=pres->host && hp>=host && (*np--==*hp--));
284: if (np==pres->host-1 && (hp==host-1 || *hp=='.')) {
2.3 frystyk 285: if (PROT_TRACE)
2.5 ! frystyk 286: TTYPrint(TDEST, "GetProxy.... No proxy directive found: `%s\'\n", pres->host);
2.1 frystyk 287: FREE(access);
288: return NULL;
289: }
290: }
291: }
292: }
293: }
294: FREE(host);
295: }
296:
297: /* Now check if we have a proxy registered for this access method */
298: {
299: HTList *cur = proxies;
300: HTProxy *pres;
301: while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
302: if (!strcmp(pres->access, access)) {
303: StrAllocCopy(proxy, pres->url);
2.2 frystyk 304: if (PROT_TRACE)
2.5 ! frystyk 305: TTYPrint(TDEST, "GetProxy.... Found: `%s\'\n", pres->url);
2.1 frystyk 306: break;
307: }
308: }
309: }
310: FREE(access);
311: return proxy;
312: #else
313: return NULL
314: #endif /* !HT_NO_PROXY */
315: }
316:
317:
2.4 frystyk 318: /* HTGateway_find
319: ** --------------
2.1 frystyk 320: ** This function evaluates the lists of registered gateways and if
321: ** one is found for the actual access method then it is returned
322: **
323: ** Returns: gateway If OK (must be freed by caller)
324: ** NULL If no gateway is found or error
325: */
2.4 frystyk 326: PUBLIC char * HTGateway_find (CONST char * url)
2.1 frystyk 327: {
328: #ifndef HT_NO_PROXY
329: char * access;
330: char * gateway = NULL;
331: if (!url || !gateways)
332: return NULL;
333: access = HTParse(url, "", PARSE_ACCESS);
334:
335: /* Check if we have a gateway registered for this access method */
336: {
337: HTList *cur = gateways;
338: HTProxy *pres;
339: while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) {
340: if (!strcmp(pres->access, access)) {
341: StrAllocCopy(gateway, pres->url);
2.2 frystyk 342: if (PROT_TRACE)
2.5 ! frystyk 343: TTYPrint(TDEST, "GetGateway.. Found: `%s\'\n", pres->url);
2.1 frystyk 344: break;
345: }
346: }
347: }
348: FREE(access);
349: return gateway;
350: #else
351: return NULL
352: #endif /* !HT_NO_PROXY */
353: }
354:
355:
356: /*
357: ** This function maintains backwards compatibility with the old
358: ** environment variables and searches for the most common values:
359: ** http, ftp, news, wais, and gopher
360: */
2.4 frystyk 361: PUBLIC void HTProxy_getEnvVar (void)
2.1 frystyk 362: {
363: #ifndef HT_NO_PROXY
364: char buf[80];
365: static CONST char *accesslist[] = {
366: "http",
367: "ftp",
368: "news",
369: "wais",
370: "gopher",
371: NULL
372: };
373: CONST char **access = accesslist;
374: while (*access) {
375: char *gateway=NULL;
376: char *proxy=NULL;
377:
378: /* search for proxy gateways */
379: strcpy(buf, *access);
380: strcat(buf, "_proxy");
381: if ((proxy = (char *) getenv(buf)) && *proxy)
2.4 frystyk 382: HTProxy_add(*access, proxy);
2.1 frystyk 383:
384: /* search for gateway servers */
385: strcpy(buf, "WWW_");
386: strcat(buf, *access);
387: strcat(buf, "_GATEWAY");
388: if ((gateway = (char *) getenv(buf)) && *gateway)
2.4 frystyk 389: HTGateway_add(*access, gateway);
2.1 frystyk 390: ++access;
391: }
392:
393: /* Search for `noproxy' directive */
394: {
395: char *noproxy = getenv("no_proxy");
396: if (noproxy && *noproxy) {
397: char *str = NULL;
398: char *strptr;
399: char *name;
400: StrAllocCopy(str, noproxy); /* Get copy we can mutilate */
401: strptr = str;
402: while ((name = HTNextField(&strptr)) != NULL) {
403: char *portstr = strchr(name, ':');
404: unsigned port=0;
405: if (portstr) {
406: *portstr++ = '\0';
407: if (*portstr) port = (unsigned) atoi(portstr);
408: }
409:
410: /* Register it for all access methods */
2.4 frystyk 411: HTNoProxy_add(name, NULL, port);
2.1 frystyk 412: }
413: free(str);
414: }
415: }
416: #endif /* !HT_NO_PROXY */
417: }
418:
Webmaster