AmendHub

Download:

jcs

/

detritus

/

amendments

/

37

gemini: Support 1X input requests


jcs made amendment 37 about 1 year ago
--- gemini.c Mon Nov 11 23:12:07 2024 +++ gemini.c Fri Nov 15 11:43:02 2024 @@ -20,8 +20,6 @@ #include "detritus.h" -#define GEMINI_PORT 1965 - enum { PARSE_STATE_HEADER, PARSE_STATE_BODY, @@ -60,7 +58,7 @@ gemini_request_init(page_handle pageh) if (page->uri->port == 0) page->uri->port = GEMINI_PORT; - + output_len = strlen(page->uri->str) + 2; output = xmalloc(output_len + 1); if (page->request->output == NULL) { @@ -351,15 +349,19 @@ gemini_reset(page_handle pageh) /* restart at body */ page->parse_state = PARSE_STATE_BODY; page->content_pos = page->header_len; - - browser_commit_to_loading_page(page->browser); } static bool parse_header(struct page *page, char *str, size_t len) { - short status; - char fail[32]; + char fail[32], *newuri, *encoded, *query; + Str255 txt; + GrafPtr win; + DialogPtr dlg; + Handle ihandle; + Rect irect, dlgrect; + size_t tlen; + short status, hit, itype, ret, top; BROWSER_DEBUGF((page->browser, "Received header: %s", str)); if (!(str[0] >= '0' && str[0] <= '9' && @@ -374,11 +376,78 @@ parse_header(struct page *page, char *str, size_t len) fail[MIN(len, sizeof(fail) - 1)] = '\0'; if (page->server_status >= 10 && page->server_status <= 19) { - /* input, not supported */ - browser_statusf(page->browser, "Error: Input not supported (%d)", - page->server_status); + /* input requested */ + GetPort(&win); + + if ((dlg = GetNewDialog(INPUT_DLOG_ID, NULL, + (WindowPtr)-1)) == NULL) { + warn("Can't find DLOG %d", INPUT_DLOG_ID); + return false; + } + center_in_screen(dlg->portRect.right - dlg->portRect.left, + dlg->portRect.bottom - dlg->portRect.top, true, &dlgrect); + MoveWindow(dlg, dlgrect.left, dlgrect.top, true); + + snprintf((char *)txt, sizeof(txt), "Input requested from %s", + page->uri->hostname); + CtoPstr(txt); + SetWTitle(dlg, txt); + + GetDItem(dlg, INPUT_DLOG_PROMPT_ID, &itype, &ihandle, &irect); + tlen = len - 2; + if (tlen >= sizeof(txt)) + tlen = sizeof(txt) - 1; + memcpy(txt + 1, str + 3, tlen); + txt[0] = tlen; + SetIText(ihandle, txt); + + ShowWindow(dlg); + for (;;) { + ModalDialog(ModalDialogFilter, &hit); + if (hit == ok || hit == cancel) + break; + } + + if (hit == ok) { + GetDItem(dlg, INPUT_DLOG_INPUT_ID, &itype, &ihandle, &irect); + GetIText(ihandle, txt); + PtoCstr(txt); + } + + DisposDialog(dlg); + + SetPort(win); + + if (hit != ok) { + browser_statusf(page->browser, "Canceled input"); + return false; + } + + /* make a new uri with this same one but send input as query */ + encoded = uri_encode(txt); + if (encoded == NULL) { + browser_statusf(page->browser, "Error: Out of memory"); + return false; + } + + tlen = 1 + strlen(encoded); + query = xmalloc(tlen + 1); + if (query == NULL) { + xfree(&encoded); + browser_statusf(page->browser, "Error: Out of memory"); + } + + snprintf(query, tlen + 1, "?%s", encoded); + xfree(&encoded); + + page->redir_to = build_relative_uri(page->uri, query, tlen); + xfree(&query); + if (page->redir_to == NULL) + browser_statusf(page->browser, "Error: Out of memory"); + return false; } + if (page->server_status >= 20 && page->server_status <= 29) { /* success */ if (len + 3 + 1 > sizeof(page->content_type)) @@ -387,30 +456,35 @@ parse_header(struct page *page, char *str, size_t len) page->content_type[len - 2] = '\0'; return true; } + if (page->server_status >= 30 && page->server_status <= 39) { /* redirect */ page->redir_to = build_relative_uri(page->uri, str + 3, len - 2); /* TODO: infinite loop detection */ return false; } + if (page->server_status >= 40 && page->server_status <= 49) { /* temp fail */ browser_statusf(page->browser, "Error: Server reported temporary " "failure: %s", fail); return false; } + if (page->server_status >= 50 && page->server_status <= 59) { /* perm fail */ browser_statusf(page->browser, "Error: Server reported " "permanent failure: %s", fail); return false; } + if (page->server_status >= 60 && page->server_status <= 69) { /* auth, not supported */ browser_statusf(page->browser, "Error: Auth not supported (%d)", status); return false; } + browser_statusf(page->browser, "Error: Unsupported status: %s", fail); return false; }