#define _POSIX_C_SOURCE 200809l #include #include #include "xalloc.h" #include "url.h" void url_free(url_t *u) { if (u->scheme) free(u->scheme); if (u->net_path) free(u->net_path); if (u->abs_path) free(u->abs_path); if (u->net_node) free(u->net_node); if (u->net_service) free(u->net_service); } url_t *url_parse(const char *s) { // TODO: verify each token (or whole url with regex) char *u = xstrdup(s); url_t *url = xmalloc(sizeof(url_t)); memset(url, 0, sizeof(url_t)); char *state = NULL; char *t = u; char *m = strstr(u, "://"); char *scheme; if (!m) { scheme = "http"; } else { m[0] = '\0'; m[2] = '\0'; u = &(m[3]); } char *net_path = strtok_r(u, "/", &state); if (!net_path) goto url_err; char *abs_path = strtok_r(NULL, "", &state); // default to index.html if (!abs_path) abs_path = ""; url->scheme = xstrdup(scheme); url->net_path = xstrdup(net_path); url->abs_path = xstrdup(abs_path); state = NULL; char *net_service = url->scheme; char *net_node = strtok_r(net_path, ":", &state); if (strcmp(net_node, url->net_path)) { net_service = strtok_r(NULL, "", &state); if (!net_service) net_service = url->scheme; } url->net_node = xstrdup(net_node); url->net_service = xstrdup(net_service); free(t); return url; url_err: url_free(url); free(url); free(u); return NULL; }