📄 htaccess.c
字号:
/* Access Manager HTAccess.c** ==============**** Authors** TBL Tim Berners-Lee timbl@info.cern.ch** JFG Jean-Francois Groff jfg@dxcern.cern.ch** DD Denis DeLaRoca (310) 825-4580 <CSP1DWD@mvs.oac.ucla.edu>** FM Foteos Macrides macrides@sci.wfeb.edu** PDM Danny Mayer mayer@ljo.dec.com**** History** 8 Jun 92 Telnet hopping prohibited as telnet is not secure TBL** 26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. JFG** 6 Oct 92 Moved HTClientHost and logfile into here. TBL** 17 Dec 92 Tn3270 added, bug fix. DD** 4 Feb 93 Access registration, Search escapes bad chars TBL** PARAMETERS TO HTSEARCH AND HTLOADRELATIVE CHANGED** 28 May 93 WAIS gateway explicit if no WAIS library linked in.** 31 May 94 Added DIRECT_WAIS support for VMS. FM** 27 Jan 95 Fixed proxy support to use NNTPSERVER for checking** whether or not to use the proxy server. PDM** 27 Jan 95 Ensured that proxy service will be overridden for files** on the local host (because HTLoadFile() doesn't try ftp** for those) and will substitute ftp for remote files. FM** 28 Jan 95 Tweeked PDM's proxy override mods to handle port info** for news and wais URL's. FM**** Bugs** This module assumes that that the graphic object is hypertext, as it** needs to select it when it has been loaded. A superclass needs to be** defined which accepts select and select_anchor.*/#ifdef VMS#define DIRECT_WAIS#endif /* VMS */#include <HTUtils.h>#include <HTTP.h>#include <HTAlert.h>/*** Implements:*/#include <HTAccess.h>/*** Uses:*/#include <HTParse.h>#include <HTML.h> /* SCW */#ifndef NO_RULES#include <HTRules.h>#endif#include <HTList.h>#include <HText.h> /* See bugs above */#include <HTCJK.h>#include <UCMap.h>#include <GridText.h>#include <LYGlobalDefs.h>#include <LYexit.h>#include <LYUtils.h>#include <LYLeaks.h>/*** These flags may be set to modify the operation of this module*/PUBLIC char * HTClientHost = NULL; /* Name of remote login host if any */PUBLIC FILE * HTlogfile = NULL; /* File to which to output one-liners */PUBLIC BOOL HTSecure = NO; /* Disable access for telnet users? */PUBLIC BOOL HTPermitRedir = NO; /* Always allow redirection in getfile()? */PUBLIC BOOL using_proxy = NO; /* are we using a proxy gateway? *//*** To generate other things, play with these:*/PUBLIC HTFormat HTOutputFormat = NULL;PUBLIC HTStream* HTOutputStream = NULL; /* For non-interactive, set this */PRIVATE HTList * protocols = NULL; /* List of registered protocol descriptors */PUBLIC char *use_this_url_instead = NULL;PRIVATE int pushed_assume_LYhndl = -1; /* see LYUC* functions below - kw */PRIVATE char * pushed_assume_MIMEname = NULL;#ifdef LY_FIND_LEAKSPRIVATE void free_protocols NOARGS{ HTList_delete(protocols); protocols = NULL; FREE(pushed_assume_MIMEname); /* shouldn't happen, just in case - kw */}#endif /* LY_FIND_LEAKS *//* Register a Protocol. HTRegisterProtocol()** --------------------*/PUBLIC BOOL HTRegisterProtocol ARGS1( HTProtocol *, protocol){ if (!protocols) { protocols = HTList_new();#ifdef LY_FIND_LEAKS atexit(free_protocols);#endif } HTList_addObject(protocols, protocol); return YES;}/* Register all known protocols. HTAccessInit()** -----------------------------**** Add to or subtract from this list if you add or remove protocol** modules. This routine is called the first time the protocol list** is needed, unless any protocols are already registered, in which** case it is not called. Therefore the application can override** this list.**** Compiling with NO_INIT prevents all known protocols from being** forced in at link time.*/#ifndef NO_INIT#ifdef GLOBALREF_IS_MACROextern GLOBALREF (HTProtocol, HTTP);extern GLOBALREF (HTProtocol, HTTPS);extern GLOBALREF (HTProtocol, HTFile);extern GLOBALREF (HTProtocol, HTTelnet);extern GLOBALREF (HTProtocol, HTTn3270);extern GLOBALREF (HTProtocol, HTRlogin);#ifndef DECNET#ifndef DISABLE_FTPextern GLOBALREF (HTProtocol, HTFTP);#endif /* DISABLE_FTP */#ifndef DISABLE_NEWSextern GLOBALREF (HTProtocol, HTNews);extern GLOBALREF (HTProtocol, HTNNTP);extern GLOBALREF (HTProtocol, HTNewsPost);extern GLOBALREF (HTProtocol, HTNewsReply);extern GLOBALREF (HTProtocol, HTSNews);extern GLOBALREF (HTProtocol, HTSNewsPost);extern GLOBALREF (HTProtocol, HTSNewsReply);#endif /* not DISABLE_NEWS */#ifndef DISABLE_GOPHERextern GLOBALREF (HTProtocol, HTGopher);extern GLOBALREF (HTProtocol, HTCSO);#endif /* not DISABLE_GOPHER */#ifndef DISABLE_FINGERextern GLOBALREF (HTProtocol, HTFinger);#endif /* not DISABLE_FINGER */#ifdef DIRECT_WAISextern GLOBALREF (HTProtocol, HTWAIS);#endif /* DIRECT_WAIS */#endif /* !DECNET */#elseGLOBALREF HTProtocol HTTP, HTTPS, HTFile, HTTelnet, HTTn3270, HTRlogin;#ifndef DECNET#ifndef DISABLE_FTPGLOBALREF HTProtocol HTFTP;#endif /* DISABLE_FTP */#ifndef DISABLE_NEWSGLOBALREF HTProtocol HTNews, HTNNTP, HTNewsPost, HTNewsReply;GLOBALREF HTProtocol HTSNews, HTSNewsPost, HTSNewsReply;#endif /* not DISABLE_NEWS */#ifndef DISABLE_GOPHERGLOBALREF HTProtocol HTGopher, HTCSO;#endif /* not DISABLE_GOPHER */#ifndef DISABLE_FINGERGLOBALREF HTProtocol HTFinger;#endif /* not DISABLE_FINGER */#ifdef DIRECT_WAISGLOBALREF HTProtocol HTWAIS;#endif /* DIRECT_WAIS */#endif /* !DECNET */#endif /* GLOBALREF_IS_MACRO */PRIVATE void HTAccessInit NOARGS /* Call me once */{ HTRegisterProtocol(&HTTP); HTRegisterProtocol(&HTTPS); HTRegisterProtocol(&HTFile); HTRegisterProtocol(&HTTelnet); HTRegisterProtocol(&HTTn3270); HTRegisterProtocol(&HTRlogin);#ifndef DECNET#ifndef DISABLE_FTP HTRegisterProtocol(&HTFTP);#endif /* DISABLE_FTP */#ifndef DISABLE_NEWS HTRegisterProtocol(&HTNews); HTRegisterProtocol(&HTNNTP); HTRegisterProtocol(&HTNewsPost); HTRegisterProtocol(&HTNewsReply); HTRegisterProtocol(&HTSNews); HTRegisterProtocol(&HTSNewsPost); HTRegisterProtocol(&HTSNewsReply);#endif /* not DISABLE_NEWS */#ifndef DISABLE_GOPHER HTRegisterProtocol(&HTGopher); HTRegisterProtocol(&HTCSO);#endif /* not DISABLE_GOPHER */#ifndef DISABLE_FINGER HTRegisterProtocol(&HTFinger);#endif /* not DISABLE_FINGER */#ifdef DIRECT_WAIS HTRegisterProtocol(&HTWAIS);#endif /* DIRECT_WAIS */#endif /* !DECNET */ LYRegisterLynxProtocols();}#endif /* !NO_INIT *//* Check for proxy override. override_proxy()** -------------------------**** Check the no_proxy environment variable to get the list** of hosts for which proxy server is not consulted.**** no_proxy is a comma- or space-separated list of machine** or domain names, with optional :port part. If no :port** part is present, it applies to all ports on that domain.**** Example:** no_proxy="cern.ch,some.domain:8001"**** Use "*" to override all proxy service:** no_proxy="*"*/PUBLIC BOOL override_proxy ARGS1( CONST char *, addr){ CONST char * no_proxy = getenv("no_proxy"); char * p = NULL; char * at = NULL; char * host = NULL; char * Host = NULL; char * acc_method = NULL; int port = 0; int h_len = 0; /* * Check for global override. */ if (no_proxy) { if (!strcmp(no_proxy, "*")) return YES; } /* * Never proxy file:// URLs if they are on the local host. * HTLoadFile() will not attempt ftp for those if direct * access fails. We'll check that first, in case no_proxy * hasn't been defined. - FM */ if (!addr) return NO; if (!(host = HTParse(addr, "", PARSE_HOST))) return NO; if (!*host) { FREE(host); return NO; } Host = (((at = strchr(host, '@')) != NULL) ? (at+1) : host);#ifdef VMS#define CompareHostname(a,b) strcasecomp(a, b)#else#define CompareHostname(a,b) strcmp(a, b)#endif /* VMS */ if ((acc_method = HTParse(addr, "", PARSE_ACCESS))) { if (!strcmp("file", acc_method) && (!strcmp(Host, "localhost") || !CompareHostname(Host, HTHostName()))) { FREE(host); FREE(acc_method); return YES; } FREE(acc_method); } if (!no_proxy) { FREE(host); return NO; } if (NULL != (p = strrchr(Host, ':'))) { /* Port specified */ *p++ = 0; /* Chop off port */ port = atoi(p); } else { /* Use default port */ acc_method = HTParse(addr, "", PARSE_ACCESS); if (acc_method != NULL) { if (!strcmp(acc_method, "http")) port = 80; else if (!strcmp(acc_method, "https")) port = 443; else if (!strcmp(acc_method, "ftp")) port = 21;#ifndef DISABLE_GOPHER else if (!strcmp(acc_method, "gopher")) port = 70;#endif else if (!strcmp(acc_method, "cso")) port = 105;#ifndef DISABLE_NEWS else if (!strcmp(acc_method, "news")) port = 119; else if (!strcmp(acc_method, "nntp")) port = 119; else if (!strcmp(acc_method, "newspost")) port = 119; else if (!strcmp(acc_method, "newsreply")) port = 119; else if (!strcmp(acc_method, "snews")) port = 563; else if (!strcmp(acc_method, "snewspost")) port = 563; else if (!strcmp(acc_method, "snewsreply")) port = 563;#endif else if (!strcmp(acc_method, "wais")) port = 210;#ifndef DISABLE_FINGER else if (!strcmp(acc_method, "finger")) port = 79;#endif else if (!strcmp(acc_method, "telnet")) port = 23; else if (!strcmp(acc_method, "tn3270")) port = 23; else if (!strcmp(acc_method, "rlogin")) port = 513; FREE(acc_method); } } if (!port) port = 80; /* Default */ h_len = strlen(Host); while (*no_proxy) { CONST char * end; CONST char * colon = NULL; int templ_port = 0; int t_len; while (*no_proxy && (WHITE(*no_proxy) || *no_proxy == ',')) no_proxy++; /* Skip whitespace and separators */ end = no_proxy; while (*end && !WHITE(*end) && *end != ',') { /* Find separator */ if (*end == ':') colon = end; /* Port number given */ end++; } if (colon) { templ_port = atoi(colon+1); t_len = colon - no_proxy; } else { t_len = end - no_proxy; } if ((!templ_port || templ_port == port) && (t_len > 0 && t_len <= h_len && !strncasecomp(Host + h_len - t_len, no_proxy, t_len))) { FREE(host); return YES; }#ifdef CJK_EX /* ASATAKU PROXY HACK */ if ((!templ_port || templ_port == port) && (t_len > 0 && t_len <= h_len && isdigit(UCH(*no_proxy)) && !strncmp(host, no_proxy, t_len))) { FREE(host); return YES; }#endif /* ASATAKU PROXY HACK */ if (*end) no_proxy = (end + 1); else break; } FREE(host); return NO;}/* Find physical name and access protocol get_physical()** --------------------------------------**** On entry,** addr must point to the fully qualified hypertext reference.** anchor a parent anchor with whose address is addr**** On exit,** returns HT_NO_ACCESS Error has occurred.** HT_OK Success*/PRIVATE int get_physical ARGS2( CONST char *, addr, HTParentAnchor *, anchor){ char * acc_method = NULL; /* Name of access method */ char * physical = NULL; char * Server_addr = NULL; BOOL override_flag = NO; /* ** Make sure the using_proxy variable is FALSE. */ using_proxy = NO;#ifndef NO_RULES physical = HTTranslate(addr); if (!physical) { if (redirecting_url) { return HT_REDIRECTING; } return HT_FORBIDDEN; } if (anchor->isISMAPScript == TRUE) { StrAllocCat(physical, "?0,0"); CTRACE((tfp, "HTAccess: Appending '?0,0' coordinate pair.\n")); } if (!strncmp(physical, "Proxied=", 8)) { HTAnchor_setPhysical(anchor, physical + 8); using_proxy = YES; } else if (!strncmp(physical, "NoProxy=", 8)) { HTAnchor_setPhysical(anchor, physical + 8); override_flag = YES; } else { HTAnchor_setPhysical(anchor, physical); } FREE(physical); /* free our copy */#else if (anchor->isISMAPScript == TRUE) { StrAllocCopy(physical, addr); StrAllocCat(physical, "?0,0"); CTRACE((tfp, "HTAccess: Appending '?0,0' coordinate pair.\n")); HTAnchor_setPhysical(anchor, physical); FREE(physical); /* free our copy */ } else { HTAnchor_setPhysical(anchor, addr); }#endif /* NO_RULES */ acc_method = HTParse(HTAnchor_physical(anchor), "file:", PARSE_ACCESS); /* ** Check whether gateway access has been set up for this. ** ** This function can be replaced by the rule system above. ** ** If the rule system has already determined that we should ** use a proxy, or that we shouldn't, ignore proxy-related ** settings, don't use no_proxy either. */#define USE_GATEWAYS#ifdef USE_GATEWAYS if (!override_flag && !using_proxy) { /* else ignore no_proxy env var */ if (!strcasecomp(acc_method, "news")) { /* ** News is different, so we need to check the name of the server, ** as well as the default port for selective exclusions. */ char *host = NULL; if ((host = HTParse(addr, "", PARSE_HOST))) { if (strchr(host, ':') == NULL) { StrAllocCopy(Server_addr, "news://"); StrAllocCat(Server_addr, host); StrAllocCat(Server_addr, ":119/"); } FREE(host); } else if (getenv("NNTPSERVER") != NULL) { StrAllocCopy(Server_addr, "news://"); StrAllocCat(Server_addr, (char *)getenv("NNTPSERVER")); StrAllocCat(Server_addr, ":119/"); } } else if (!strcasecomp(acc_method, "wais")) { /* ** Wais also needs checking of the default port ** for selective exclusions.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -