commit 31f1a758a6a9144108ca1356abef2d56ef12f759 from: Omar Polo date: Thu Apr 22 10:42:50 2021 UTC switch to phos_uri Initially I took the IRI parser from gmid, stripped of the UTF-8 things and transformed back into a URI parser. Then I've added some functions to resolve URIs, but it wasn't enough. gmid parser is aimed at servers, and so it doesn't handle very well relative links. This makes use of the libphos uri parser, which was coded to follow the RFC more strictly, and to fully support all kinds of URIs. It'll need to be expanded in the future and be improved for sure commit - bfa33dbefe2bc41a9961e881cfea874e6bc78cfa commit + 31f1a758a6a9144108ca1356abef2d56ef12f759 blob - e518dcfed610e17e951ae6e87eda60570f31d844 blob + d440349455599524b60f7bb68fb1bb5738469e33 --- .gitignore +++ .gitignore @@ -1,6 +1,9 @@ TAGS .deps compat/.deps +phos/.deps +phos/.dirstamp +phos/*.o Makefile Makefile.in aclocal.m4 blob - 0b37a9f76c62a30d723a4f118c22eb3261852483 blob + e770e1a7b7b096fd6e6f57c674a157aed8c54147 --- Makefile.am +++ Makefile.am @@ -18,12 +18,13 @@ telescope_SOURCES = cmd.gen.h \ telescope.h \ textplain.c \ ui.c \ - url.c \ - url.h \ utf8.c \ util.c \ wrap.c +# phos bundled files +telescope_SOURCES += phos/phos_uri.c + BUILT_SOURCES = cmd.gen.h CLEANFILES = cmd.gen.h blob - 4738d542f20472d5606661f6b4996e1e753181ff blob + c3f28e1156edd6f29d138c08d8b7f432f9c09b4b --- gemini.c +++ gemini.c @@ -96,7 +96,7 @@ TAILQ_HEAD(, req) reqhead; /* a pending request */ struct req { struct event ev; - struct url url; + struct phos_uri url; uint32_t id; int fd; struct tls *ctx; @@ -387,20 +387,9 @@ write_request(int fd, short ev, void *d) ssize_t r; size_t len; char buf[1027]; /* URL + \r\n\0 */ - - strlcpy(buf, "gemini://", sizeof(buf)); - strlcat(buf, req->url.host, sizeof(buf)); - if (*req->url.port != '\0' && strcmp("1965", req->url.port)) { - strlcat(buf, ":", sizeof(buf)); - strlcat(buf, req->url.port, sizeof(buf)); - } - strlcat(buf, "/", sizeof(buf)); - strlcat(buf, req->url.path, sizeof(buf)); - if (req->url.query[0] != '\0') { - strlcat(buf, "?", sizeof(buf)); - strlcat(buf, req->url.query, sizeof(buf)); - } + if (!phos_serialize_uri(&req->url, buf, sizeof(buf))) + die(); len = strlcat(buf, "\r\n", sizeof(buf)); @@ -534,7 +523,6 @@ static void handle_get(struct imsg *imsg, size_t datalen) { struct req *req; - const char *e; char *data; data = imsg->data; @@ -548,8 +536,8 @@ handle_get(struct imsg *imsg, size_t datalen) req->id = imsg->hdr.peerid; TAILQ_INSERT_HEAD(&reqhead, req, reqs); - if (!url_parse(imsg->data, &req->url, &e)) { - close_with_err(req, e); + if (!phos_parse_absolute_uri(data, &req->url)) { + close_with_err(req, "Can't parse URI"); return; } blob - 185a4ca90006ff9a58aeb4571ffa3257f7c25b5a blob + 10c411cd8ebaf898e152e0d585a4ab4a73c6588b --- telescope.c +++ telescope.c @@ -14,8 +14,8 @@ struct tabshead tabshead; /* the first is also the fallback one */ static struct proto protos[] = { - { "gemini:", load_gemini_url }, - { "about:", load_about_url }, + { "gemini", load_gemini_url }, + { "about", load_about_url }, { NULL, NULL }, }; @@ -100,7 +100,7 @@ handle_imsg_check_cert(struct imsg *imsg, size_t datal tab = tab_by_id(imsg->hdr.peerid); - if ((e = telescope_lookup_tofu(&certs, tab->url.host)) == NULL) { + if ((e = telescope_lookup_tofu(&certs, tab->uri.host)) == NULL) { /* TODO: an update in libressl/libretls changed * significantly. Find a better approach at storing * the certs! */ @@ -110,7 +110,7 @@ handle_imsg_check_cert(struct imsg *imsg, size_t datal tofu_res = 1; /* trust on first use */ if ((e = calloc(1, sizeof(*e))) == NULL) abort(); - strlcpy(e->domain, tab->url.host, sizeof(e->domain)); + strlcpy(e->domain, tab->uri.host, sizeof(e->domain)); strlcpy(e->hash, hash, sizeof(e->hash)); telescope_ohash_insert(&certs, e); imsg_compose(fsibuf, IMSG_SAVE_CERT, tab->id, 0, -1, @@ -300,77 +300,58 @@ load_page_from_str(struct tab *tab, const char *page) void load_about_url(struct tab *tab, const char *url) { - char *m; - size_t len; - tab->trust = TS_VERIFIED; - memset(&tab->url, 0, sizeof(tab->url)); - - m = strchr(url, ':'); - strlcpy(tab->url.scheme, "about", sizeof(tab->url.scheme)); - strlcpy(tab->url.path, m+1, sizeof(tab->url.path)); - - len = sizeof(tab->hist_cur->h)-1; - strlcpy(tab->hist_cur->h, url, len); - gemtext_initparser(&tab->window.page); imsg_compose(fsibuf, IMSG_GET, tab->id, 0, -1, - tab->hist_cur->h, len+1); + tab->hist_cur->h, strlen(tab->hist_cur->h)+1); imsg_flush(fsibuf); } void load_gemini_url(struct tab *tab, const char *url) { - const char *err; - char *p; size_t len; - len = sizeof(tab->hist_cur->h)-1; - - if (has_prefix(url, "gemini:")) { - if (!url_parse(url, &tab->url, &err)) - goto err; - } else { - if (!url_resolve_from(&tab->url, url, &err)) - goto err; - } - - url_unparse(&tab->url, tab->hist_cur->h, len); + len = sizeof(tab->hist_cur->h); imsg_compose(netibuf, IMSG_GET, tab->id, 0, -1, - tab->hist_cur->h, len+1); + tab->hist_cur->h, len); imsg_flush(netibuf); return; - -err: - if (asprintf(&p, "#error loading %s\n>%s\n", - url, err) == -1) - die(); - strlcpy(tab->hist_cur->h, url, len); - load_page_from_str(tab, p); - free(p); } static void do_load_url(struct tab *tab, const char *url) { - struct proto *p; + struct phos_uri uri; + struct proto *p; + char *t; tab->trust = TS_UNKNOWN; + memcpy(&uri, &tab->uri, sizeof(tab->uri)); + if (!phos_resolve_uri_from_str(&uri, url, &tab->uri)) { + if (asprintf(&t, "#error loading %s\n>%s\n", + url, "Can't parse the URI") == -1) + die(); + strlcpy(tab->hist_cur->h, url, sizeof(tab->hist_cur->h)); + load_page_from_str(tab, t); + free(t); + return; + } + + phos_serialize_uri(&tab->uri, tab->hist_cur->h, + sizeof(tab->hist_cur->h)); + for (p = protos; p->schema != NULL; ++p) { - if (has_prefix(url, p->schema)) { + if (!strcmp(uri.scheme, p->schema)) { p->loadfn(tab, url); - return; + return; } } protos[0].loadfn(tab, url); - - empty_vlist(&tab->window); - empty_linelist(&tab->window); } void @@ -385,6 +366,8 @@ load_url(struct tab *tab, const char *url) } hist_push(&tab->hist, tab->hist_cur); do_load_url(tab, url); + empty_vlist(&tab->window); + empty_linelist(&tab->window); } int blob - dd7cfaf2e219ffbf7cb333bcd9c10b7e595cc1de blob + 770cd15b4aa867fe99e607edc4b6132311fa998d --- telescope.h +++ telescope.h @@ -20,9 +20,8 @@ #include "compat.h" #include +#include -#include "url.h" - #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -150,7 +149,7 @@ struct tab { uint32_t flags; enum trust_state trust; - struct url url; + struct phos_uri uri; struct histhead hist; struct hist *hist_cur; size_t hist_off; blob - 32f7475b9f1abca38940609a096cb66cf8907002 blob + 06860322003c6ca4e9fadd18097fc928eeedce9a --- ui.c +++ ui.c @@ -1091,7 +1091,7 @@ static void ir_select(void) { char buf[1025] = {0}; - struct url url; + struct phos_uri uri; struct tab *tab; tab = current_tab(); @@ -1100,9 +1100,12 @@ ir_select(void) minibuffer_hist_save_entry(); /* a bit ugly but... */ - memcpy(&url, &tab->url, sizeof(tab->url)); - url_set_query(&url, ministate.buf); - url_unparse(&url, buf, sizeof(buf)); + memcpy(&uri, &tab->uri, sizeof(tab->uri)); + + /* XXX: ptc encode! */ + memcpy(&uri.query, ministate.buf, strlen(ministate.buf)+1); + + phos_serialize_uri(&uri, buf, sizeof(buf)); load_url_in_tab(tab, buf); }