Dillo v3.1.1-91-g6d5b3ee3
Loading...
Searching...
No Matches
capi.c
Go to the documentation of this file.
1/*
2 * File: capi.c
3 *
4 * Copyright 2002-2007 Jorge Arellano Cid <jcid@dillo.org>
5 * Copyright 2023 Rodrigo Arias Mallo <rodarima@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 */
12
20#include <string.h>
21#include <errno.h>
22
23#include "config.h"
24#include "msg.h"
25#include "capi.h"
26#include "IO/IO.h" /* for IORead &friends */
27#include "IO/Url.h"
28#include "chain.h"
29#include "history.h"
30#include "nav.h"
31#include "dpiapi.h"
32#include "uicmd.hh"
33#include "domain.h"
34#include "../dpip/dpip.h"
35
36/* for testing dpi chat */
37#include "bookmark.h"
38
39typedef struct {
40 DilloUrl *url;
41 void *bw;
42 char *server;
43 char *datastr;
44 int SockFD;
45 int Flags;
46 ChainLink *InfoSend;
47 ChainLink *InfoRecv;
48
49 int Ref;
50} capi_conn_t;
51
53enum {
55 TIMEOUT = 2, /* unused */
56 ABORTED = 4
57};
58
59/*
60 * Local data
61 */
63static Dlist *CapiConns; /* Data list for active connections; it holds
64 * pointers to capi_conn_t structures. */
66static DilloUrl *CapiVsUrl = NULL;
67
68/*
69 * Forward declarations
70 */
71void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
72 void *Data1, void *Data2);
73
74
75/* ------------------------------------------------------------------------- */
76
80void a_Capi_init(void)
81{
82 /* create an empty list */
83 CapiConns = dList_new(32);
84 /* init cache */
86}
87
88/* ------------------------------------------------------------------------- */
89
93static capi_conn_t *
94 Capi_conn_new(const DilloUrl *url, void *bw, char *server, char *datastr)
95{
96 capi_conn_t *conn;
97
98 conn = dNew(capi_conn_t, 1);
99 conn->url = url ? a_Url_dup(url) : NULL;
100 conn->bw = bw;
101 conn->server = dStrdup(server);
102 conn->datastr = dStrdup(datastr);
103 conn->SockFD = -1;
104 conn->Flags = (strcmp(server, "http") != 0) ? PENDING : 0;
105 conn->InfoSend = NULL;
106 conn->InfoRecv = NULL;
107 conn->Ref = 0; /* Reference count */
108 return conn;
109}
110
115static capi_conn_t *Capi_conn_valid(capi_conn_t *conn)
116{
117 return dList_find(CapiConns, conn);
118}
119
123static void Capi_conn_ref(capi_conn_t *conn)
124{
125 if (++conn->Ref == 1) {
126 /* add the connection data to list */
127 dList_append(CapiConns, (void *)conn);
128 }
129 _MSG(" Capi_conn_ref #%d %p\n", conn->Ref, conn);
130}
131
135static void Capi_conn_unref(capi_conn_t *conn)
136{
137 _MSG(" Capi_conn_unref #%d %p\n", conn->Ref - 1, conn);
138
139 /* We may validate conn here, but it doesn't *seem* necessary */
140 if (--conn->Ref == 0) {
141 /* remove conn preserving the list order */
142 dList_remove(CapiConns, (void *)conn);
143 /* free dynamic memory */
144 a_Url_free(conn->url);
145 dFree(conn->server);
146 dFree(conn->datastr);
147 dFree(conn);
148 }
149 _MSG(" Capi_conn_unref CapiConns=%d\n", dList_length(CapiConns));
150}
151
155static int Capi_conn_by_server_cmp(const void *v1, const void *v2)
156{
157 const capi_conn_t *node = v1;
158 const char *server = v2;
159 dReturn_val_if_fail(node && node->server && server, 1);
160 return strcmp(node->server, server);
161}
162
166static capi_conn_t *Capi_conn_find(char *server)
167{
169}
170
174static void Capi_conn_resume(void)
175{
176 int i;
177 DataBuf *dbuf;
178 capi_conn_t *conn;
179
180 for (i = 0; i < dList_length(CapiConns); ++i) {
181 conn = dList_nth_data (CapiConns, i);
182 if (conn->Flags & PENDING) {
183 dbuf = a_Chain_dbuf_new(conn->datastr,(int)strlen(conn->datastr), 0);
184 if (conn->InfoSend) {
185 a_Capi_ccc(OpSend, 1, BCK, conn->InfoSend, dbuf, NULL);
186 }
187 dFree(dbuf);
188 conn->Flags &= ~PENDING;
189 }
190 }
191}
192
200{
201 int i;
202 capi_conn_t *conn;
203
204 for (i = 0; i < dList_length(CapiConns); ++i) {
205 conn = dList_nth_data (CapiConns, i);
206 if (a_Url_cmp(conn->url, url) == 0) {
207 if (conn->InfoSend) {
208 a_Capi_ccc(OpAbort, 1, BCK, conn->InfoSend, NULL, NULL);
209 }
210 if (conn->InfoRecv) {
211 a_Capi_ccc(OpAbort, 2, BCK, conn->InfoRecv, NULL, NULL);
212 }
213 break;
214 }
215 }
216}
217
218/* ------------------------------------------------------------------------- */
219
224{
226 CapiVsUrl = a_Url_dup(url);
227}
228
233{
234 const DilloUrl *referer;
235 int allow = FALSE;
236
237 if (dStrAsciiCasecmp(URL_SCHEME(url), "dpi") == 0) {
238 if (!(URL_FLAGS(url) & (URL_Post + URL_Get))) {
239 allow = TRUE;
240 } else if (!(URL_FLAGS(url) & URL_Post) &&
241 strncmp(URL_PATH(url), "/vsource/", 9) == 0) {
242 allow = TRUE;
243 } else {
244 /* only allow GET&POST dpi-requests from dpi-generated urls */
245 if (a_Nav_stack_size(bw)) {
246 referer = a_History_get_url(NAV_TOP_UIDX(bw));
247 if (dStrAsciiCasecmp(URL_SCHEME(referer), "dpi") == 0) {
248 allow = TRUE;
249 }
250 }
251 }
252 } else {
253 allow = TRUE;
254 }
255
256 if (!allow) {
257 MSG("a_Capi_dpi_verify_request: Permission Denied!\n");
258 MSG(" URL_STR : %s\n", URL_STR(url));
259 if (URL_FLAGS(url) & URL_Post) {
260 MSG(" URL_DATA: %s\n", dStr_printable(URL_DATA(url), 1024));
261 }
262 }
263 return allow;
264}
265
269static int Capi_url_uses_dpi(DilloUrl *url, char **server_ptr)
270{
271 char *p, *server = NULL, *url_str = URL_STR(url);
272 Dstr *tmp;
273
274 if ((dStrnAsciiCasecmp(url_str, "http:", 5) == 0) ||
275 (dStrnAsciiCasecmp(url_str, "https:", 6) == 0) ||
276 (dStrnAsciiCasecmp(url_str, "about:", 6) == 0)) {
277 /* URL doesn't use dpi (server = NULL) */
278 } else if (dStrnAsciiCasecmp(url_str, "dpi:/", 5) == 0) {
279 /* dpi prefix, get this server's name */
280 if ((p = strchr(url_str + 5, '/')) != NULL) {
281 server = dStrndup(url_str + 5, (uint_t)(p - url_str - 5));
282 } else {
283 server = dStrdup("?");
284 }
285 if (strcmp(server, "bm") == 0) {
286 dFree(server);
287 server = dStrdup("bookmarks");
288 }
289 } else if ((p = strchr(url_str, ':')) != NULL) {
290 tmp = dStr_new("proto.");
291 dStr_append_l(tmp, url_str, p - url_str);
292 server = tmp->str;
293 dStr_free(tmp, 0);
294 }
295
296 return ((*server_ptr = server) ? 1 : 0);
297}
298
302static char *Capi_dpi_build_cmd(DilloWeb *web, char *server)
303{
304 char *cmd;
305
306 if (strcmp(server, "downloads") == 0) {
307 /* let the downloads server get it */
308 cmd = a_Dpip_build_cmd("cmd=%s url=%s destination=%s",
309 "download", URL_STR(web->url), web->filename);
310
311 } else {
312 /* For everyone else, the url string is enough... */
313 cmd = a_Dpip_build_cmd("cmd=%s url=%s", "open_url", URL_STR(web->url));
314 }
315 return cmd;
316}
317
322{
323 char *p, *buf, *cmd, size_str[32], *server="vsource";
324 int buf_size;
325
326 if (!(p = strchr(URL_STR(url), ':')) || !(p = strchr(p + 1, ':')))
327 return;
328
329 if (a_Capi_get_buf(CapiVsUrl, &buf, &buf_size)) {
330 /* send the page's source to this dpi connection */
331 snprintf(size_str, 32, "%d", buf_size);
332 cmd = a_Dpip_build_cmd("cmd=%s url=%s data_size=%s",
333 "start_send_page", URL_STR(url), size_str);
334 a_Capi_dpi_send_cmd(NULL, bw, cmd, server, 0);
335 a_Capi_dpi_send_data(url, bw, buf, buf_size, server, 0);
336 } else {
337 cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
338 "DpiError", "Page is NOT cached");
339 a_Capi_dpi_send_cmd(NULL, bw, cmd, server, 0);
340 }
341 dFree(cmd);
342}
343
348{
349 bool_t permit = FALSE;
350
351 /* web->requester is NULL if the action is initiated by user */
352 if (!web->requester)
353 return TRUE;
354
355 if (web->flags & ~WEB_RootUrl &&
356 !dStrAsciiCasecmp(URL_SCHEME(web->requester), "https")) {
357 const char *s = URL_SCHEME(web->url);
358
359 /* As of 2015, blocking of "active" mixed content is widespread
360 * (style sheets, javascript, fonts, etc.), but the big browsers aren't
361 * quite in a position to block "passive" mixed content (images) yet.
362 * (Not clear whether there's consensus on which category to place
363 * background images in.)
364 *
365 * We are blocking both, and only permitting secure->insecure page
366 * redirection for now (e.g., duckduckgo has been seen providing links
367 * to https URLs that redirect to http). As the web security landscape
368 * evolves, we may be able to remove that permission.
369 */
370 if (dStrAsciiCasecmp(s, "https") && dStrAsciiCasecmp(s, "data")) {
371 MSG("capi: Blocked mixed content: %s -> %s\n",
372 URL_STR(web->requester), URL_STR(web->url));
373 return FALSE;
374 }
375 }
376
377 if (a_Capi_get_flags(web->url) & CAPI_IsCached ||
378 a_Domain_permit(web->requester, web->url)) {
379 permit = TRUE;
380 }
381 return permit;
382}
383
392int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData)
393{
394 int reload;
395 char *cmd, *server;
396 capi_conn_t *conn = NULL;
397 const char *scheme = URL_SCHEME(web->url);
398 int safe = 0, ret = 0, use_cache = 0;
399
400 if (Capi_request_permitted(web)) {
401 /* reload test */
402 reload = (!(a_Capi_get_flags(web->url) & CAPI_IsCached) ||
403 (URL_FLAGS(web->url) & URL_E2EQuery));
404
405 if (web->flags & WEB_Download) {
406 /* download request: if cached save from cache, else
407 * for http, ftp or https, use the downloads dpi */
409 if (web->filename) {
410 if ((web->stream = fopen(web->filename, "w"))) {
411 use_cache = 1;
412 } else {
413 MSG_WARN("Cannot open \"%s\" for writing: %s.\n",
414 web->filename, dStrerror(errno));
415 }
416 }
417 } else if (a_Cache_download_enabled(web->url)) {
418 server = "downloads";
419 cmd = Capi_dpi_build_cmd(web, server);
420 a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
421 dFree(cmd);
422 } else {
423 MSG_WARN("Ignoring download request for '%s': "
424 "not in cache and not downloadable.\n",
425 URL_STR(web->url));
426 }
427
428 } else if (Capi_url_uses_dpi(web->url, &server)) {
429 /* dpi request */
430 if ((safe = a_Capi_dpi_verify_request(web->bw, web->url))) {
431 if (dStrAsciiCasecmp(scheme, "dpi") == 0) {
432 if (strcmp(server, "vsource") == 0) {
433 /* allow "view source" reload upon user request */
434 } else {
435 /* make the other "dpi:/" prefixed urls always reload. */
437 reload = 1;
438 }
439 }
440 if (reload) {
442 /* Send dpip command */
443 _MSG("a_Capi_open_url, reload url='%s'\n", URL_STR(web->url));
444 cmd = Capi_dpi_build_cmd(web, server);
445 a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
446 dFree(cmd);
447 if (strcmp(server, "vsource") == 0) {
448 Capi_dpi_send_source(web->bw, web->url);
449 }
450 }
451 use_cache = 1;
452 }
453 dFree(server);
454
455 } else if (!dStrAsciiCasecmp(scheme, "http") ||
456 !dStrAsciiCasecmp(scheme, "https")) {
457 /* http request */
458
459#ifndef ENABLE_TLS
460 if (!dStrAsciiCasecmp(scheme, "https")) {
461 if (web->flags & WEB_RootUrl)
462 a_UIcmd_set_msg(web->bw,
463 "HTTPS was disabled at compilation time.");
464 a_Web_free(web);
465 return 0;
466 }
467#endif
468 if (reload) {
470 /* create a new connection and start the CCC operations */
471 conn = Capi_conn_new(web->url, web->bw, "http", "none");
472 /* start the reception branch before the query one because the DNS
473 * may callback immediately. This may avoid a race condition. */
474 a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, "http");
475 a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, web);
476 }
477 use_cache = 1;
478
479 } else if (!dStrAsciiCasecmp(scheme, "about")) {
480 /* internal request */
481 use_cache = 1;
482 }
483 }
484
485 if (use_cache) {
486 if (!conn || (conn && Capi_conn_valid(conn))) {
487 /* not aborted, let's continue... */
488 ret = a_Cache_open_url(web, Call, CbData);
489 }
490 } else {
491 a_Web_free(web);
492 }
493 return ret;
494}
495
500{
501 int status = 0;
502
503 if (flags) {
504 status |= CAPI_IsCached;
505 if (flags & CA_IsEmpty)
506 status |= CAPI_IsEmpty;
507 if (flags & CA_InProgress)
508 status |= CAPI_InProgress;
509 else
510 status |= CAPI_Completed;
511
512 /* CAPI_Aborted is not yet used/defined */
513 }
514 return status;
515}
516
521{
522 uint_t flags = a_Cache_get_flags(Url);
523 int status = flags ? Capi_map_cache_flags(flags) : 0;
524 return status;
525}
526
531{
533 int status = flags ? Capi_map_cache_flags(flags) : 0;
534 return status;
535}
536
541int a_Capi_get_buf(const DilloUrl *Url, char **PBuf, int *BufSize)
542{
543 return a_Cache_get_buf(Url, PBuf, BufSize);
544}
545
550{
552}
553
557const char *a_Capi_get_content_type(const DilloUrl *url)
558{
559 return a_Cache_get_content_type(url);
560}
561
565const char *a_Capi_set_content_type(const DilloUrl *url, const char *ctype,
566 const char *from)
567{
568 return a_Cache_set_content_type(url, ctype, from);
569}
570
576int a_Capi_dpi_send_data(const DilloUrl *url, void *bw,
577 char *data, int data_sz, char *server, int flags)
578{
579 capi_conn_t *conn;
580 DataBuf *dbuf;
581
582 if (flags & 1) {
583 /* open a new connection to server */
584
585 /* Create a new connection data struct and add it to the list */
586 conn = Capi_conn_new(url, bw, server, data);
587 /* start the CCC operations */
588 a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, server);
589 a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, server);
590
591 } else {
592 /* Re-use an open connection */
593 conn = Capi_conn_find(server);
594 if (conn && conn->InfoSend) {
595 /* found & active */
596 dbuf = a_Chain_dbuf_new(data, data_sz, 0);
597 a_Capi_ccc(OpSend, 1, BCK, conn->InfoSend, dbuf, NULL);
598 dFree(dbuf);
599 } else {
600 MSG(" ERROR: [a_Capi_dpi_send_data] No open connection found\n");
601 }
602 }
603
604 return 0;
605}
606
611int a_Capi_dpi_send_cmd(DilloUrl *url, void *bw, char *cmd, char *server,
612 int flags)
613{
614 return a_Capi_dpi_send_data(url, bw, cmd, strlen(cmd), server, flags);
615}
616
621void a_Capi_stop_client(int Key, int force)
622{
623 CacheClient_t *Client;
624
625 _MSG("a_Capi_stop_client: force=%d\n", force);
626
627 Client = a_Cache_client_get_if_unique(Key);
628 if (Client && (force || Client->BufSize == 0)) {
629 /* remove empty entries too */
631 }
633}
634
638void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
639 void *Data1, void *Data2)
640{
641 capi_conn_t *conn;
642
643 dReturn_if_fail( a_Chain_check("a_Capi_ccc", Op, Branch, Dir, Info) );
644
645 if (Branch == 1) {
646 if (Dir == BCK) {
647 /* Command sending branch */
648 switch (Op) {
649 case OpStart:
650 /* Data1 = conn; Data2 = {Web | server} */
651 conn = Data1;
652 Capi_conn_ref(conn);
653 Info->LocalKey = conn;
654 conn->InfoSend = Info;
655 if (strcmp(conn->server, "http") == 0 ||
656 strcmp(conn->server, "https") == 0) {
658 a_Chain_bcb(OpStart, Info, Data2, NULL);
659 } else {
661 a_Chain_bcb(OpStart, Info, Data2, NULL);
662 }
663 break;
664 case OpSend:
665 /* Data1 = dbuf */
666 a_Chain_bcb(OpSend, Info, Data1, NULL);
667 break;
668 case OpEnd:
669 conn = Info->LocalKey;
670 conn->InfoSend = NULL;
671 a_Chain_bcb(OpEnd, Info, NULL, NULL);
672 Capi_conn_unref(conn);
673 dFree(Info);
674 break;
675 case OpAbort:
676 conn = Info->LocalKey;
677 conn->InfoSend = NULL;
678 a_Chain_bcb(OpAbort, Info, NULL, NULL);
679 Capi_conn_unref(conn);
680 dFree(Info);
681 break;
682 default:
683 MSG_WARN("Unused CCC Capi 1B\n");
684 break;
685 }
686 } else { /* 1 FWD */
687 /* Command sending branch (status) */
688 switch (Op) {
689 case OpSend:
690 if (!Data2) {
691 MSG_WARN("Capi.c: Opsend [1F] Data2 = NULL\n");
692 } else if (strcmp(Data2, "FD") == 0) {
693 conn = Info->LocalKey;
694 conn->SockFD = *(int*)Data1;
695 /* communicate the FD through the answer branch */
696 a_Capi_ccc(OpSend, 2, BCK, conn->InfoRecv, &conn->SockFD, "FD");
697 } else if (strcmp(Data2, "DpidOK") == 0) {
698 /* resume pending dpi requests */
700 }
701 break;
702 case OpAbort:
703 conn = Info->LocalKey;
704 conn->InfoSend = NULL;
705 a_Cache_process_dbuf(IOAbort, NULL, 0, conn->url);
706 if (Data2) {
707 if (!strcmp(Data2, "DpidERROR")) {
708 a_UIcmd_set_msg(conn->bw,
709 "ERROR: can't start dpid daemon "
710 "(URL scheme = '%s')!",
711 conn->url ? URL_SCHEME(conn->url) : "");
712 } else if (!strcmp(Data2, "Both") && conn->InfoRecv) {
713 /* abort the other branch too */
714 a_Capi_ccc(OpAbort, 2, BCK, conn->InfoRecv, NULL, NULL);
715 }
716 }
717 /* if URL == expect-url */
718 a_Nav_cancel_expect_if_eq(conn->bw, conn->url);
719 /* finish conn */
720 Capi_conn_unref(conn);
721 dFree(Info);
722 break;
723 default:
724 MSG_WARN("Unused CCC Capi 1F\n");
725 break;
726 }
727 }
728
729 } else if (Branch == 2) {
730 if (Dir == BCK) {
731 /* Answer branch */
732 switch (Op) {
733 case OpStart:
734 /* Data1 = conn; Data2 = {"http" | "<dpi server name>"} */
735 conn = Data1;
736 Capi_conn_ref(conn);
737 Info->LocalKey = conn;
738 conn->InfoRecv = Info;
739 if (strcmp(conn->server, "http") == 0)
741 else
743 a_Chain_bcb(OpStart, Info, NULL, Data2);
744 break;
745 case OpSend:
746 /* Data1 = FD */
747 if (Data2 && strcmp(Data2, "FD") == 0) {
748 a_Chain_bcb(OpSend, Info, Data1, Data2);
749 }
750 break;
751 case OpAbort:
752 conn = Info->LocalKey;
753 conn->InfoRecv = NULL;
754 a_Chain_bcb(OpAbort, Info, NULL, NULL);
755 /* remove the cache entry for this URL */
757 Capi_conn_unref(conn);
758 dFree(Info);
759 break;
760 default:
761 MSG_WARN("Unused CCC Capi 2B\n");
762 break;
763 }
764 } else { /* 2 FWD */
765 /* Server listening branch */
766 switch (Op) {
767 case OpSend:
768 conn = Info->LocalKey;
769 if (strcmp(Data2, "send_page_2eof") == 0) {
770 /* Data1 = dbuf */
771 DataBuf *dbuf = Data1;
772 bool_t finished = a_Cache_process_dbuf(IORead, dbuf->Buf,
773 dbuf->Size, conn->url);
774 if (finished && Capi_conn_valid(conn) && conn->InfoRecv) {
775 /* If we have a persistent connection where cache tells us
776 * that we've received the full response, and cache didn't
777 * trigger an abort and tear everything down, tell upstream.
778 */
779 a_Chain_bcb(OpSend, conn->InfoRecv, NULL, "reply_complete");
780 }
781 } else if (strcmp(Data2, "send_status_message") == 0) {
782 a_UIcmd_set_msg(conn->bw, "%s", Data1);
783 } else if (strcmp(Data2, "chat") == 0) {
784 a_UIcmd_set_msg(conn->bw, "%s", Data1);
785 a_Bookmarks_chat_add(NULL, NULL, Data1);
786 } else if (strcmp(Data2, "dialog") == 0) {
787 a_Dpiapi_dialog(conn->bw, conn->server, Data1);
788 } else if (strcmp(Data2, "reload_request") == 0) {
789 a_Nav_reload(conn->bw);
790 } else if (strcmp(Data2, "start_send_page") == 0) {
791 /* prepare the cache to receive the data stream for this URL
792 *
793 * a_Capi_open_url() already added a new cache entry,
794 * and a client for it.
795 */
796 }
797 break;
798 case OpEnd:
799 conn = Info->LocalKey;
800 conn->InfoRecv = NULL;
801
802 a_Cache_process_dbuf(IOClose, NULL, 0, conn->url);
803
804 if (conn->InfoSend) {
805 /* Propagate OpEnd to the sending branch too */
806 a_Capi_ccc(OpEnd, 1, BCK, conn->InfoSend, NULL, NULL);
807 }
808 Capi_conn_unref(conn);
809 dFree(Info);
810 break;
811 case OpAbort:
812 conn = Info->LocalKey;
813 conn->InfoRecv = NULL;
814 a_Cache_process_dbuf(IOAbort, NULL, 0, conn->url);
815 if (Data2) {
816 if (!strcmp(Data2, "Both") && conn->InfoSend) {
817 /* abort the other branch too */
818 a_Capi_ccc(OpAbort, 1, BCK, conn->InfoSend, NULL, NULL);
819 }
820 }
821 /* if URL == expect-url */
822 a_Nav_cancel_expect_if_eq(conn->bw, conn->url);
823 /* finish conn */
824 Capi_conn_unref(conn);
825 dFree(Info);
826 break;
827 default:
828 MSG_WARN("Unused CCC Capi 2F\n");
829 break;
830 }
831 }
832 }
833}
#define IORead
Definition IO.h:11
#define IOAbort
Definition IO.h:14
#define IOClose
Definition IO.h:13
void a_Bookmarks_chat_add(BrowserWindow *Bw, char *Cmd, char *answer)
Have a short chat with the bookmarks server, and finally ask it to add a new bookmark.
Definition bookmark.c:27
#define _MSG(...)
Definition bookmarks.c:45
#define MSG(...)
Definition bookmarks.c:46
int a_Cache_get_buf(const DilloUrl *Url, char **PBuf, int *BufSize)
Get the pointer to the URL document, and its size, from the cache entry.
Definition cache.c:552
CacheClient_t * a_Cache_client_get_if_unique(int Key)
Last Client for this entry?
Definition cache.c:1399
uint_t a_Cache_get_flags_with_redirection(const DilloUrl *url)
Get cache entry status (following redirections).
Definition cache.c:415
const char * a_Cache_set_content_type(const DilloUrl *url, const char *ctype, const char *from)
Change Content-Type for cache entry found by url.
Definition cache.c:492
void a_Cache_unref_buf(const DilloUrl *Url)
Unreference the data buffer when no longer using it.
Definition cache.c:571
const char * a_Cache_get_content_type(const DilloUrl *url)
Get current Content-Type for cache entry found by URL.
Definition cache.c:472
void a_Cache_entry_remove_by_url(DilloUrl *url)
Wrapper for capi.
Definition cache.c:357
bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, const DilloUrl *Url)
Receive new data, update the reception buffer (for next read), update the cache, and service the clie...
Definition cache.c:897
int a_Cache_download_enabled(const DilloUrl *url)
Check whether a URL scheme is downloadable.
Definition cache.c:1093
void a_Cache_init(void)
Initialize cache data.
Definition cache.c:118
int a_Cache_open_url(void *web, CA_Callback_t Call, void *CbData)
Try finding the url in the cache.
Definition cache.c:376
uint_t a_Cache_get_flags(const DilloUrl *url)
Get cache entry status.
Definition cache.c:406
void a_Cache_stop_client(int Key)
Remove a client from the client queue TODO: notify the dicache and upper layers.
Definition cache.c:1419
void(* CA_Callback_t)(int Op, CacheClient_t *Client)
Callback type for cache clients.
Definition cache.h:43
#define CA_IsEmpty
Definition cache.h:35
#define CA_InProgress
Definition cache.h:25
static void Capi_conn_resume(void)
Resume connections that were waiting for dpid to start.
Definition capi.c:174
int a_Capi_get_buf(const DilloUrl *Url, char **PBuf, int *BufSize)
Get the cache's buffer for the URL, and its size.
Definition capi.c:541
@ PENDING
Definition capi.c:54
@ ABORTED
Definition capi.c:56
@ TIMEOUT
Definition capi.c:55
static bool_t Capi_request_permitted(DilloWeb *web)
Shall we permit this request to open a URL?
Definition capi.c:347
static void Capi_conn_unref(capi_conn_t *conn)
Decrement the reference count (and remove from list when zero)
Definition capi.c:135
static Dlist * CapiConns
Data list for active dpi connections.
Definition capi.c:63
int a_Capi_dpi_send_cmd(DilloUrl *url, void *bw, char *cmd, char *server, int flags)
Send a dpi cmd.
Definition capi.c:611
const char * a_Capi_set_content_type(const DilloUrl *url, const char *ctype, const char *from)
Set the Content-Type for the URL.
Definition capi.c:565
static char * Capi_dpi_build_cmd(DilloWeb *web, char *server)
Build the dpip command tag, according to URL and server.
Definition capi.c:302
static capi_conn_t * Capi_conn_valid(capi_conn_t *conn)
Validate a capi_conn_t pointer.
Definition capi.c:115
void a_Capi_set_vsource_url(const DilloUrl *url)
Store the last URL requested by "view source".
Definition capi.c:223
static int Capi_conn_by_server_cmp(const void *v1, const void *v2)
Compare function for searching a conn by server string.
Definition capi.c:155
int a_Capi_dpi_verify_request(BrowserWindow *bw, DilloUrl *url)
Safety test: only allow GET|POST dpi-urls from dpi-generated pages.
Definition capi.c:232
static capi_conn_t * Capi_conn_new(const DilloUrl *url, void *bw, char *server, char *datastr)
Create a new connection data structure.
Definition capi.c:94
static DilloUrl * CapiVsUrl
Last URL asked for view source.
Definition capi.c:66
static capi_conn_t * Capi_conn_find(char *server)
Find connection data by server.
Definition capi.c:166
void a_Capi_unref_buf(const DilloUrl *Url)
Unref the cache's buffer when no longer using it.
Definition capi.c:549
static int Capi_url_uses_dpi(DilloUrl *url, char **server_ptr)
If the url belongs to a dpi server, return its name.
Definition capi.c:269
void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2)
CCC function for the CAPI module.
Definition capi.c:638
int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData)
Most used function for requesting a URL.
Definition capi.c:392
int a_Capi_get_flags_with_redirection(const DilloUrl *Url)
Same as a_Capi_get_flags() but following redirections.
Definition capi.c:530
void a_Capi_stop_client(int Key, int force)
Remove a client from the cache client queue.
Definition capi.c:621
static void Capi_conn_ref(capi_conn_t *conn)
Increment the reference count and add to the list if not present.
Definition capi.c:123
static int Capi_map_cache_flags(uint_t flags)
Convert cache-defined flags to Capi ones.
Definition capi.c:499
static void Capi_dpi_send_source(BrowserWindow *bw, DilloUrl *url)
Send the requested URL's source to the "view source" dpi.
Definition capi.c:321
void a_Capi_init(void)
Initialize capi&cache data.
Definition capi.c:80
const char * a_Capi_get_content_type(const DilloUrl *url)
Get the Content-Type associated with the URL.
Definition capi.c:557
int a_Capi_dpi_send_data(const DilloUrl *url, void *bw, char *data, int data_sz, char *server, int flags)
Send data to a dpi (e.g.
Definition capi.c:576
void a_Capi_conn_abort_by_url(const DilloUrl *url)
Abort the connection for a given url, using its CCC.
Definition capi.c:199
int a_Capi_get_flags(const DilloUrl *Url)
Return status information of an URL's content-transfer process.
Definition capi.c:520
#define CAPI_InProgress
Definition capi.h:17
#define CAPI_IsEmpty
Definition capi.h:16
#define CAPI_IsCached
Definition capi.h:15
#define CAPI_Completed
Definition capi.h:19
int a_Chain_bcb(int Op, ChainLink *Info, void *Data1, void *Data2)
Issue the backward callback of the 'Info' link.
Definition chain.c:126
DataBuf * a_Chain_dbuf_new(void *buf, int size, int code)
Allocate and initialize a new DataBuf structure.
Definition chain.c:171
ChainLink * a_Chain_link_new(ChainLink *AInfo, ChainFunction_t AFunc, int Direction, ChainFunction_t BFunc, int AtoB_branch, int BtoA_branch)
Create a new link from module A to module B.
Definition chain.c:55
int a_Chain_check(char *FuncStr, int Op, int Branch, int Dir, ChainLink *Info)
Check whether the CCC is operative.
Definition chain.c:186
ChainLink * a_Chain_new(void)
Create and initialize a new chain-link.
Definition chain.c:42
#define OpAbort
Definition chain.h:17
#define OpStart
Definition chain.h:13
#define BCK
Definition chain.h:30
#define OpSend
Definition chain.h:14
#define OpEnd
Definition chain.h:16
unsigned int uint_t
Definition d_size.h:20
unsigned char bool_t
Definition d_size.h:21
void dFree(void *mem)
Definition dlib.c:68
int dStrAsciiCasecmp(const char *s1, const char *s2)
Definition dlib.c:203
char * dStrdup(const char *s)
Definition dlib.c:77
Dlist * dList_new(int size)
Create a new empty list.
Definition dlib.c:548
int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n)
Definition dlib.c:215
int dList_length(Dlist *lp)
For completing the ADT.
Definition dlib.c:613
void * dList_nth_data(Dlist *lp, int n0)
Return the nth data item, NULL when not found or 'n0' is out of range.
Definition dlib.c:662
void dStr_free(Dstr *ds, int all)
Free a dillo string.
Definition dlib.c:337
void dStr_append_l(Dstr *ds, const char *s, int l)
Append a C string to a Dstr (providing length).
Definition dlib.c:308
char * dStrndup(const char *s, size_t sz)
Definition dlib.c:88
Dstr * dStr_new(const char *s)
Create a new string.
Definition dlib.c:325
void dList_append(Dlist *lp, void *data)
Append a data item to the list.
Definition dlib.c:597
void * dList_find_custom(Dlist *lp, const void *data, dCompareFunc func)
Search a data item using a custom function.
Definition dlib.c:704
const char * dStr_printable(Dstr *in, int maxlen)
Return a printable representation of the provided Dstr, limited to a length of roughly maxlen.
Definition dlib.c:513
void dList_remove(Dlist *lp, const void *data)
Definition dlib.c:641
void * dList_find(Dlist *lp, const void *data)
Return the found data item, or NULL if not present.
Definition dlib.c:672
#define dStrerror
Definition dlib.h:95
#define dReturn_if_fail(expr)
Definition dlib.h:72
#define dReturn_val_if_fail(expr, val)
Definition dlib.h:76
#define TRUE
Definition dlib.h:23
#define FALSE
Definition dlib.h:19
#define dNew(type, count)
Definition dlib.h:49
bool_t a_Domain_permit(const DilloUrl *source, const DilloUrl *dest)
Is the resource at 'source' permitted to request the resource at 'dest'?
Definition domain.c:116
void a_Dpiapi_dialog(BrowserWindow *bw, char *server, char *dpip_tag)
Process a dpip "dialog" command from any dpi.
Definition dpiapi.c:52
char * a_Dpip_build_cmd(const char *format,...)
Printf like function for building dpip commands.
Definition dpip.c:83
const DilloUrl * a_History_get_url(int idx)
Return the DilloUrl field (by index)
Definition history.c:80
void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2)
CCC function for the HTTP module.
Definition http.c:883
#define MSG_WARN(...)
Definition msg.h:26
void a_Nav_cancel_expect_if_eq(BrowserWindow *bw, const DilloUrl *url)
Definition nav.c:260
void a_Nav_reload(BrowserWindow *bw)
Definition nav.c:516
int a_Nav_stack_size(BrowserWindow *bw)
Definition nav.c:98
#define NAV_TOP_UIDX(bw)
Definition nav.h:10
void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2)
CCC function for the Dpi module.
Definition dpi.c:646
Contains the specific data for a single window.
Definition bw.h:27
Data structure for cache clients.
Definition cache.h:48
const DilloUrl * Url
Pointer to a cache entry Url.
Definition cache.h:50
uint_t BufSize
Valid size of cache-data.
Definition cache.h:53
A convenience data structure for passing data chunks between nodes.
Definition chain.h:52
char * Buf
Definition chain.h:53
int Size
Definition chain.h:54
Definition url.h:88
Definition dlib.h:131
Definition dlib.h:102
Dstr_char_t * str
Definition dlib.h:105
char * filename
Variables for Local saving.
Definition web.hh:34
int flags
Additional info.
Definition web.hh:29
DilloUrl * url
Requested URL.
Definition web.hh:25
FILE * stream
Definition web.hh:35
DilloUrl * requester
URL that caused this request, or < NULL if user-initiated.
Definition web.hh:26
BrowserWindow * bw
The requesting browser window [reference].
Definition web.hh:28
void a_UIcmd_set_msg(BrowserWindow *bw, const char *format,...)
Definition uicmd.cc:1516
void a_Url_set_flags(DilloUrl *u, int flags)
Set DilloUrl flags.
Definition url.c:527
int a_Url_cmp(const DilloUrl *A, const DilloUrl *B)
Compare two Url's to check if they're the same, or which one is bigger.
Definition url.c:506
void a_Url_free(DilloUrl *url)
Free a DilloUrl.
Definition url.c:208
DilloUrl * a_Url_dup(const DilloUrl *ori)
Duplicate a Url structure.
Definition url.c:477
#define URL_PATH(u)
Definition url.h:72
#define URL_E2EQuery
Definition url.h:35
#define URL_FLAGS(u)
Definition url.h:79
#define URL_DATA(u)
Definition url.h:77
#define URL_STR(u)
Definition url.h:76
#define URL_SCHEME(u)
Definition url.h:70
#define URL_Post
Definition url.h:33
#define URL_Get
Definition url.h:32
void a_Web_free(DilloWeb *web)
Deallocate a DilloWeb structure.
Definition web.cc:152
#define WEB_RootUrl
Definition web.hh:16
#define WEB_Download
Definition web.hh:19