📄 uri.c
字号:
return(0); /* * failed, fallback to reg_name */ if (!IS_REG_NAME(cur)) { return(5); } NEXT(cur); while (IS_REG_NAME(cur)) NEXT(cur); if (uri != NULL) { if (uri->server != NULL) xmlFree(uri->server); uri->server = NULL; if (uri->user != NULL) xmlFree(uri->user); uri->user = NULL; if (uri->authority != NULL) xmlFree(uri->authority); uri->authority = xmlURIUnescapeString(*str, cur - *str, NULL); } *str = cur; return(0);}/** * xmlParseURIHierPart: * @uri: pointer to an URI structure * @str: pointer to the string to analyze * * Parse an URI hirarchical part * * hier_part = ( net_path | abs_path ) [ "?" query ] * abs_path = "/" path_segments * net_path = "//" authority [ abs_path ] * * Returns 0 or the error code */intxmlParseURIHierPart(xmlURIPtr uri, const char **str) { int ret; const char *cur; if (str == NULL) return(-1); cur = *str; if ((cur[0] == '/') && (cur[1] == '/')) { cur += 2; ret = xmlParseURIAuthority(uri, &cur); if (ret != 0) return(ret); if (cur[0] == '/') { cur++; ret = xmlParseURIPathSegments(uri, &cur, 1); } } else if (cur[0] == '/') { cur++; ret = xmlParseURIPathSegments(uri, &cur, 1); } else { return(4); } if (ret != 0) return(ret); if (*cur == '?') { cur++; ret = xmlParseURIQuery(uri, &cur); if (ret != 0) return(ret); } *str = cur; return(0);}/** * xmlParseAbsoluteURI: * @uri: pointer to an URI structure * @str: pointer to the string to analyze * * Parse an URI reference string and fills in the appropriate fields * of the @uri structure * * absoluteURI = scheme ":" ( hier_part | opaque_part ) * * Returns 0 or the error code */intxmlParseAbsoluteURI(xmlURIPtr uri, const char **str) { int ret; if (str == NULL) return(-1); ret = xmlParseURIScheme(uri, str); if (ret != 0) return(ret); if (**str != ':') return(1); (*str)++; if (**str == '/') return(xmlParseURIHierPart(uri, str)); return(xmlParseURIOpaquePart(uri, str));}/** * xmlParseRelativeURI: * @uri: pointer to an URI structure * @str: pointer to the string to analyze * * Parse an relative URI string and fills in the appropriate fields * of the @uri structure * * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] * abs_path = "/" path_segments * net_path = "//" authority [ abs_path ] * rel_path = rel_segment [ abs_path ] * * Returns 0 or the error code */intxmlParseRelativeURI(xmlURIPtr uri, const char **str) { int ret = 0; const char *cur; if (str == NULL) return(-1); cur = *str; if ((cur[0] == '/') && (cur[1] == '/')) { cur += 2; ret = xmlParseURIAuthority(uri, &cur); if (ret != 0) return(ret); if (cur[0] == '/') { cur++; ret = xmlParseURIPathSegments(uri, &cur, 1); } } else if (cur[0] == '/') { cur++; ret = xmlParseURIPathSegments(uri, &cur, 1); } else { ret = xmlParseURIRelSegment(uri, &cur); if (ret != 0) return(ret); if (cur[0] == '/') { cur++; ret = xmlParseURIPathSegments(uri, &cur, 1); } } if (ret != 0) return(ret); if (*cur == '?') { cur++; ret = xmlParseURIQuery(uri, &cur); if (ret != 0) return(ret); } *str = cur; return(ret);}/** * xmlParseURIReference: * @uri: pointer to an URI structure * @str: the string to analyze * * Parse an URI reference string and fills in the appropriate fields * of the @uri structure * * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] * * Returns 0 or the error code */intxmlParseURIReference(xmlURIPtr uri, const char *str) { int ret; const char *tmp = str; if (str == NULL) return(-1); xmlCleanURI(uri); /* * Try first to parse aboslute refs, then fallback to relative if * it fails. */ ret = xmlParseAbsoluteURI(uri, &str); if (ret != 0) { xmlCleanURI(uri); str = tmp; ret = xmlParseRelativeURI(uri, &str); } if (ret != 0) { xmlCleanURI(uri); return(ret); } if (*str == '#') { str++; ret = xmlParseURIFragment(uri, &str); if (ret != 0) return(ret); } if (*str != 0) { xmlCleanURI(uri); return(1); } return(0);}/** * xmlNormalizeURIPath: * @path: pointer to the path string * * applies the 5 normalization steps to a path string * Normalization occurs directly on the string, no new allocation is done * * Returns 0 or an error code */intxmlNormalizeURIPath(char *path) { int cur, out; if (path == NULL) return(-1); cur = 0; out = 0; while ((path[cur] != 0) && (path[cur] != '/')) cur++; if (path[cur] == 0) return(0); /* we are positionned at the beginning of the first segment */ cur++; out = cur; /* * Analyze each segment in sequence. */ while (path[cur] != 0) { /* * c) All occurrences of "./", where "." is a complete path segment, * are removed from the buffer string. */ if ((path[cur] == '.') && (path[cur + 1] == '/')) { cur += 2; continue; } /* * d) If the buffer string ends with "." as a complete path segment, * that "." is removed. */ if ((path[cur] == '.') && (path[cur + 1] == 0)) { path[out] = 0; break; } /* read the segment */ while ((path[cur] != 0) && (path[cur] != '/')) { path[out++] = path[cur++]; } path[out++] = path[cur]; if (path[cur] != 0) { cur++; } } cur = 0; out = 0; while ((path[cur] != 0) && (path[cur] != '/')) cur++; if (path[cur] == 0) return(0); /* we are positionned at the beginning of the first segment */ cur++; out = cur; /* * Analyze each segment in sequence. */ while (path[cur] != 0) { /* * e) All occurrences of "<segment>/../", where <segment> is a * complete path segment not equal to "..", are removed from the * buffer string. Removal of these path segments is performed * iteratively, removing the leftmost matching pattern on each * iteration, until no matching pattern remains. */ if ((cur > 1) && (out > 1) && (path[cur] == '/') && (path[cur + 1] == '.') && (path[cur + 2] == '.') && (path[cur + 3] == '/') && ((path[out] != '.') || (path[out - 1] != '.') || (path[out - 2] != '/'))) { cur += 3; out --; while ((out > 0) && (path[out] != '/')) { out --; } path[out] = 0; continue; } /* * f) If the buffer string ends with "<segment>/..", where <segment> * is a complete path segment not equal to "..", that * "<segment>/.." is removed. */ if ((path[cur] == '/') && (path[cur + 1] == '.') && (path[cur + 2] == '.') && (path[cur + 3] == 0) && ((path[out] != '.') || (path[out - 1] != '.') || (path[out - 2] != '/'))) { cur += 4; out --; while ((out > 0) && (path[out - 1] != '/')) { out --; } path[out] = 0; continue; } path[out++] = path[cur++]; /* / or 0 */ } path[out] = 0; /* * g) If the resulting buffer string still begins with one or more * complete path segments of "..", then the reference is * considered to be in error. Implementations may handle this * error by retaining these components in the resolved path (i.e., * treating them as part of the final URI), by removing them from * the resolved path (i.e., discarding relative levels above the * root), or by avoiding traversal of the reference. * * We discard them from the final path. */ cur = 0; while ((path[cur] == '/') && (path[cur + 1] == '.') && (path[cur + 2] == '.')) cur += 3; if (cur != 0) { out = 0; while (path[cur] != 0) path[out++] = path[cur++]; path[out] = 0; } return(0);}/** * xmlBuildURI: * @URI: the URI instance found in the document * @base: the base value * * Computes he final URI of the reference done by checking that * the given URI is valid, and building the final URI using the * base URI. This is processed according to section 5.2 of the * RFC 2396 * * 5.2. Resolving Relative References to Absolute Form * * Returns a new URI string (to be freed by the caller) or NULL in case * of error. */xmlChar *xmlBuildURI(const xmlChar *URI, const xmlChar *base) { xmlChar *val = NULL; int ret, len, index, cur, out; xmlURIPtr ref = NULL; xmlURIPtr bas = NULL; xmlURIPtr res = NULL; /* * 1) The URI reference is parsed into the potential four components and * fragment identifier, as described in Section 4.3. */ ref = xmlCreateURI(); if (ref == NULL) goto done; ret = xmlParseURIReference(ref, (const char *) URI); if (ret != 0) goto done; bas = xmlCreateURI(); if (bas == NULL) goto done; ret = xmlParseURIReference(bas, (const char *) base); if (ret != 0) goto done; /* * 2) If the path component is empty and the scheme, authority, and * query components are undefined, then it is a reference to the * current document and we are done. Otherwise, the reference URI's * query and fragment components are defined as found (or not found) * within the URI reference and not inherited from the base URI. */ res = xmlCreateURI(); if (res == NULL) goto done; if ((ref->scheme == NULL) && (ref->path == NULL) && ((ref->authority == NULL) && (ref->server == NULL)) && (ref->query == NULL)) { if (ref->fragment == NULL) goto done; res->fragment = xmlMemStrdup(ref->fragment); val = xmlSaveUri(res); goto done; } /* * 3) If the scheme component is defined, indicating that the reference * starts with a scheme name, then the reference is interpreted as an * absolute URI and we are done. Otherwise, the reference URI's * scheme is inherited from the base URI's scheme component. */ if (ref->scheme != NULL) { val = xmlSaveUri(ref); goto done; } res->scheme = xmlMemStrdup(bas->scheme); /* * 4) If the authority component is defined, then the reference is a * network-path and we skip to step 7. Otherwise, the reference * URI's authority is inherited from the base URI's authority * component, which will also be undefined if the URI scheme does not * use an authority component. */ if ((ref->authority != NULL) || (ref->server != NULL)) { if (ref->authority != NULL) res->authority = xmlMemStrdup(ref->authority); else { res->server = xmlMemStrdup(ref->server); if (ref->user != NULL) res->user = xmlMemStrdup(ref->user); res->port = ref->port; } if (ref->path != NULL) res->path = xmlMemStrdup(ref->path); if (ref->query != NULL) res->query = xmlMemStrdup(ref->query); if (ref->fragment != NULL) res->fragment = xmlMemStrdup(ref->fragment); goto step_7; } if (bas->authority != NULL) res->authority = xmlMemStrdup(bas->authority); else if (bas->server != NULL) { res->server = xmlMemStrdup(bas->server); if (bas->user != NULL) res->user = xmlMemStrdup(bas->user); res->port = bas->port; } /* * 5) If the path component begins with a slash character ("/"), then * the reference is an absolute-path and we skip to step 7. */ if ((ref->path != NULL) && (ref->path[0] == '/')) { res->path = xmlMemStrdup(ref->path); if (ref->query != NULL) res->query = xmlMemStrdup(ref->query); if (ref->fragment != NULL) res->fragment = xmlMemStrdup(ref->fragment); goto step_7; } /* * 6) If this step is reached, then we are resolving a relative-path * reference. The relative path needs to be merged with the base * URI's path. Although there are many ways to do this, we will * describe a simple method using a separate string buffer. * * Allocate a buffer large enough for the result string. */ len = 2; /* extra / and 0 */ if (ref->path != NULL) len += strlen(ref->path); if (bas->path != NULL) len += strlen(bas->path); res->path = (char *) xmlMalloc(len); if (res->path == NULL) { fprintf(stderr, "xmlBuildURI: out of memory\n"); goto done; } res->path[0] = 0; /* * a) All but the last segment of the base URI's path component is * copied to the buffer. In other words, any characters after the * last (right-most) slash character, if any, are excluded. */ cur = 0; out = 0; if (bas->path != NULL) { while (bas->path[cur] != 0) { while ((bas->path[cur] != 0) && (bas->path[cur] != '/')) cur++; if (bas->path[cur] == 0) break; cur++; while (out < cur) { res->path[out] = bas->path[out]; out++; } } } res->path[out] = 0; /* * b) The reference's path component is appended to the buffer * string. */ if (ref->path != NULL) { index = 0; while (ref->path[index] != 0) { res->path[out++] = ref->path[index++]; } } res->path[out] = 0; /* * Steps c) to h) are really path normalization steps */ xmlNormalizeURIPath(res->path);step_7: /* * 7) The resulting URI components, including any inherited from the * base URI, are recombined to give the absolute form of the URI * reference. */ val = xmlSaveUri(res);done: if (ref != NULL) xmlFreeURI(ref); if (base != NULL) xmlFreeURI(bas); if (res != NULL) xmlFreeURI(res); return(val);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -