📄 uri.c
字号:
/* * Concat the set of path segments to the current path */ len = cur - *str; if (slash) len++; if (uri->path != NULL) { len2 = strlen(uri->path); len += len2; } path = (char *) xmlMallocAtomic(len + 1); if (path == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlParseURIPathSegments: out of memory\n"); *str = cur; return (-1); } if (uri->path != NULL) memcpy(path, uri->path, len2); if (slash) { path[len2] = '/'; len2++; } path[len2] = 0; if (cur - *str > 0) { if (uri->cleanup & 2) { memcpy(&path[len2], *str, cur - *str); path[len2 + (cur - *str)] = 0; } else xmlURIUnescapeString(*str, cur - *str, &path[len2]); } if (uri->path != NULL) xmlFree(uri->path); uri->path = path; } *str = cur; return (0);}/** * xmlParseURIAuthority: * @uri: pointer to an URI structure * @str: pointer to the string to analyze * * Parse the authority part of an URI. * * authority = server | reg_name * server = [ [ userinfo "@" ] hostport ] * reg_name = 1*( unreserved | escaped | "$" | "," | ";" | ":" | * "@" | "&" | "=" | "+" ) * * Note : this is completely ambiguous since reg_name is allowed to * use the full set of chars in use by server: * * 3.2.1. Registry-based Naming Authority * * The structure of a registry-based naming authority is specific * to the URI scheme, but constrained to the allowed characters * for an authority component. * * Returns 0 or the error code */static intxmlParseURIAuthority(xmlURIPtr uri, const char **str) { const char *cur; int ret; if (str == NULL) return(-1); cur = *str; /* * try first to parse it as a server string. */ ret = xmlParseURIServer(uri, str); if ((ret == 0) && (*str != NULL) && ((**str == 0) || (**str == '/') || (**str == '?'))) return(0); *str = cur; /* * 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); if (uri->cleanup & 2) uri->authority = STRNDUP(*str, cur - *str); else 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 hierarchical part * * hier_part = ( net_path | abs_path ) [ "?" query ] * abs_path = "/" path_segments * net_path = "//" authority [ abs_path ] * * Returns 0 or the error code */static 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 */static intxmlParseAbsoluteURI(xmlURIPtr uri, const char **str) { int ret; const char *cur; if (str == NULL) return(-1); cur = *str; ret = xmlParseURIScheme(uri, str); if (ret != 0) return(ret); if (**str != ':') { *str = cur; 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 */static 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 if (cur[0] != '#' && cur[0] != '?') { 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 absolute 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);}/** * xmlParseURI: * @str: the URI string to analyze * * Parse an URI * * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] * * Returns a newly built xmlURIPtr or NULL in case of error */xmlURIPtrxmlParseURI(const char *str) { xmlURIPtr uri; int ret; if (str == NULL) return(NULL); uri = xmlCreateURI(); if (uri != NULL) { ret = xmlParseURIReference(uri, str); if (ret) { xmlFreeURI(uri); return(NULL); } } return(uri);}/** * xmlParseURIRaw: * @str: the URI string to analyze * @raw: if 1 unescaping of URI pieces are disabled * * Parse an URI but allows to keep intact the original fragments. * * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] * * Returns a newly built xmlURIPtr or NULL in case of error */xmlURIPtrxmlParseURIRaw(const char *str, int raw) { xmlURIPtr uri; int ret; if (str == NULL) return(NULL); uri = xmlCreateURI(); if (uri != NULL) { if (raw) { uri->cleanup |= 2; } ret = xmlParseURIReference(uri, str); if (ret) { xmlFreeURI(uri); return(NULL); } } return(uri);}/************************************************************************ * * * Public functions * * * ************************************************************************//** * 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, indx, 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. * * NOTE that a completely empty URI is treated by modern browsers * as a reference to "." rather than as a synonym for the current * URI. Should we do that here? */ if (URI == NULL) ret = -1; else { if (*URI) { ref = xmlCreateURI(); if (ref == NULL) goto done; ret = xmlParseURIReference(ref, (const char *) URI); } else ret = 0; } if (ret != 0) goto done; if ((ref != NULL) && (ref->scheme != NULL)) { /* * The URI is absolute don't modify. */ val = xmlStrdup(URI); goto done; } if (base == NULL) ret = -1; else { bas = xmlCreateURI(); if (bas == NULL) goto done; ret = xmlParseURIReference(bas, (const char *) base); } if (ret != 0) { if (ref) val = xmlSaveUri(ref); goto done; } if (ref == NULL) { /* * the base fragment must be ignored */ if (bas->fragment != NULL) { xmlFree(bas->fragment); bas->fragment = NULL; } val = xmlSaveUri(bas); 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. * * NOTE that in modern browsers, the parsing differs from the above * in the following aspect: the query component is allowed to be * defined while still treating this as a reference to the current * document. */ res = xmlCreateURI(); if (res == NULL) goto done; if ((ref->scheme == NULL) && (ref->path == NULL) && ((ref->authority == NULL) && (ref->server == NULL))) { if (bas->scheme != NULL) res->scheme = xmlMemStrdup(bas->scheme); 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; } if (bas->path != NULL) res->path = xmlMemStrdup(bas->path); if (ref->query_raw != NULL) res->query_raw = xmlMemStrdup (ref->query_raw); else if (ref->query != NULL) res->query = xmlMemStrdup(ref->query); else if (bas->query_raw != NULL) res->query_raw = xmlMemStrdup(bas->query_raw); else if (bas->query != NULL) res->query = xmlMemStrdup(bas->query); if (ref->fragment != NULL) res->fragment = xmlMemStrdup(ref->fragment); goto step_7; } /* * 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; } if (bas->scheme != NULL) res->scheme = xmlMemStrdup(bas->scheme); if (ref->query_raw != NULL) res->query_raw = xmlMemStrdup(ref->query_raw); else if (ref->query != NULL) res->query = xmlMemStrdup(ref->query); if (ref->fragment != NULL) res->fragment = xmlMemStrdup(ref->fragment); /* * 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. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -