?? htparse.c
字號:
/* HTParse.c** URI MANAGEMENT**** (c) COPYRIGHT MIT 1995.** Please first read the full copyright statement in the file COPYRIGH.** @(#) $Id: HTParse.c,v 2.80 1999/02/22 22:10:11 frystyk Exp $**** history:** May 12 94 TAB added as legal char in HTCleanTelnetString***//* Library include files */#include "wwwsys.h"#include "WWWUtil.h"#include "HTParse.h" /* Implemented here */typedef struct _HTURI { char * access; /* Now known as "scheme" */ char * host; char * absolute; char * relative; char * fragment;} HTURI;/* Scan a filename for its consituents** -----------------------------------**** On entry,** name points to a document name which may be incomplete.** On exit,** absolute or relative may be nonzero (but not both).** host, fragment and access may be nonzero if they were specified.** Any which are nonzero point to zero terminated strings.*/PRIVATE void scan (char * name, HTURI * parts){ char * p; char * after_access = name; memset(parts, '\0', sizeof(HTURI)); /* Look for fragment identifier */ if ((p = strchr(name, '#')) != NULL) { *p++ = '\0'; parts->fragment = p; } if ((p = strchr(name, ' ')) != NULL) *p++ = '\0'; for(p=name; *p; p++) { /* ** Look for any whitespace. This is very bad for pipelining as it ** makes the request invalid */ if (isspace((int) *p)) { char *orig=p, *dest=p+1; while ((*orig++ = *dest++)); p = p-1; } if (*p=='/' || *p=='#' || *p=='?') break; if (*p==':') { *p = 0; parts->access = after_access; /* Scheme has been specified *//* The combination of gcc, the "-O" flag and the HP platform is unhealthy. The following three lines is a quick & dirty fix, but is not recommended. Rather, turn off "-O". *//* after_access = p;*//* while (*after_access == 0)*//* after_access++;*/ after_access = p+1; if (0==strcasecomp("URL", parts->access)) { parts->access = NULL; /* Ignore IETF's URL: pre-prefix */ } else break; } } p = after_access; if (*p=='/'){ if (p[1]=='/') { parts->host = p+2; /* host has been specified */ *p=0; /* Terminate access */ p=strchr(parts->host,'/'); /* look for end of host name if any */ if(p) { *p=0; /* Terminate host */ parts->absolute = p+1; /* Root has been found */ } } else { parts->absolute = p+1; /* Root found but no host */ } } else { parts->relative = (*after_access) ? after_access : 0; /* zero for "" */ }}/* Parse a Name relative to another name** -------------------------------------**** This returns those parts of a name which are given (and requested)** substituting bits from the related name where necessary.**** On entry,** aName A filename given** relatedName A name relative to which aName is to be parsed. Give** it an empty string if aName is absolute.** wanted A mask for the bits which are wanted.**** On exit,** returns A pointer to a malloc'd string which MUST BE FREED*/PUBLIC char * HTParse (const char *aName, const char *relatedName, int wanted){ char * result = 0; char * return_value = 0; int len; char * name = 0; char * rel = 0; char * p; char * access; HTURI given, related; if (!aName) return NULL; if (!relatedName) /* HWL 23/8/94: dont dump due to NULL */ relatedName = ""; /* Make working copies of input strings to cut up: */ len = strlen(aName)+strlen(relatedName)+10; if ((result=(char *) HT_MALLOC(len)) == NULL) /* Lots of space: more than enough */ HT_OUTOFMEM("parse space"); StrAllocCopy(name, aName); StrAllocCopy(rel, relatedName); scan(name, &given); scan(rel, &related); result[0]=0; /* Clear string */ access = given.access ? given.access : related.access; if (wanted & PARSE_ACCESS) if (access) { strcat(result, access); if(wanted & PARSE_PUNCTUATION) strcat(result, ":"); } if (given.access && related.access) /* If different, inherit nothing. */ if (strcmp(given.access, related.access)!=0) { related.host=0; related.absolute=0; related.relative=0; related.fragment=0; } if (wanted & PARSE_HOST) if(given.host || related.host) { if(wanted & PARSE_PUNCTUATION) strcat(result, "//"); strcat(result, given.host ? given.host : related.host); } if (given.host && related.host) /* If different hosts, inherit no path. */ if (strcmp(given.host, related.host)!=0) { related.absolute=0; related.relative=0; related.fragment=0; } if (wanted & PARSE_PATH) { if(given.absolute) { /* All is given */ if(wanted & PARSE_PUNCTUATION) strcat(result, "/"); strcat(result, given.absolute); } else if(related.absolute) { /* Adopt path not name */ strcat(result, "/"); strcat(result, related.absolute); if (given.relative) { p = strchr(result, '?'); /* Search part? */ if (!p) p=result+strlen(result)-1; for (; *p!='/'; p--); /* last / */ p[1]=0; /* Remove filename */ strcat(result, given.relative); /* Add given one */#if 0 result = HTSimplify (&result);#endif } } else if(given.relative) { strcat(result, given.relative); /* what we've got */ } else if(related.relative) { strcat(result, related.relative); } else { /* No inheritance */ strcat(result, "/"); } } if (wanted & PARSE_VIEW) if(given.fragment || related.fragment) { if(given.absolute && given.fragment) { /*Fixes for relURLs...*/ if(wanted & PARSE_PUNCTUATION) strcat(result, "#"); strcat(result, given.fragment); } else if (!(given.absolute) && !(given.fragment)) { strcat(result, ""); } else { if(wanted & PARSE_PUNCTUATION) strcat(result, "#"); strcat(result, given.fragment ? given.fragment : related.fragment); } } HT_FREE(rel); HT_FREE(name); StrAllocCopy(return_value, result); HT_FREE(result); return return_value; /* exactly the right length */}/*** Canonicalizes the URL in the following manner starting from the host** pointer:**** 1) The host name is converted to lowercase** 2) Chop off port if `:80' (http), `:70' (gopher), or `:21' (ftp)**** Return: OK The position of the current path part of the URL** which might be the old one or a new one.*/PRIVATE char * HTCanon (char ** filename, char * host){ char *newname = NULL; char *port; char *strptr; char *path; char *access = host-3; while (access>*filename && *(access-1)!='/') /* Find access method */ access--; if ((path = strchr(host, '/')) == NULL) /* Find path */ path = host + strlen(host); if ((strptr = strchr(host, '@')) != NULL && strptr<path) /* UserId */ host = strptr; if ((port = strchr(host, ':')) != NULL && port>path) /* Port number */ port = NULL; strptr = host; /* Convert to lower-case */ while (strptr<path) { *strptr = TOLOWER(*strptr); strptr++; } /* Does the URL contain a full domain name? This also works for a numerical host name. The domain name is already made lower-case and without a trailing dot. */#if 0 if (((strptr = strchr(host, '.')) == NULL || strptr >= path) && strncasecomp(host, "localhost", 9)) { const char *domain = HTGetDomainName(); if (domain && *domain) { if ((newname = (char *) HT_CALLOC(1, strlen(*filename) + strlen(domain)+2)) == NULL) HT_OUTOFMEM("HTCanon"); if (port) strncpy(newname, *filename, (int) (port-*filename)); else strncpy(newname, *filename, (int) (path-*filename)); strcat(newname, "."); strcat(newname, domain); } } else /* Look for a trailing dot */#endif { char *dot = port ? port : path; if (dot > *filename && *--dot=='.') {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -