/** * @brief Parse the fragment component of a URI * * @param[in,out] uri Pointer to a URI structure * @param[in,out] q Double pointer to a string containing the URI * * @returns Operation status * @retval 0 Success * @retval <0 Error */ static int uri_parse_fragment(uri_t *uri, char **q) { ssize_t num = 0; size_t len = 0; char *p = NULL; if (uri->fragment != NULL) { return -EBADMSG; } p = strsep(q, ""); if (p == NULL) { uri_destroy(uri); return -EBADMSG; } len = strlen(p) + 1; uri->fragment = calloc(len, 1); if (uri->fragment == NULL) { uri_destroy(uri); return -ENOMEM; } num = uri_decode_str(uri->fragment, p, 0, len); if ((num == -1) || (num >= len)) { uri_destroy(uri); return -EBADMSG; } return 0; }
static URI * parseuris(const char* basestr, const char *uristr){ URI *uri, *rel, *base; if(basestr){ base = uri_create_str(basestr, NULL); if(!base) return NULL; rel = uri_create_str(uristr, NULL); if(!rel) return NULL; uri = uri_create_uri(rel, base); if(!uri) return NULL; uri_destroy(base); uri_destroy(rel); return uri; } uri = uri_create_str(uristr, NULL); if(!uri) return NULL; return uri; }
/** * @brief Parse the scheme component of a URI * * @param[in,out] uri Pointer to a URI structure * @param[in,out] q Double pointer to a string containing the URI * * @returns Operation status * @retval 0 Success * @retval <0 Error */ static int uri_parse_scheme(uri_t *uri, char **q) { ssize_t num = 0; size_t len = 0; char *p = NULL; char *r = NULL; if (uri->scheme != NULL) { return -EBADMSG; } p = *q; r = strchr(p, ':'); if (r != NULL) { *r = '\0'; len = strlen(p) + 1; if (len > 1) { uri->scheme = calloc(len, 1); if (uri->scheme == NULL) { uri_destroy(uri); return -ENOMEM; } num = uri_decode_str(uri->scheme, p, 0, len); if ((num == -1) || (num >= len)) { uri_destroy(uri); return -EBADMSG; } } *q = r + 1; } return 0; }
char * join(char *baseuri, char *reluri){ URI *uri; char *res; int r; uri = parseuris(baseuri,reluri); if(!uri) return NULL; res = get_uri(uri); uri_destroy(uri); return res; }
int uri_copy(uri_t *dest, uri_t *src) { if ((dest == NULL) || (src == NULL)) { return -EINVAL; } uri_destroy(dest); if (src->scheme != NULL) { dest->scheme = strdup(src->scheme); if (dest->scheme == NULL) { uri_destroy(dest); return -ENOMEM; } } if (src->userinfo != NULL) { dest->userinfo = strdup(src->userinfo); if (dest->userinfo == NULL) { uri_destroy(dest); return -ENOMEM; } } if (src->host != NULL) { dest->host = strdup(src->host); if (dest->scheme == NULL) { uri_destroy(dest); return -ENOMEM; } } if (src->port != NULL) { dest->port = strdup(src->port); if (dest->scheme == NULL) { uri_destroy(dest); return -ENOMEM; } } if (src->path != NULL) { dest->path = strdup(src->path); if (dest->path == NULL) { uri_destroy(dest); return -ENOMEM; } } if (src->query != NULL) { dest->query = strdup(src->query); if (dest->query == NULL) { uri_destroy(dest); return -ENOMEM; } } if (src->fragment != NULL) { dest->fragment = strdup(src->fragment); if (dest->fragment == NULL) { uri_destroy(dest); return -ENOMEM; } } return 0; }
int uri_parse(uri_t *uri, const char *str) { char *s = NULL; char *q = NULL; char c = '\0'; int ret = 0; if ((uri == NULL) || (str == NULL)) { return -EINVAL; } uri_destroy(uri); s = strdup(str); if (s == NULL) { return -ENOMEM; } q = s; if (*s != '/') { /* read scheme */ ret = uri_parse_scheme(uri, &q); if (ret != 0) { free(s); return ret; } } /* read hier-part */ ret = uri_parse_hier_part(uri, &q); if (ret != 0) { free(s); return ret; } if (q != NULL) { /* check with the original input string */ /* to see what character was overwritten */ c = str[(q - 1) - s]; if (c == '?') { ret = uri_parse_query(uri, &q); if (ret != 0) { free(s); return ret; } } } if (q != NULL) { /* check with the original input string */ /* to see what character was overwritten */ c = str[(q - 1) - s]; if (c == '#') { ret = uri_parse_fragment(uri, &q); if (ret != 0) { free(s); return ret; } } } free(s); if (q != NULL) { return -EBADMSG; } return 0; }
/** * @brief Parse the hierarchy part of a URI * * @param[in,out] uri Pointer to a URI structure * @param[in,out] q Double pointer to a string containing the URI * * @returns Operation status * @retval 0 Success * @retval <0 Error */ static int uri_parse_hier_part(uri_t *uri, char **q) { ssize_t num = 0; size_t len = 0; char *port = NULL; char *path = NULL; char *p = NULL; char *r = NULL; if ((uri->userinfo != NULL) || (uri->host != NULL) || (uri->port != NULL) || (uri->path != NULL)) { return -EBADMSG; } p = strsep(q, "?#"); if (p == NULL) { uri_destroy(uri); return -EBADMSG; } len = strlen(p); if ((len >= 2) && (p[0] == '/') && (p[1] == '/')) { /* parse authority and path */ p += 2; r = strchr(p, '@'); if (r != NULL) { /* parse userinfo */ *r = '\0'; len = strlen(p) + 1; uri->userinfo = calloc(len, 1); if (uri->userinfo == NULL) { uri_destroy(uri); return -ENOMEM; } num = uri_decode_str(uri->userinfo, p, 0, len); if ((num == -1) || (num >= len)) { uri_destroy(uri); return -EBADMSG; } p = r + 1; } /* check for port and path */ port = uri_find_port(p); if (port != NULL) { *port++ = '\0'; path = strchr(port, '/'); } else { path = strchr(p, '/'); } if (path != NULL) { *path++ = '\0'; } /* parse host */ len = strlen(p) + 1; r = p + len - 2; if ((len > 2) && (*p == '[') && (*r == ']')) { /* strip enclosing '[' and ']' from IPv6 address */ p++; *r = '\0'; len -= 2; } if (len > 1) { uri->host = calloc(len, 1); if (uri->host == NULL) { uri_destroy(uri); return -ENOMEM; } num = uri_decode_str(uri->host, p, 0, len); if ((num == -1) || (num >= len)) { uri_destroy(uri); return -EBADMSG; } } if (port != NULL) { /* parse port */ len = strlen(port) + 1; uri->port = calloc(len, 1); if (uri->port == NULL) { uri_destroy(uri); return -ENOMEM; } num = uri_decode_str(uri->port, port, 0, len); if ((num == -1) || (num >= len)) { uri_destroy(uri); return -EBADMSG; } } if (path != NULL) { /* parse path */ len = strlen(path) + 1; uri->path = calloc(len + 1, 1); /* + 1 for the leading forward slash */ if (uri->path == NULL) { uri_destroy(uri); return -ENOMEM; } /* reintroduce stripped forward slash */ uri->path[0] = '/'; num = uri_decode_str(uri->path + 1, path, 0, len); if ((num == -1) || (num >= len)) { uri_destroy(uri); return -EBADMSG; } } } else if (len > 0) { /* parse path only */ len = strlen(p) + 1; uri->path = calloc(len, 1); if (uri->path == NULL) { uri_destroy(uri); return -ENOMEM; } num = uri_decode_str(uri->path, p, 0, len); if ((num == -1) || (num >= len)) { uri_destroy(uri); return -EBADMSG; } } return 0; }