diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-01 13:46:17 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-01 13:46:17 +0300 |
commit | f8a848179504282d92be8c96022ee3d8e72509b3 (patch) | |
tree | 93e261e4e6c544ff6e79bc7438af12f166937af0 | |
parent | d1dc79623142112521d15ef936e010f099b0e242 (diff) |
Scheme-specific proxies for Gopher and HTTP
Make requests via a proxy.
TODO: What about the server domain verification? Check against the proxy
hostname?
-rw-r--r-- | src/app.c | 34 | ||||
-rw-r--r-- | src/app.h | 1 | ||||
-rw-r--r-- | src/gmrequest.c | 19 | ||||
-rw-r--r-- | src/ui/util.c | 12 |
4 files changed, 62 insertions, 4 deletions
@@ -96,6 +96,8 @@ struct Impl_App { | |||
96 | int zoomPercent; | 96 | int zoomPercent; |
97 | enum iColorTheme theme; | 97 | enum iColorTheme theme; |
98 | iBool useSystemTheme; | 98 | iBool useSystemTheme; |
99 | iString gopherProxy; | ||
100 | iString httpProxy; | ||
99 | }; | 101 | }; |
100 | 102 | ||
101 | static iApp app_; | 103 | static iApp app_; |
@@ -149,6 +151,8 @@ static iString *serializePrefs_App_(const iApp *d) { | |||
149 | appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent); | 151 | appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent); |
150 | appendFormat_String(str, "theme.set arg:%d auto:1\n", d->theme); | 152 | appendFormat_String(str, "theme.set arg:%d auto:1\n", d->theme); |
151 | appendFormat_String(str, "ostheme arg:%d\n", d->useSystemTheme); | 153 | appendFormat_String(str, "ostheme arg:%d\n", d->useSystemTheme); |
154 | appendFormat_String(str, "proxy.gopher address:%s\n", cstr_String(&d->gopherProxy)); | ||
155 | appendFormat_String(str, "proxy.http address:%s\n", cstr_String(&d->httpProxy)); | ||
152 | return str; | 156 | return str; |
153 | } | 157 | } |
154 | 158 | ||
@@ -281,6 +285,8 @@ static void init_App_(iApp *d, int argc, char **argv) { | |||
281 | d->visited = new_Visited(); | 285 | d->visited = new_Visited(); |
282 | d->bookmarks = new_Bookmarks(); | 286 | d->bookmarks = new_Bookmarks(); |
283 | d->tabEnum = 0; /* generates unique IDs for tab pages */ | 287 | d->tabEnum = 0; /* generates unique IDs for tab pages */ |
288 | init_String(&d->gopherProxy); | ||
289 | init_String(&d->httpProxy); | ||
284 | setThemePalette_Color(d->theme); | 290 | setThemePalette_Color(d->theme); |
285 | loadPrefs_App_(d); | 291 | loadPrefs_App_(d); |
286 | load_Visited(d->visited, dataDir_App_); | 292 | load_Visited(d->visited, dataDir_App_); |
@@ -427,6 +433,17 @@ enum iColorTheme colorTheme_App(void) { | |||
427 | return app_.theme; | 433 | return app_.theme; |
428 | } | 434 | } |
429 | 435 | ||
436 | const iString *schemeProxy_App(iRangecc scheme) { | ||
437 | iApp *d = &app_; | ||
438 | if (equalCase_Rangecc(scheme, "gopher")) { | ||
439 | return &d->gopherProxy; | ||
440 | } | ||
441 | if (equalCase_Rangecc(scheme, "http") || equalCase_Rangecc(scheme, "https")) { | ||
442 | return &d->httpProxy; | ||
443 | } | ||
444 | return NULL; | ||
445 | } | ||
446 | |||
430 | int run_App(int argc, char **argv) { | 447 | int run_App(int argc, char **argv) { |
431 | init_App_(&app_, argc, argv); | 448 | init_App_(&app_, argc, argv); |
432 | const int rc = run_App_(&app_); | 449 | const int rc = run_App_(&app_); |
@@ -515,11 +532,14 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { | |||
515 | isSelected_Widget(findChild_Widget(d, "prefs.retainwindow"))); | 532 | isSelected_Widget(findChild_Widget(d, "prefs.retainwindow"))); |
516 | postCommandf_App("ostheme arg:%d", | 533 | postCommandf_App("ostheme arg:%d", |
517 | isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); | 534 | isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); |
535 | postCommandf_App("proxy.http address:%s", | ||
536 | cstr_String(text_InputWidget(findChild_Widget(d, "prefs.proxy.http")))); | ||
537 | postCommandf_App("proxy.gopher address:%s", | ||
538 | cstr_String(text_InputWidget(findChild_Widget(d, "prefs.proxy.gopher")))); | ||
518 | destroy_Widget(d); | 539 | destroy_Widget(d); |
519 | return iTrue; | 540 | return iTrue; |
520 | } | 541 | } |
521 | else if (equal_Command(cmd, "prefs.ostheme.changed")) { | 542 | else if (equal_Command(cmd, "prefs.ostheme.changed")) { |
522 | //setToggle_Widget(findChild_Widget(d, "prefs.ostheme"), arg_Command(cmd)); | ||
523 | postCommandf_App("ostheme arg:%d", arg_Command(cmd)); | 543 | postCommandf_App("ostheme arg:%d", arg_Command(cmd)); |
524 | } | 544 | } |
525 | else if (equal_Command(cmd, "theme.changed")) { | 545 | else if (equal_Command(cmd, "theme.changed")) { |
@@ -739,6 +759,10 @@ iBool handleCommand_App(const char *cmd) { | |||
739 | setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->retainWindowSize); | 759 | setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->retainWindowSize); |
740 | setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"), | 760 | setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"), |
741 | collectNewFormat_String("%g", uiScale_Window(d->window))); | 761 | collectNewFormat_String("%g", uiScale_Window(d->window))); |
762 | setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.http"), | ||
763 | schemeProxy_App(range_CStr("http"))); | ||
764 | setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gopher"), | ||
765 | schemeProxy_App(range_CStr("gopher"))); | ||
742 | setCommandHandler_Widget(dlg, handlePrefsCommands_); | 766 | setCommandHandler_Widget(dlg, handlePrefsCommands_); |
743 | } | 767 | } |
744 | else if (equal_Command(cmd, "navigate.home")) { | 768 | else if (equal_Command(cmd, "navigate.home")) { |
@@ -802,6 +826,14 @@ iBool handleCommand_App(const char *cmd) { | |||
802 | } | 826 | } |
803 | return iFalse; | 827 | return iFalse; |
804 | } | 828 | } |
829 | else if (equal_Command(cmd, "proxy.gopher")) { | ||
830 | setCStr_String(&d->gopherProxy, suffixPtr_Command(cmd, "address")); | ||
831 | return iTrue; | ||
832 | } | ||
833 | else if (equal_Command(cmd, "proxy.http")) { | ||
834 | setCStr_String(&d->httpProxy, suffixPtr_Command(cmd, "address")); | ||
835 | return iTrue; | ||
836 | } | ||
805 | else { | 837 | else { |
806 | return iFalse; | 838 | return iFalse; |
807 | } | 839 | } |
@@ -57,6 +57,7 @@ uint32_t elapsedSinceLastTicker_App (void); /* milliseconds */ | |||
57 | 57 | ||
58 | int zoom_App (void); | 58 | int zoom_App (void); |
59 | enum iColorTheme colorTheme_App (void); | 59 | enum iColorTheme colorTheme_App (void); |
60 | const iString * schemeProxy_App (iRangecc scheme); | ||
60 | 61 | ||
61 | iGmCerts * certs_App (void); | 62 | iGmCerts * certs_App (void); |
62 | iVisited * visited_App (void); | 63 | iVisited * visited_App (void); |
diff --git a/src/gmrequest.c b/src/gmrequest.c index 391c7e89..24732650 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c | |||
@@ -402,6 +402,9 @@ void submit_GmRequest(iGmRequest *d) { | |||
402 | init_Url(&url, &d->url); | 402 | init_Url(&url, &d->url); |
403 | /* Check for special schemes. */ | 403 | /* Check for special schemes. */ |
404 | /* TODO: If this were a library, these could be handled via callbacks. */ | 404 | /* TODO: If this were a library, these could be handled via callbacks. */ |
405 | /* TODO: Handle app's configured proxies and these via the same mechanism. */ | ||
406 | const iString *host = collect_String(newRange_String(url.host)); | ||
407 | uint16_t port = toInt_String(collect_String(newRange_String(url.port))); | ||
405 | if (equalCase_Rangecc(url.scheme, "about")) { | 408 | if (equalCase_Rangecc(url.scheme, "about")) { |
406 | const iBlock *src = aboutPageSource_(url.path); | 409 | const iBlock *src = aboutPageSource_(url.path); |
407 | if (src) { | 410 | if (src) { |
@@ -487,6 +490,19 @@ void submit_GmRequest(iGmRequest *d) { | |||
487 | iNotifyAudience(d, finished, GmRequestFinished); | 490 | iNotifyAudience(d, finished, GmRequestFinished); |
488 | return; | 491 | return; |
489 | } | 492 | } |
493 | else if (schemeProxy_App(url.scheme)) { | ||
494 | /* User has configured a proxy server for this scheme. */ | ||
495 | const iString *proxy = schemeProxy_App(url.scheme); | ||
496 | if (contains_String(proxy, ':')) { | ||
497 | const size_t cpos = indexOf_String(proxy, ':'); | ||
498 | port = atoi(cstr_String(proxy) + cpos + 1); | ||
499 | host = collect_String(newCStrN_String(cstr_String(proxy), cpos)); | ||
500 | } | ||
501 | else { | ||
502 | host = proxy; | ||
503 | port = 0; | ||
504 | } | ||
505 | } | ||
490 | d->state = receivingHeader_GmRequestState; | 506 | d->state = receivingHeader_GmRequestState; |
491 | d->req = new_TlsRequest(); | 507 | d->req = new_TlsRequest(); |
492 | const iGmIdentity *identity = identityForUrl_GmCerts(d->certs, &d->url); | 508 | const iGmIdentity *identity = identityForUrl_GmCerts(d->certs, &d->url); |
@@ -495,11 +511,10 @@ void submit_GmRequest(iGmRequest *d) { | |||
495 | } | 511 | } |
496 | iConnect(TlsRequest, d->req, readyRead, d, readIncoming_GmRequest_); | 512 | iConnect(TlsRequest, d->req, readyRead, d, readIncoming_GmRequest_); |
497 | iConnect(TlsRequest, d->req, finished, d, requestFinished_GmRequest_); | 513 | iConnect(TlsRequest, d->req, finished, d, requestFinished_GmRequest_); |
498 | uint16_t port = toInt_String(collect_String(newRange_String(url.port))); | ||
499 | if (port == 0) { | 514 | if (port == 0) { |
500 | port = 1965; /* default Gemini port */ | 515 | port = 1965; /* default Gemini port */ |
501 | } | 516 | } |
502 | setUrl_TlsRequest(d->req, collect_String(newRange_String(url.host)), port); | 517 | setUrl_TlsRequest(d->req, host, port); |
503 | setContent_TlsRequest(d->req, | 518 | setContent_TlsRequest(d->req, |
504 | utf8_String(collectNewFormat_String("%s\r\n", cstr_String(&d->url)))); | 519 | utf8_String(collectNewFormat_String("%s\r\n", cstr_String(&d->url)))); |
505 | submit_TlsRequest(d->req); | 520 | submit_TlsRequest(d->req); |
diff --git a/src/ui/util.c b/src/ui/util.c index 6aa6ccc9..dfe364a5 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -755,8 +755,18 @@ iWidget *makePreferences_Widget(void) { | |||
755 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.retainwindow"))); | 755 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.retainwindow"))); |
756 | addChild_Widget(headings, iClob(makeHeading_Widget("UI scale factor:"))); | 756 | addChild_Widget(headings, iClob(makeHeading_Widget("UI scale factor:"))); |
757 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(8))), "prefs.uiscale"); | 757 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(8))), "prefs.uiscale"); |
758 | addChild_Widget(headings, iClob(makeHeading_Widget(uiHeading_ColorEscape "Proxies"))); | ||
759 | addChild_Widget(values, iClob(makeHeading_Widget(""))); | ||
760 | addChild_Widget(headings, iClob(makeHeading_Widget("HTTP proxy:"))); | ||
761 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.http"); | ||
762 | addChild_Widget(headings, iClob(makeHeading_Widget("Gopher proxy:"))); | ||
763 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.gopher"); | ||
758 | arrange_Widget(dlg); | 764 | arrange_Widget(dlg); |
759 | // as_Widget(songDir)->rect.size.x = dlg->rect.size.x - headings->rect.size.x; | 765 | /* Text input widths. */ { |
766 | const int inputWidth = width_Rect(page->rect) - width_Rect(headings->rect); | ||
767 | as_Widget(findChild_Widget(values, "prefs.proxy.http"))->rect.size.x = inputWidth; | ||
768 | as_Widget(findChild_Widget(values, "prefs.proxy.gopher"))->rect.size.x = inputWidth; | ||
769 | } | ||
760 | iWidget *div = new_Widget(); { | 770 | iWidget *div = new_Widget(); { |
761 | setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | 771 | setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); |
762 | addChild_Widget(div, iClob(new_LabelWidget("Dismiss", SDLK_ESCAPE, 0, "prefs.dismiss"))); | 772 | addChild_Widget(div, iClob(new_LabelWidget("Dismiss", SDLK_ESCAPE, 0, "prefs.dismiss"))); |