commit 15dc7d0816a074f495897ddb8790f482fbfa27f1 from: Omar Polo date: Tue Mar 09 05:49:51 2021 UTC add url_resolve_from to resolve non-full uris commit - 723bee54d360957eec85ac2eef9ebd5516db3ade commit + 15dc7d0816a074f495897ddb8790f482fbfa27f1 blob - c1931a699d4fd7f28ab71456257f3c97eceb250d blob + b7d99055862723b1ee6e5a9e62cc963169110af0 --- url.c +++ url.c @@ -431,6 +431,54 @@ url_parse(const char *data, struct url *url, const cha strlcpy(url->query, u.query, sizeof(url->query)); if (u.fragment != NULL) strlcpy(url->fragment, u.fragment, sizeof(url->fragment)); + + return 1; +} + +int +url_resolve_from(struct url *url, const char *str, const char **err) +{ + char *marker, *query, *hash, *i; + + marker = strstr(str, "://"); + query = strchr(str, '?'); + hash = strchr(str, '#'); + + /* full URL */ + if (marker != NULL + && (query == NULL || marker < query) + && (hash == NULL || marker < hash)) + return url_parse(str, url, err); + + /* TODO: reuse more of the above */ + + /* absolute url */ + if (*str == '/') { + strlcpy(url->path, str, sizeof(url->path)); + + if ((hash = strchr(url->path, '#')) != NULL) { + *hash = '\0'; + hash++; + strlcpy(url->fragment, hash, + sizeof(url->fragment)); + } + if ((query = strchr(url->path, '?')) != NULL) { + *query = '\0'; + query++; + strlcpy(url->query, query, + sizeof(url->query)); + } + return 1; + } + + /* local url */ + for (i = strchr(url->path, '\0'); i >= url->path; --i) { + if (*i == '/') + break; + } + + *i = '\0'; + strlcat(url->path, str, sizeof(url->path)); return 1; } blob - b43ea710c8ecda1d6981658ecdab720281d9da80 blob + 1da297cb09c85ac346bf9128b7838afb3ccb901a --- url.h +++ url.h @@ -29,3 +29,4 @@ struct url { }; int url_parse(const char*, struct url*, const char**); +int url_resolve_from(struct url*, const char*, const char**);