HTProxy.c
Upload User: zlh9724
Upload Date: 2007-01-04
Package Size: 1991k
Code Size: 11k
Category:

Browser Client

Development Platform:

Unix_Linux

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