commit 0972d8b2a08f2c28e86b3cc310f9eac1be74766d from: Omar Polo date: Tue Mar 02 16:32:07 2021 UTC move special page to main process commit - 86395f5c1e1693b506e0e3e9087a073aeb694e86 commit + 0972d8b2a08f2c28e86b3cc310f9eac1be74766d blob - f510a44129c6f2446a709f1546452e51701bbe85 blob + b9d7b8287a090c303ff1b6a8df20342f17075afb --- gemini.c +++ gemini.c @@ -63,12 +63,14 @@ static void check_special_page(struct req*, const ch static void handle_get(struct imsg*, size_t); static void handle_cert_status(struct imsg*, size_t); +static void handle_proceed(struct imsg*, size_t); static void handle_stop(struct imsg*, size_t); static void handle_quit(struct imsg*, size_t); static imsg_handlerfn *handlers[] = { [IMSG_GET] = handle_get, [IMSG_CERT_STATUS] = handle_cert_status, + [IMSG_PROCEED] = handle_proceed, [IMSG_STOP] = handle_stop, [IMSG_QUIT] = handle_quit, }; @@ -343,7 +345,6 @@ parse_reply(struct req *req) req->buf, len); imsg_flush(ibuf); - yield_r(req, copy_body, NULL); return; err: @@ -377,27 +378,6 @@ copy_body(int fd, short ev, void *d) break; } } -} - -static int -serve_special_page(struct req *req, const char *url) -{ - int code = 20; - const char *meta = "text/gemini"; - - if (strcmp(url, "about:new")) - return 0; - - imsg_compose(ibuf, IMSG_GOT_CODE, req->id, 0, -1, &code, sizeof(code)); - imsg_compose(ibuf, IMSG_GOT_META, req->id, 0, -1, meta, strlen(meta)+1); - imsg_compose(ibuf, IMSG_BUF, req->id, 0, -1, about_new, strlen(about_new)); - imsg_compose(ibuf, IMSG_EOF, req->id, 0, -1, NULL, 0); - imsg_flush(ibuf); - - /* don't close_page here, since req is not added to requests - * queue */ - free(req); - return 1; } static void @@ -417,9 +397,6 @@ handle_get(struct imsg *imsg, size_t datalen) req->id = imsg->hdr.peerid; - if (serve_special_page(req, data)) - return; - if (!url_parse(imsg->data, &req->url, &e)) { fprintf(stderr, "failed to parse url: %s\n", e); close_with_err(req, e); @@ -467,6 +444,15 @@ handle_cert_status(struct imsg *imsg, size_t datalen) } static void +handle_proceed(struct imsg *imsg, size_t datalen) +{ + struct req *req; + + req = req_by_id(imsg->hdr.peerid); + yield_r(req, copy_body, NULL); +} + +static void handle_stop(struct imsg *imsg, size_t datalen) { struct req *req; blob - 70fa25871c6cf66971d840815d9da003ac15074c blob + 44faf3c1699c6a9ef82a9c23ef26dbb275b44e64 --- pages.c +++ pages.c @@ -36,3 +36,22 @@ const char *about_new = ">quote\n" "Id dolore aperiam voluptatem libero eaque omnis rerum nulla. Ullam sit voluptate accusamus molestiae enim minus. Fugit sequi quam dignissimos. Odio inventore vel sed. Voluptatem aut magni dignissimos." ; + +const char *err_pages[70] = { + [CANNOT_FETCH] = "# Couldn't load the page\n", + [TOO_MUCH_REDIRECTS] = "# Too much redirects\n", + + [40] = "# Temporary failure\n", + [41] = "# Server unavailable\n", + [42] = "# CGI error\n", + [43] = "# Proxy error\n", + [44] = "# Slow down\n", + [50] = "# Permanent failure\n", + [51] = "# Not found\n", + [52] = "# Gone\n", + [53] = "# Proxy request refused\n", + [59] = "# Bad request\n", + [60] = "# Client certificate required\n", + [61] = "# Certificate not authorised\n", + [62] = "# Certificate not valid\n" +}; blob - b22f1e2f3eac9a175081da9049cfea62e36b4da0 blob + ff93bcfbd3dbbff0d6f93cd7bbe960dfa6329146 --- telescope.c +++ telescope.c @@ -24,6 +24,9 @@ static void handle_imsg_got_meta(struct imsg*, size_t) static void handle_imsg_buf(struct imsg*, size_t); static void handle_imsg_eof(struct imsg*, size_t); +static void load_page_from_str(struct tab*, const char*); +static void load_url(struct tab*, const char*); + static imsg_handlerfn *handlers[] = { [IMSG_ERR] = handle_imsg_err, [IMSG_CHECK_CERT] = handle_imsg_check_cert, @@ -72,36 +75,78 @@ handle_imsg_check_cert(struct imsg *imsg, size_t datal static void handle_imsg_got_code(struct imsg *imsg, size_t datalen) { - int code; + const char *errpage; + struct tab *tab; - if (sizeof(code) != datalen) + tab = tab_by_id(imsg->hdr.peerid); + + if (sizeof(tab->code) != datalen) die(); + memcpy(&tab->code, imsg->data, sizeof(tab->code)); - memcpy(&code, imsg->data, sizeof(code)); + if (tab->code < 20) { + if (tab->code != 10 && tab->code != 11) + tab->code = 10; + } else if (tab->code < 30) + tab->code = 20; + else if (tab->code < 40) + tab->code = 30; + else if (tab->code < 50) + tab->code = 40; + else if (tab->code < 60) + tab->code = 50; + else + tab->code = 60; - /* fprintf(stderr, "got status code: %d\n", code); */ + if (tab->code != 30) + tab->redirect_count = 0; } static void handle_imsg_got_meta(struct imsg *imsg, size_t datalen) { - /* fprintf(stderr, "got meta: "); */ - /* fflush(stderr); */ - /* write(2, imsg->data, datalen); */ - /* fprintf(stderr, "\n"); */ + struct tab *tab; + + tab = tab_by_id(imsg->hdr.peerid); + + if (sizeof(tab->meta) <= datalen) + die(); + memcpy(tab->meta, imsg->data, datalen); + + /* TODO: parse the MIME type if it's 20 */ + gemtext_initparser(&tab->page); + + if (tab->code == 20) { + imsg_compose(ibuf, IMSG_PROCEED, tab->id, 0, -1, NULL, 0); + imsg_flush(ibuf); + return; + } + + if (tab->code == 30) + die(); + + /* 4x, 5x or 6x */ + + if (!tab->page.parse(&tab->page, err_pages[tab->code], + strlen(err_pages[tab->code]))) + die(); + if (!tab->page.free(&tab->page)) + die(); + + ui_on_tab_refresh(tab); } static void handle_imsg_buf(struct imsg *imsg, size_t datalen) { - struct tab *t; + struct tab *tab; - t = tab_by_id(imsg->hdr.peerid); + tab = tab_by_id(imsg->hdr.peerid); - if (!t->page.parse(&t->page, imsg->data, datalen)) + if (!tab->page.parse(&tab->page, imsg->data, datalen)) die(); - ui_on_tab_refresh(t); + ui_on_tab_refresh(tab); } static void @@ -145,12 +190,35 @@ dispatch_imsg(int fd, short ev, void *d) } } +static void +load_page_from_str(struct tab *tab, const char *page) +{ + gemtext_initparser(&tab->page); + if (!tab->page.parse(&tab->page, about_new, strlen(about_new))) + die(); + if (!tab->page.free(&tab->page)) + die(); + ui_on_tab_refresh(tab); +} + +static void +load_url(struct tab *tab, const char *url) +{ + if (!strcmp(url, "about:new")) { + load_page_from_str(tab, about_new); + return; + } + + imsg_compose(ibuf, IMSG_GET, tab->id, 0, -1, url, strlen(url)+1); + imsg_flush(ibuf); +} + void new_tab(void) { struct tab *tab; const char *url = "about:new"; - /* const char *url = "gemini://localhost/cgi/slow-out"; */ + /* const char *url = "gemini://localhost.it/"; */ if ((tab = calloc(1, sizeof(*tab))) == NULL) die(); @@ -159,12 +227,10 @@ new_tab(void) tab->id = tab_counter++; TAILQ_INIT(&tab->page.head); - gemtext_initparser(&tab->page); - imsg_compose(ibuf, IMSG_GET, tab->id, 0, -1, url, strlen(url)+1); - imsg_flush(ibuf); - ui_on_new_tab(tab); + + load_url(tab, url); } int blob - fba4108e1f8e0cf7637d6dce7f7e1c4d31f4f1dc blob + 62c3fb3d9c04d0e9a9f20ab61f4ff9c1a0d92f87 --- telescope.h +++ telescope.h @@ -36,9 +36,10 @@ enum imsg_type { IMSG_CERT_STATUS, IMSG_GOT_CODE, IMSG_GOT_META, + IMSG_PROCEED, + IMSG_STOP, IMSG_BUF, IMSG_EOF, - IMSG_STOP, IMSG_QUIT, }; @@ -89,19 +90,27 @@ struct tab { TAILQ_ENTRY(tab) tabs; uint32_t id; uint32_t flags; + + int code; + char meta[GEMINI_URL_LEN]; + int redirect_count; }; extern struct event imsgev; -/* about.c */ -extern const char *about_new; - /* gemini.c */ int client_main(struct imsgbuf *b); /* gemtext.c */ void gemtext_initparser(struct parser*); +/* pages.c */ +extern const char *about_new; + +#define CANNOT_FETCH 0 +#define TOO_MUCH_REDIRECTS 1 +extern const char *err_pages[70]; + /* ui.c */ int ui_init(void); void ui_on_new_tab(struct tab*);