📄 htaccess.c
字号:
*/ char *host = NULL; if ((host = HTParse(addr, "", PARSE_HOST))) { if (!(strchr(host, ':'))) { StrAllocCopy(Server_addr, "wais://"); StrAllocCat(Server_addr, host); StrAllocCat(Server_addr, ":210/"); } FREE(host); } else StrAllocCopy(Server_addr, addr); } else { StrAllocCopy(Server_addr, addr); } override_flag = override_proxy(Server_addr); } if (!override_flag && !using_proxy) { char * gateway_parameter = NULL, *gateway, *proxy; /* ** Search for gateways. */ HTSprintf0(&gateway_parameter, "WWW_%s_GATEWAY", acc_method); gateway = getenv(gateway_parameter); /* coerce for decstation */ /* ** Search for proxy servers. */ if (!strcmp(acc_method, "file")) /* ** If we got to here, a file URL is for ftp on a remote host. - FM */ strcpy(gateway_parameter, "ftp_proxy"); else sprintf(gateway_parameter, "%s_proxy", acc_method); proxy = getenv(gateway_parameter); FREE(gateway_parameter); if (gateway) CTRACE((tfp, "Gateway found: %s\n", gateway)); if (proxy) CTRACE((tfp, "proxy server found: %s\n", proxy)); /* ** Proxy servers have precedence over gateway servers. */ if (proxy) { char * gatewayed = NULL; StrAllocCopy(gatewayed,proxy); if (!strncmp(gatewayed, "http", 4)) { char *cp = strrchr(gatewayed, '/'); /* Append a slash to the proxy specification if it doesn't * end in one but otherwise looks normal (starts with "http", * has no '/' other than ones before the hostname). - kw */ if (cp && (cp - gatewayed) <= 7) LYAddHtmlSep(&gatewayed); } /* ** Ensure that the proxy server uses ftp for file URLs. - FM */ if (!strncmp(addr, "file", 4)) { StrAllocCat(gatewayed, "ftp"); StrAllocCat(gatewayed, (addr + 4)); } else StrAllocCat(gatewayed, addr); using_proxy = YES; if (anchor->isISMAPScript == TRUE) StrAllocCat(gatewayed, "?0,0"); HTAnchor_setPhysical(anchor, gatewayed); FREE(gatewayed); FREE(acc_method); acc_method = HTParse(HTAnchor_physical(anchor), "http:", PARSE_ACCESS); } else if (gateway) { char * path = HTParse(addr, "", PARSE_HOST + PARSE_PATH + PARSE_PUNCTUATION); /* Chop leading / off to make host into part of path */ char * gatewayed = HTParse(path+1, gateway, PARSE_ALL); FREE(path); HTAnchor_setPhysical(anchor, gatewayed); FREE(gatewayed); FREE(acc_method); acc_method = HTParse(HTAnchor_physical(anchor), "http:", PARSE_ACCESS); } } FREE(Server_addr);#endif /* use gateways */ /* ** Search registered protocols to find suitable one. */ { int i, n;#ifndef NO_INIT if (!protocols) HTAccessInit();#endif n = HTList_count(protocols); for (i = 0; i < n; i++) { HTProtocol *p = (HTProtocol *)HTList_objectAt(protocols, i); if (!strcmp(p->name, acc_method)) { HTAnchor_setProtocol(anchor, p); FREE(acc_method); return (HT_OK); } } } FREE(acc_method); return HT_NO_ACCESS;}/* * Temporarily set the int UCLYhndl_for_unspec and string * UCLYhndl_for_unspec used for charset "assuming" to the values * implied by a HTParentAnchor's UCStages, after saving the current * values for later restoration. - kw * @@@ These functions may not really belong here, but where else? * I want the "pop" to occur as soon as possible after loading * has finished. - kw @@@ */extern char*UCAssume_MIMEcharset;PUBLIC void LYUCPushAssumed ARGS1( HTParentAnchor *, anchor){ int anchor_LYhndl = -1; LYUCcharset * anchor_UCI = NULL; if (anchor) { anchor_LYhndl = HTAnchor_getUCLYhndl(anchor, UCT_STAGE_PARSER); if (anchor_LYhndl >= 0) anchor_UCI = HTAnchor_getUCInfoStage(anchor, UCT_STAGE_PARSER); if (anchor_UCI && anchor_UCI->MIMEname) { pushed_assume_MIMEname = UCAssume_MIMEcharset; UCAssume_MIMEcharset = NULL; if (HTCJK == JAPANESE) StrAllocCopy(UCAssume_MIMEcharset, pushed_assume_MIMEname); else StrAllocCopy(UCAssume_MIMEcharset, anchor_UCI->MIMEname); pushed_assume_LYhndl = anchor_LYhndl; /* some diagnostics */ if (UCLYhndl_for_unspec != anchor_LYhndl) CTRACE((tfp, "LYUCPushAssumed: UCLYhndl_for_unspec changed %d -> %d\n", UCLYhndl_for_unspec, anchor_LYhndl)); UCLYhndl_for_unspec = anchor_LYhndl; return; } } pushed_assume_LYhndl = -1; FREE(pushed_assume_MIMEname);}/* * Restore the int UCLYhndl_for_unspec and string * UCLYhndl_for_unspec used for charset "assuming" from the values * saved by LYUCPushAssumed, if any. - kw */PUBLIC int LYUCPopAssumed NOARGS{ if (pushed_assume_LYhndl >= 0) { /* some diagnostics */ if (UCLYhndl_for_unspec != pushed_assume_LYhndl) CTRACE((tfp, "LYUCPopAssumed: UCLYhndl_for_unspec changed %d -> %d\n", UCLYhndl_for_unspec, pushed_assume_LYhndl)); UCLYhndl_for_unspec = pushed_assume_LYhndl; pushed_assume_LYhndl = -1; FREE(UCAssume_MIMEcharset); UCAssume_MIMEcharset = pushed_assume_MIMEname; pushed_assume_MIMEname = NULL; return UCLYhndl_for_unspec; } return -1;}/* Load a document HTLoad()** ---------------**** This is an internal routine, which has an address AND a matching** anchor. (The public routines are called with one OR the other.)**** On entry,** addr must point to the fully qualified hypertext reference.** anchor a parent anchor with whose address is addr**** On exit,** returns <0 Error has occurred.** HT_LOADED Success** HT_NO_DATA Success, but no document loaded.** (telnet session started etc)*/PRIVATE int HTLoad ARGS4( CONST char *, addr, HTParentAnchor *, anchor, HTFormat, format_out, HTStream *, sink){ HTProtocol *p; int status = get_physical(addr, anchor); if (status == HT_FORBIDDEN) { /* prevent crash if telnet or similar was forbidden by rule. - kw */ LYFixCursesOn("show alert:"); return HTLoadError(sink, 500, gettext("Access forbidden by rule")); } else if (status == HT_REDIRECTING) { return status; /* fake redirection by rule, to redirecting_url */ } if (status < 0) return status; /* Can't resolve or forbidden */ /* prevent crash if telnet or similar mapped or proxied by rule. - kw */ LYFixCursesOnForAccess(addr, HTAnchor_physical(anchor)); p = (HTProtocol *)HTAnchor_protocol(anchor); anchor->underway = TRUE; /* Hack to deal with caching */ status= (*(p->load))(HTAnchor_physical(anchor), anchor, format_out, sink); anchor->underway = FALSE; LYUCPopAssumed(); return status;}/* Get a save stream for a document HTSaveStream()** --------------------------------*/PUBLIC HTStream *HTSaveStream ARGS1( HTParentAnchor *, anchor){ HTProtocol *p = (HTProtocol *)HTAnchor_protocol(anchor); if (!p) return NULL; return (*p->saveStream)(anchor);}PUBLIC int redirection_attempts = 0; /* counter in HTLoadDocument *//* Load a document - with logging etc HTLoadDocument()** ----------------------------------**** - Checks or documents already loaded** - Logs the access** - Allows stdin filter option** - Trace ouput and error messages**** On Entry,** anchor is the node_anchor for the document** full_address The address of the document to be accessed.** filter if YES, treat stdin as HTML**** On Exit,** returns YES Success in opening document** NO Failure*/PRIVATE BOOL HTLoadDocument ARGS4( CONST char *, full_address, HTParentAnchor *, anchor, HTFormat, format_out, HTStream*, sink){ int status; HText * text; CONST char * address_to_load = full_address; char *cp; BOOL ForcingNoCache = LYforce_no_cache; CTRACE((tfp, "HTAccess: loading document %s\n", address_to_load)); /* ** Free use_this_url_instead and reset permanent_redirection ** if not done elsewhere. - FM */ FREE(use_this_url_instead); permanent_redirection = FALSE; /* ** Make sure some yoyo doesn't send us 'round in circles ** with redirecting URLs that point back to themselves. ** We'll set the original Lynx limit of 10 redirections ** per requested URL from a user, because the HTTP/1.1 ** will no longer specify a restriction to 5, but will ** leave it up to the browser's discretion, in deference ** to Microsoft. - FM */ if (redirection_attempts > 10) { redirection_attempts = 0; HTAlert(TOO_MANY_REDIRECTIONS); return NO; } /* * If this is marked as an internal link but we don't have the * document loaded any more, and we haven't explicitly flagged * that we want to reload with LYforce_no_cache, then something * has disappeared from the cache when we expected it to be still * there. The user probably doesn't expect a new network access. * So if we have POST data and safe is not set in the anchor, * ask for confirmation, and fail if not granted. The exception * are LYNXIMGMAP documents, for which we defer to LYLoadIMGmap * for prompting if necessary. - kw */ if (LYinternal_flag && !LYforce_no_cache && anchor->post_data && !anchor->safe && (text = (HText *)HTAnchor_document(anchor)) == NULL && strncmp(full_address, "LYNXIMGMAP:", 11) && HTConfirm(gettext("Document with POST content not found in cache. Resubmit?")) != TRUE) { return NO; } /* ** If we don't have POST content, check whether this is a previous ** redirecting URL, and keep re-checking until we get to the final ** destination or redirection limit. If we do have POST content, ** we didn't allow permanent redirection, and an interactive user ** will be deciding whether to keep redirecting. - FM */ if (!anchor->post_data) { while ((cp = HTAnchor_physical(anchor)) != NULL && !strncmp(cp, "Location=", 9)) { DocAddress NewDoc; CTRACE((tfp, "HTAccess: '%s' is a redirection URL.\n", anchor->address)); CTRACE((tfp, "HTAccess: Redirecting to '%s'\n", cp+9)); /* ** Don't exceed the redirection_attempts limit. - FM */ if (++redirection_attempts > 10) { HTAlert(TOO_MANY_REDIRECTIONS); redirection_attempts = 0; FREE(use_this_url_instead); return NO; } /* ** Set up the redirection. - FM **/ StrAllocCopy(use_this_url_instead, cp+9); NewDoc.address = use_this_url_instead; NewDoc.post_data = NULL; NewDoc.post_content_type = NULL; NewDoc.bookmark = anchor->bookmark; NewDoc.isHEAD = anchor->isHEAD; NewDoc.safe = anchor->safe; anchor = HTAnchor_parent(HTAnchor_findAddress(&NewDoc)); } } /* ** If we had previous redirection, go back and check out ** that the URL under the current restrictions. - FM */ if (use_this_url_instead) { FREE(redirecting_url); return(NO); } /* ** See if we can use an already loaded document. */ if (!LYforce_no_cache && (text = (HText *)HTAnchor_document(anchor))) { /* ** We have a cached rendition of the target document. ** Check if it's OK to re-use it. We consider it OK if: ** (1) the anchor does not have the no_cache element set, or ** (2) we've overridden it, e.g., because we are acting on ** a PREV_DOC command or a link in the History Page and ** it's not a reply from a POST with the LYresubmit_posts ** flag set, or ** (3) we are repositioning within the currently loaded document ** based on the target anchor's address (URL_Reference). * * If DONT_TRACK_INTERNAL_LINKS is defined, HText_AreDifferent() * is used to determine whether (3) applies. If the target address * differs from that of the current document only by a fragment * and the target address has an appended fragment, repositioning * without reloading is always assumed. * Note that HText_AreDifferent() currently always returns TRUE * if the target has a LYNXIMGMAP URL, so that an internally * generated pseudo-document will normally not be re-used unless * condition (2) applies. (Condition (1) cannot apply since in * LYMap.c, no_cache is always set in the anchor object). This * doesn't guarantee that the resource from which the MAP element * is taken will be read again (reloaded) when the list of links * for a client-side image map is regenerated, when in some cases * it should (e.g., user requested RELOAD, or HTTP response with * no-cache header and we are not overriding). * * If DONT_TRACK_INTERNAL_LINKS is undefined, a target address that * points to the same URL as the current document may still result in * reloading, depending on whether the original URL-Reference * was given as an internal link in the context of the previously * loaded document. HText_AreDifferent() is not used here for * testing whether we are just repositioning. For an internal * link, the potential callers of this function from mainloop() * down will either avoid making the call (and do the repositioning * differently) or set LYinternal_flag (or LYoverride_no_cache). * Note that (a) LYNXIMGMAP pseudo-documents and (b) The "List Page" * document are treated logically as being part of the document on * which they are based, for the purpose of whether to treat a link * as internal, but the logic for this (by setting LYinternal_flag * as necessary) is implemented elsewhere. There is a specific * test for LYNXIMGMAP here so that the generated pseudo-document * will not be re-used unless LYoverride_no_cache is set. The same * caveat as above applies w.r.t. reloading of the underlying * resource. * ** We also should be checking other aspects of cache ** regulation (e.g., based on an If-Modified-Since check, ** etc.) but the code for doing those other things isn't ** available yet. */#ifdef DONT_TRACK_INTERNAL_LINKS if (LYoverride_no_cache || !HText_hasNoCacheSet(text) || !HText_AreDifferent(anchor, full_address))#else if (LYoverride_no_cache || ((LYinternal_flag || !HText_hasNoCacheSet(text)) && strncmp(full_address, "LYNXIMGMAP:", 11)))#endif /* TRACK_INTERNAL_LINKS */ { CTRACE((tfp, "HTAccess: Document already in memory.\n")); HText_select(text);#ifdef DIRED_SUPPORT if (HTAnchor_format(anchor) == WWW_DIRED) lynx_edit_mode = TRUE;#endif redirection_attempts = 0; return YES; } else { ForcingNoCache = YES; CTRACE((tfp, "HTAccess: Auto-reloading document.\n")); } } /* ** Get the document from the net. If we are auto-reloading, ** the mutable anchor elements from the previous rendition ** should be freed in conjunction with loading of the new ** rendition. - FM */ LYforce_no_cache = NO; /* reset after each time through */ if (ForcingNoCache) { FREE(anchor->title); } status = HTLoad(address_to_load, anchor, format_out, sink); CTRACE((tfp, "HTAccess: status=%d\n", status)); /* ** Log the access if necessary. */ if (HTlogfile) { time_t theTime; time(&theTime); fprintf(HTlogfile, "%24.24s %s %s %s\n", ctime(&theTime), HTClientHost ? HTClientHost : "local", status < 0 ? "FAIL" : "GET", full_address); fflush(HTlogfile); /* Actually update it on disk */ CTRACE((tfp, "Log: %24.24s %s %s %s\n", ctime(&theTime), HTClientHost ? HTClientHost : "local",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -