📄 htparse.c
字号:
char *orig=dot, *dest=dot+1; while((*orig++ = *dest++)); if (port) port--; path--; } } /* Chop off port if `:', `:80' (http), `:70' (gopher), or `:21' (ftp) */ if (port) { if (!*(port+1) || *(port+1)=='/') { if (!newname) { char *orig=port, *dest=port+1; while((*orig++ = *dest++)); } } else if ((!strncmp(access, "http", 4) && (*(port+1)=='8'&&*(port+2)=='0'&&(*(port+3)=='/'||!*(port+3)))) || (!strncmp(access, "gopher", 6) && (*(port+1)=='7'&&*(port+2)=='0'&&(*(port+3)=='/'||!*(port+3)))) || (!strncmp(access, "ftp", 3) && (*(port+1)=='2'&&*(port+2)=='1'&&(*(port+3)=='/'||!*(port+3))))) { if (!newname) { char *orig=port, *dest=port+3; while((*orig++ = *dest++)); path -= 3; /* Update path position, Henry Minsky */ } } else if (newname) strncat(newname, port, (int) (path-port)); } if (newname) { char *newpath = newname+strlen(newname); strcat(newname, path); path = newpath; HT_FREE(*filename); /* Free old copy */ *filename = newname; } return path;}/*** Search the URL and determine whether it is a relative or absolute URL.** We check to see if there is a ":" before any "/", "?", and "#". If this** is the case then we say it is absolute. Otherwise it is relative.*/PUBLIC BOOL HTURL_isAbsolute (const char * url){ if (url) { const char * ptr = url; while (*ptr) { if (*ptr == ':') return YES; if (*ptr == '/' || *ptr == '?' || *ptr == '#') break; ptr ++; } } return NO;}/* Simplify a URI// --------------// A URI is allowed to contain the seqeunce xxx/../ which may be// replaced by "" , and the seqeunce "/./" which may be replaced by "/".// Simplification helps us recognize duplicate URIs. //// Thus, /etc/junk/../fred becomes /etc/fred// /etc/junk/./fred becomes /etc/junk/fred//// but we should NOT change// http://fred.xxx.edu/../..//// or ../../albert.html//// In order to avoid empty URLs the following URLs become://// /fred/.. becomes /fred/..// /fred/././.. becomes /fred/..// /fred/.././junk/.././ becomes /fred/..//// If more than one set of `://' is found (several proxies in cascade) then// only the part after the last `://' is simplified.//// Returns: A string which might be the old one or a new one.*/PUBLIC char *HTSimplify (char ** url){ char *path; char *p; if (!url || !*url) { HTTRACE(URI_TRACE, "HTSimplify.. Nothing done\n"); return *url; } HTTRACE(URI_TRACE, "HTSimplify.. `%s\' " _ *url); /* Find any scheme name */ if ((path = strstr(*url, "://")) != NULL) { /* Find host name */ char *newptr; char *access = *url; while (access<path && (*access=TOLOWER(*access))) access++; path += 3; while ((newptr = strstr(path, "://")) != NULL) /* For proxies */ path = newptr+3; path = HTCanon(url, path); /* We have a host name */ } else if ((path = strstr(*url, ":/")) != NULL) { path += 2; } else path = *url; if (*path == '/' && *(path+1)=='/') { /* Some URLs start //<foo> */ path += 1; } else if (!strncmp(path, "news:", 5)) { char *ptr = strchr(path+5, '@'); if (!ptr) ptr = path+5; while (*ptr) { /* Make group or host lower case */ *ptr = TOLOWER(*ptr); ptr++; } HTTRACE(URI_TRACE, "into\n............ `%s'\n" _ *url); return *url; /* Doesn't need to do any more */ } if ((p = path)) { char *end; if (!((end = strchr(path, ';')) || (end = strchr(path, '?')) || (end = strchr(path, '#')))) end = path+strlen(path); /* Parse string second time to simplify */ p = path; while(p<end) { if (*p=='/') { if (p>*url && *(p+1)=='.' && (*(p+2)=='/' || !*(p+2))) { char *orig = p+1; char *dest = (*(p+2)!='/') ? p+2 : p+3; while ((*orig++ = *dest++)); /* Remove a slash and a dot */ end = orig-1; } else if (*(p+1)=='.' && *(p+2)=='.' && (*(p+3)=='/' || !*(p+3))) { char *q = p; while (q>path && *--q!='/'); /* prev slash */ if (strncmp(q, "/../", 4)) { char *orig = q+1; char *dest = (*(p+3)!='/') ? p+3 : p+4; while ((*orig++ = *dest++)); /* Remove /xxx/.. */ end = orig-1; p = q; /* Start again with prev slash */ } else p++; } else if (*(p+1)=='/') { while (*(p+1)=='/') { char *orig=p, *dest=p+1; while ((*orig++ = *dest++)); /* Remove multiple /'s */ end = orig-1; } } else p++; } else p++; } } /* ** Check for host/../.. kind of things */ while (*path=='/' && *(path+1)=='.' && *(path+2)=='.' && (!*(path+3) || *(path+3)=='/')) { char * orig = path; char * dest = path+3; while ((*orig++ = *dest++)); } HTTRACE(URI_TRACE, "into\n............ `%s'\n" _ *url); return *url;}/* Make Relative Name** ------------------**** This function creates and returns a string which gives an expression of** one address as related to another. Where there is no relation, an absolute** address is retured.**** On entry,** Both names must be absolute, fully qualified names of nodes** (no fragment bits)**** On exit,** The return result points to a newly allocated name which, if** parsed by HTParse relative to relatedName, will yield aName.** The caller is responsible for freeing the resulting name later.***/PUBLIC char * HTRelative (const char * aName, const char * relatedName){ char * result = 0; const char *p = aName; const char *q = relatedName; const char * after_access = NULL; const char * path = 0; const char * last_slash = 0; int slashes = 0; for(;*p; p++, q++) { /* Find extent of match */ if (*p!=*q) break; if (*p==':') if (!after_access) after_access = p+1; if (*p=='/') { last_slash = p; slashes++; if (slashes==3) path=p; } } /* q, p point to the first non-matching character or zero */ if (!after_access) { /* Different access */ StrAllocCopy(result, aName); } else if (slashes<3){ /* Different nodes */ StrAllocCopy(result, after_access); } else { /* Some path in common */ int levels= 0; for(; *q && *q!='#' && *q!=';' && *q!='?'; q++) if (*q=='/') levels++; if ((result = (char *) HT_MALLOC(3*levels + strlen(last_slash) + 4)) == NULL) HT_OUTOFMEM("HTRelative"); *result = '\0'; if (!levels) strcat(result, "./"); for(;levels; levels--)strcat(result, "../"); strcat(result, last_slash+1); if (!*result) strcat(result, "./"); } HTTRACE(URI_TRACE, "HTRelative.. `%s' expressed relative to `%s' is `%s'\n" _ aName _ relatedName _ result);#if 0 { char * absstr = HTParse(result, relatedName, PARSE_ALL); HTSimplify(&absstr); HTTRACE(URI_TRACE, "HTRelative.. `%s' made absolute based on `%s' is `%s'\n" _ result _ relatedName _ absstr); if (strcmp(absstr, aName) != 0) HTTRACE(URI_TRACE, "THEY DIFFER!!!\n"); HT_FREE(absstr); }#endif return result;}/* HTCleanTelnetString() * Make sure that the given string doesn't contain characters that * could cause security holes, such as newlines in ftp, gopher, * news or telnet URLs; more specifically: allows everything between * ASCII 20-7E, and also A0-FE, inclusive. Also TAB ('\t') allowed! * * On entry, * str the string that is *modified* if necessary. The * string will be truncated at the first illegal * character that is encountered. * On exit, * returns YES, if the string was modified. * NO, otherwise. */PUBLIC BOOL HTCleanTelnetString (char * str){ char * cur = str; if (!str) return NO; while (*cur) { int a = TOASCII((unsigned char) *cur); if (a != 0x9 && (a < 0x20 || (a > 0x7E && a < 0xA0) || a > 0xFE)) { HTTRACE(URI_TRACE, "Illegal..... character in URL: \"%s\"\n" _ str); *cur = 0; HTTRACE(URI_TRACE, "Truncated... \"%s\"\n" _ str); return YES; } cur++; } return NO;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -