summaryrefslogtreecommitdiff
path: root/src/capi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/capi.c')
-rw-r--r--src/capi.c225
1 files changed, 118 insertions, 107 deletions
diff --git a/src/capi.c b/src/capi.c
index 85aef974..8c4a1ae2 100644
--- a/src/capi.c
+++ b/src/capi.c
@@ -16,7 +16,9 @@
*/
#include <string.h>
+#include <errno.h>
+#include "config.h"
#include "msg.h"
#include "capi.h"
#include "IO/IO.h" /* for IORead &friends */
@@ -268,6 +270,7 @@ static int Capi_url_uses_dpi(DilloUrl *url, char **server_ptr)
Dstr *tmp;
if ((dStrnAsciiCasecmp(url_str, "http:", 5) == 0) ||
+ (dStrnAsciiCasecmp(url_str, "https:", 6) == 0) ||
(dStrnAsciiCasecmp(url_str, "about:", 6) == 0)) {
/* URL doesn't use dpi (server = NULL) */
} else if (dStrnAsciiCasecmp(url_str, "dpi:/", 5) == 0) {
@@ -298,39 +301,7 @@ static char *Capi_dpi_build_cmd(DilloWeb *web, char *server)
{
char *cmd;
- if (strcmp(server, "proto.https") == 0) {
- /* Let's be kind and make the HTTP query string for the dpi */
- char *proxy_connect = a_Http_make_connect_str(web->url);
- Dstr *http_query = a_Http_make_query_str(web->url, web->requester,
- web->flags, FALSE);
-
- if ((uint_t) http_query->len > strlen(http_query->str)) {
- /* Can't handle NULLs embedded in query data */
- MSG_ERR("HTTPS query truncated!\n");
- }
-
- /* BUG: WORKAROUND: request to only check the root URL's certificate.
- * This avoids the dialog bombing that stems from loading multiple
- * https images/resources in a single page. A proper fix would take
- * either to implement the https-dpi as a server (with state),
- * or to move back https handling into dillo. */
- if (proxy_connect) {
- const char *proxy_urlstr = a_Http_get_proxy_urlstr();
- cmd = a_Dpip_build_cmd("cmd=%s proxy_url=%s proxy_connect=%s "
- "url=%s query=%s check_cert=%s",
- "open_url", proxy_urlstr,
- proxy_connect, URL_STR(web->url),
- http_query->str,
- (web->flags & WEB_RootUrl) ? "true" : "false");
- } else {
- cmd = a_Dpip_build_cmd("cmd=%s url=%s query=%s check_cert=%s",
- "open_url", URL_STR(web->url),http_query->str,
- (web->flags & WEB_RootUrl) ? "true" : "false");
- }
- dFree(proxy_connect);
- dStr_free(http_query, 1);
-
- } else if (strcmp(server, "downloads") == 0) {
+ if (strcmp(server, "downloads") == 0) {
/* let the downloads server get it */
cmd = a_Dpip_build_cmd("cmd=%s url=%s destination=%s",
"download", URL_STR(web->url), web->filename);
@@ -345,7 +316,7 @@ static char *Capi_dpi_build_cmd(DilloWeb *web, char *server)
/*
* Send the requested URL's source to the "view source" dpi
*/
-static void Capi_dpi_send_source(BrowserWindow *bw, DilloUrl *url)
+static void Capi_dpi_send_source(BrowserWindow *bw, DilloUrl *url)
{
char *p, *buf, *cmd, size_str[32], *server="vsource";
int buf_size;
@@ -385,81 +356,92 @@ int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData)
int safe = 0, ret = 0, use_cache = 0;
/* web->requester is NULL if the action is initiated by user */
- if (!(a_Capi_get_flags(web->url) & CAPI_IsCached ||
- web->requester == NULL ||
- a_Domain_permit(web->requester, web->url))) {
- return 0;
- }
-
- /* reload test */
- reload = (!(a_Capi_get_flags(web->url) & CAPI_IsCached) ||
- (URL_FLAGS(web->url) & URL_E2EQuery));
-
- if (web->flags & WEB_Download) {
- /* download request: if cached save from cache, else
- * for http, ftp or https, use the downloads dpi */
- if (a_Capi_get_flags_with_redirection(web->url) & CAPI_IsCached) {
- if (web->filename) {
- if ((web->stream = fopen(web->filename, "w"))) {
- use_cache = 1;
- } else {
- MSG_WARN("Cannot open \"%s\" for writing.\n", web->filename);
+ if (a_Capi_get_flags(web->url) & CAPI_IsCached ||
+ web->requester == NULL ||
+ a_Domain_permit(web->requester, web->url)) {
+
+ /* reload test */
+ reload = (!(a_Capi_get_flags(web->url) & CAPI_IsCached) ||
+ (URL_FLAGS(web->url) & URL_E2EQuery));
+
+ if (web->flags & WEB_Download) {
+ /* download request: if cached save from cache, else
+ * for http, ftp or https, use the downloads dpi */
+ if (a_Capi_get_flags_with_redirection(web->url) & CAPI_IsCached) {
+ if (web->filename) {
+ if ((web->stream = fopen(web->filename, "w"))) {
+ use_cache = 1;
+ } else {
+ MSG_WARN("Cannot open \"%s\" for writing: %s.\n",
+ web->filename, dStrerror(errno));
+ }
}
+ } else if (a_Cache_download_enabled(web->url)) {
+ server = "downloads";
+ cmd = Capi_dpi_build_cmd(web, server);
+ a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
+ dFree(cmd);
+ } else {
+ MSG_WARN("Ignoring download request for '%s': "
+ "not in cache and not downloadable.\n",
+ URL_STR(web->url));
}
- } else if (a_Cache_download_enabled(web->url)) {
- server = "downloads";
- cmd = Capi_dpi_build_cmd(web, server);
- a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
- dFree(cmd);
- } else {
- MSG_WARN("Ignoring download request for '%s': "
- "not in cache and not downloadable.\n",
- URL_STR(web->url));
- }
-
- } else if (Capi_url_uses_dpi(web->url, &server)) {
- /* dpi request */
- if ((safe = a_Capi_dpi_verify_request(web->bw, web->url))) {
- if (dStrAsciiCasecmp(scheme, "dpi") == 0) {
- if (strcmp(server, "vsource") == 0) {
- /* allow "view source" reload upon user request */
- } else {
- /* make the other "dpi:/" prefixed urls always reload. */
- a_Url_set_flags(web->url, URL_FLAGS(web->url) | URL_E2EQuery);
- reload = 1;
+
+ } else if (Capi_url_uses_dpi(web->url, &server)) {
+ /* dpi request */
+ if ((safe = a_Capi_dpi_verify_request(web->bw, web->url))) {
+ if (dStrAsciiCasecmp(scheme, "dpi") == 0) {
+ if (strcmp(server, "vsource") == 0) {
+ /* allow "view source" reload upon user request */
+ } else {
+ /* make the other "dpi:/" prefixed urls always reload. */
+ a_Url_set_flags(web->url, URL_FLAGS(web->url) |URL_E2EQuery);
+ reload = 1;
+ }
+ }
+ if (reload) {
+ a_Capi_conn_abort_by_url(web->url);
+ /* Send dpip command */
+ _MSG("a_Capi_open_url, reload url='%s'\n", URL_STR(web->url));
+ cmd = Capi_dpi_build_cmd(web, server);
+ a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
+ dFree(cmd);
+ if (strcmp(server, "vsource") == 0) {
+ Capi_dpi_send_source(web->bw, web->url);
+ }
}
+ use_cache = 1;
}
+ dFree(server);
+
+ } else if (!dStrAsciiCasecmp(scheme, "http") ||
+ !dStrAsciiCasecmp(scheme, "https")) {
+ /* http request */
+
+#ifndef ENABLE_SSL
+ if (!dStrAsciiCasecmp(scheme, "https")) {
+ if (web->flags & WEB_RootUrl)
+ a_UIcmd_set_msg(web->bw,
+ "HTTPS was disabled at compilation time");
+ a_Web_free(web);
+ return 0;
+ }
+#endif
if (reload) {
a_Capi_conn_abort_by_url(web->url);
- /* Send dpip command */
- _MSG("a_Capi_open_url, reload url='%s'\n", URL_STR(web->url));
- cmd = Capi_dpi_build_cmd(web, server);
- a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
- dFree(cmd);
- if (strcmp(server, "vsource") == 0) {
- Capi_dpi_send_source(web->bw, web->url);
- }
+ /* create a new connection and start the CCC operations */
+ conn = Capi_conn_new(web->url, web->bw, "http", "none");
+ /* start the reception branch before the query one because the DNS
+ * may callback immediately. This may avoid a race condition. */
+ a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, "http");
+ a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, web);
}
use_cache = 1;
- }
- dFree(server);
-
- } else if (!dStrAsciiCasecmp(scheme, "http")) {
- /* http request */
- if (reload) {
- a_Capi_conn_abort_by_url(web->url);
- /* create a new connection and start the CCC operations */
- conn = Capi_conn_new(web->url, web->bw, "http", "none");
- /* start the reception branch before the query one because the DNS
- * may callback immediately. This may avoid a race condition. */
- a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, "http");
- a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, web);
- }
- use_cache = 1;
- } else if (!dStrAsciiCasecmp(scheme, "about")) {
- /* internal request */
- use_cache = 1;
+ } else if (!dStrAsciiCasecmp(scheme, "about")) {
+ /* internal request */
+ use_cache = 1;
+ }
}
if (use_cache) {
@@ -632,7 +614,8 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
Capi_conn_ref(conn);
Info->LocalKey = conn;
conn->InfoSend = Info;
- if (strcmp(conn->server, "http") == 0) {
+ if (strcmp(conn->server, "http") == 0 ||
+ strcmp(conn->server, "https") == 0) {
a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Http_ccc, 1, 1);
a_Chain_bcb(OpStart, Info, Data2, NULL);
} else {
@@ -659,7 +642,7 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
dFree(Info);
break;
default:
- MSG_WARN("Unused CCC\n");
+ MSG_WARN("Unused CCC Capi 1B\n");
break;
}
} else { /* 1 FWD */
@@ -681,6 +664,7 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
case OpAbort:
conn = Info->LocalKey;
conn->InfoSend = NULL;
+ a_Cache_process_dbuf(IOAbort, NULL, 0, conn->url);
if (Data2) {
if (!strcmp(Data2, "DpidERROR")) {
a_UIcmd_set_msg(conn->bw,
@@ -699,7 +683,7 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
dFree(Info);
break;
default:
- MSG_WARN("Unused CCC\n");
+ MSG_WARN("Unused CCC Capi 1F\n");
break;
}
}
@@ -714,7 +698,10 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
Capi_conn_ref(conn);
Info->LocalKey = conn;
conn->InfoRecv = Info;
- a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Dpi_ccc, 2, 2);
+ if (strcmp(conn->server, "http") == 0)
+ a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Http_ccc, 2, 2);
+ else
+ a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Dpi_ccc, 2, 2);
a_Chain_bcb(OpStart, Info, NULL, Data2);
break;
case OpSend:
@@ -733,7 +720,7 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
dFree(Info);
break;
default:
- MSG_WARN("Unused CCC\n");
+ MSG_WARN("Unused CCC Capi 2B\n");
break;
}
} else { /* 2 FWD */
@@ -744,7 +731,15 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
if (strcmp(Data2, "send_page_2eof") == 0) {
/* Data1 = dbuf */
DataBuf *dbuf = Data1;
- a_Cache_process_dbuf(IORead, dbuf->Buf, dbuf->Size, conn->url);
+ bool_t finished = a_Cache_process_dbuf(IORead, dbuf->Buf,
+ dbuf->Size, conn->url);
+ if (finished && Capi_conn_valid(conn) && conn->InfoRecv) {
+ /* If we have a persistent connection where cache tells us
+ * that we've received the full response, and cache didn't
+ * trigger an abort and tear everything down, tell upstream.
+ */
+ a_Chain_bcb(OpSend, conn->InfoRecv, NULL, "reply_complete");
+ }
} else if (strcmp(Data2, "send_status_message") == 0) {
a_UIcmd_set_msg(conn->bw, "%s", Data1);
} else if (strcmp(Data2, "chat") == 0) {
@@ -775,8 +770,24 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
Capi_conn_unref(conn);
dFree(Info);
break;
+ case OpAbort:
+ conn = Info->LocalKey;
+ conn->InfoRecv = NULL;
+ a_Cache_process_dbuf(IOAbort, NULL, 0, conn->url);
+ if (Data2) {
+ if (!strcmp(Data2, "Both") && conn->InfoSend) {
+ /* abort the other branch too */
+ a_Capi_ccc(OpAbort, 1, BCK, conn->InfoSend, NULL, NULL);
+ }
+ }
+ /* if URL == expect-url */
+ a_Nav_cancel_expect_if_eq(conn->bw, conn->url);
+ /* finish conn */
+ Capi_conn_unref(conn);
+ dFree(Info);
+ break;
default:
- MSG_WARN("Unused CCC\n");
+ MSG_WARN("Unused CCC Capi 2F\n");
break;
}
}