Dillo v3.1.1-119-g140d9ebd
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-2024 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#include "prefs.h"
36
37/* for testing dpi chat */
38#include "bookmark.h"
39
40typedef struct {
41 DilloUrl *url;
42 void *bw;
43 char *server;
44 char *datastr;
45 int SockFD;
46 int Flags;
47 ChainLink *InfoSend;
48 ChainLink *InfoRecv;
49
50 int Ref;
51} capi_conn_t;
52
54enum {
56 TIMEOUT = 2, /* unused */
57 ABORTED = 4
58};
59
60/*
61 * Local data
62 */
64static Dlist *CapiConns; /* Data list for active connections; it holds
65 * pointers to capi_conn_t structures. */
67static DilloUrl *CapiVsUrl = NULL;
68
69/*
70 * Forward declarations
71 */
72void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
73 void *Data1, void *Data2);
74
75
76/* ------------------------------------------------------------------------- */
77
81void a_Capi_init(void)
82{
83 /* create an empty list */
84 CapiConns = dList_new(32);
85 /* init cache */
87}
88
89/* ------------------------------------------------------------------------- */
90
94static capi_conn_t *
95 Capi_conn_new(const DilloUrl *url, void *bw, char *server, char *datastr)
96{
97 capi_conn_t *conn;
98
99 conn = dNew(capi_conn_t, 1);
100 conn->url = url ? a_Url_dup(url) : NULL;
101 conn->bw = bw;
102 conn->server = dStrdup(server);
103 conn->datastr = dStrdup(datastr);
104 conn->SockFD = -1;
105 conn->Flags = (strcmp(server, "http") != 0) ? PENDING : 0;
106 conn->InfoSend = NULL;
107 conn->InfoRecv = NULL;
108 conn->Ref = 0; /* Reference count */
109 return conn;
110}
111
116static capi_conn_t *Capi_conn_valid(capi_conn_t *conn)
117{
118 return dList_find(CapiConns, conn);
119}
120
124static void Capi_conn_ref(capi_conn_t *conn)
125{
126 if (++conn->Ref == 1) {
127 /* add the connection data to list */
128 dList_append(CapiConns, (void *)conn);
129 }
130 _MSG(" Capi_conn_ref #%d %p\n", conn->Ref, conn);
131}
132
136static void Capi_conn_unref(capi_conn_t *conn)
137{
138 _MSG(" Capi_conn_unref #%d %p\n", conn->Ref - 1, conn);
139
140 /* We may validate conn here, but it doesn't *seem* necessary */
141 if (--conn->Ref == 0) {
142 /* remove conn preserving the list order */
143 dList_remove(CapiConns, (void *)conn);
144 /* free dynamic memory */
145 a_Url_free(conn->url);
146 dFree(conn->server);
147 dFree(conn->datastr);
148 dFree(conn);
149 }
150 _MSG(" Capi_conn_unref CapiConns=%d\n", dList_length(CapiConns));
151}
152
156static int Capi_conn_by_server_cmp(const void *v1, const void *v2)
157{
158 const capi_conn_t *node = v1;
159 const char *server = v2;
160 dReturn_val_if_fail(node && node->server && server, 1);
161 return strcmp(node->server, server);
162}
163
167static capi_conn_t *Capi_conn_find(char *server)
168{
170}
171
175static void Capi_conn_resume(void)
176{
177 int i;
178 DataBuf *dbuf;
179 capi_conn_t *conn;
180
181 for (i = 0; i < dList_length(CapiConns); ++i) {
182 conn = dList_nth_data (CapiConns, i);
183 if (conn->Flags & PENDING) {
184 dbuf = a_Chain_dbuf_new(conn->datastr,(int)strlen(conn->datastr), 0);
185 if (conn->InfoSend) {
186 a_Capi_ccc(OpSend, 1, BCK, conn->InfoSend, dbuf, NULL);
187 }
188 dFree(dbuf);
189 conn->Flags &= ~PENDING;
190 }
191 }
192}
193
201{
202 int i;
203 capi_conn_t *conn;
204
205 for (i = 0; i < dList_length(CapiConns); ++i) {
206 conn = dList_nth_data (CapiConns, i);
207 if (a_Url_cmp(conn->url, url) == 0) {
208 if (conn->InfoSend) {
209 a_Capi_ccc(OpAbort, 1, BCK, conn->InfoSend, NULL, NULL);
210 }
211 if (conn->InfoRecv) {
212 a_Capi_ccc(OpAbort, 2, BCK, conn->InfoRecv, NULL, NULL);
213 }
214 break;
215 }
216 }
217}
218
219/* ------------------------------------------------------------------------- */
220
225{
227 CapiVsUrl = a_Url_dup(url);
228}
229
234{
235 const DilloUrl *referer;
236 int allow = FALSE;
237
238 if (dStrAsciiCasecmp(URL_SCHEME(url), "dpi") == 0) {
239 if (!(URL_FLAGS(url) & (URL_Post + URL_Get))) {
240 allow = TRUE;
241 } else if (!(URL_FLAGS(url) & URL_Post) &&
242 strncmp(URL_PATH(url), "/vsource/", 9) == 0) {
243 allow = TRUE;
244 } else {
245 /* only allow GET&POST dpi-requests from dpi-generated urls */
246 if (a_Nav_stack_size(bw)) {
247 referer = a_History_get_url(NAV_TOP_UIDX(bw));
248 if (dStrAsciiCasecmp(URL_SCHEME(referer), "dpi") == 0) {
249 allow = TRUE;
250 }
251 }
252 }
253 } else {
254 allow = TRUE;
255 }
256
257 if (!allow) {
258 MSG("a_Capi_dpi_verify_request: Permission Denied!\n");
259 MSG(" URL_STR : %s\n", URL_STR(url));
260 if (URL_FLAGS(url) & URL_Post) {
261 MSG(" URL_DATA: %s\n", dStr_printable(URL_DATA(url), 1024));
262 }
263 }
264 return allow;
265}
266
270static int Capi_url_uses_dpi(DilloUrl *url, char **server_ptr)
271{
272 char *p, *server = NULL, *url_str = URL_STR(url);
273 Dstr *tmp;
274
275 if ((dStrnAsciiCasecmp(url_str, "http:", 5) == 0) ||
276 (dStrnAsciiCasecmp(url_str, "https:", 6) == 0) ||
277 (dStrnAsciiCasecmp(url_str, "about:", 6) == 0)) {
278 /* URL doesn't use dpi (server = NULL) */
279 } else if (dStrnAsciiCasecmp(url_str, "dpi:/", 5) == 0) {
280 /* dpi prefix, get this server's name */
281 if ((p = strchr(url_str + 5, '/')) != NULL) {
282 server = dStrndup(url_str + 5, (uint_t)(p - url_str - 5));
283 } else {
284 server = dStrdup("?");
285 }
286 if (strcmp(server, "bm") == 0) {
287 dFree(server);
288 server = dStrdup("bookmarks");
289 }
290 } else if ((p = strchr(url_str, ':')) != NULL) {
291 tmp = dStr_new("proto.");
292 dStr_append_l(tmp, url_str, p - url_str);
293 server = tmp->str;
294 dStr_free(tmp, 0);
295 }
296
297 return ((*server_ptr = server) ? 1 : 0);
298}
299
303static char *Capi_dpi_build_cmd(DilloWeb *web, char *server)
304{
305 char *cmd;
306
307 if (strcmp(server, "downloads") == 0) {
308 /* let the downloads server get it */
309 cmd = a_Dpip_build_cmd("cmd=%s url=%s destination=%s user-agent=%s",
310 "download", URL_STR(web->url), web->filename,
312
313 } else {
314 /* For everyone else, the url string is enough... */
315 cmd = a_Dpip_build_cmd("cmd=%s url=%s", "open_url", URL_STR(web->url));
316 }
317 return cmd;
318}
319
324{
325 char *p, *buf, *cmd, size_str[32], *server="vsource";
326 int buf_size;
327
328 if (!(p = strchr(URL_STR(url), ':')) || !(p = strchr(p + 1, ':')))
329 return;
330
331 if (a_Capi_get_buf(CapiVsUrl, &buf, &buf_size)) {
332 /* send the page's source to this dpi connection */
333 snprintf(size_str, 32, "%d", buf_size);
334 cmd = a_Dpip_build_cmd("cmd=%s url=%s data_size=%s",
335 "start_send_page", URL_STR(url), size_str);
336 a_Capi_dpi_send_cmd(NULL, bw, cmd, server, 0);
337 a_Capi_dpi_send_data(url, bw, buf, buf_size, server, 0);
338 } else {
339 cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
340 "DpiError", "Page is NOT cached");
341 a_Capi_dpi_send_cmd(NULL, bw, cmd, server, 0);
342 }
343 dFree(cmd);
344}
345
350{
351 bool_t permit = FALSE;
352
353 /* web->requester is NULL if the action is initiated by user */
354 if (!web->requester)
355 return TRUE;
356
357 if (web->flags & ~WEB_RootUrl &&
358 !dStrAsciiCasecmp(URL_SCHEME(web->requester), "https")) {
359 const char *s = URL_SCHEME(web->url);
360
361 /* As of 2015, blocking of "active" mixed content is widespread
362 * (style sheets, javascript, fonts, etc.), but the big browsers aren't
363 * quite in a position to block "passive" mixed content (images) yet.
364 * (Not clear whether there's consensus on which category to place
365 * background images in.)
366 *
367 * We are blocking both, and only permitting secure->insecure page
368 * redirection for now (e.g., duckduckgo has been seen providing links
369 * to https URLs that redirect to http). As the web security landscape
370 * evolves, we may be able to remove that permission.
371 */
372 if (dStrAsciiCasecmp(s, "https") && dStrAsciiCasecmp(s, "data")) {
373 MSG("capi: Blocked mixed content: %s -> %s\n",
374 URL_STR(web->requester), URL_STR(web->url));
375 return FALSE;
376 }
377 }
378
379 if (a_Capi_get_flags(web->url) & CAPI_IsCached ||
380 a_Domain_permit(web->requester, web->url)) {
381 permit = TRUE;
382 }
383 return permit;
384}
385
394int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData)
395{
396 int reload;
397 char *cmd, *server;
398 capi_conn_t *conn = NULL;
399 const char *scheme = URL_SCHEME(web->url);
400 int safe = 0, ret = 0, use_cache = 0;
401
402 if (Capi_request_permitted(web)) {
403 /* reload test */
404 reload = (!(a_Capi_get_flags(web->url) & CAPI_IsCached) ||
405 (URL_FLAGS(web->url) & URL_E2EQuery));
406
407 if (web->flags & WEB_Download) {
408 /* download request: if cached save from cache, else
409 * for http, ftp or https, use the downloads dpi */
411 if (web->filename) {
412 if ((web->stream = fopen(web->filename, "w"))) {
413 use_cache = 1;
414 } else {
415 MSG_WARN("Cannot open \"%s\" for writing: %s.\n",
416 web->filename, dStrerror(errno));
417 }
418 }
419 } else if (a_Cache_download_enabled(web->url)) {
420 server = "downloads";
421 cmd = Capi_dpi_build_cmd(web, server);
422 a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
423 dFree(cmd);
424 } else {
425 MSG_WARN("Ignoring download request for '%s': "
426 "not in cache and not downloadable.\n",
427 URL_STR(web->url));
428 }
429
430 } else if (Capi_url_uses_dpi(web->url, &server)) {
431 /* dpi request */
432 if ((safe = a_Capi_dpi_verify_request(web->bw, web->url))) {
433 if (dStrAsciiCasecmp(scheme, "dpi") == 0) {
434 if (strcmp(server, "vsource") == 0) {
435 /* allow "view source" reload upon user request */
436 } else {
437 /* make the other "dpi:/" prefixed urls always reload. */
439 reload = 1;
440 }
441 }
442 if (reload) {
444 /* Send dpip command */
445 _MSG("a_Capi_open_url, reload url='%s'\n", URL_STR(web->url));
446 cmd = Capi_dpi_build_cmd(web, server);
447 a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1);
448 dFree(cmd);
449 if (strcmp(server, "vsource") == 0) {
450 Capi_dpi_send_source(web->bw, web->url);
451 }
452 }
453 use_cache = 1;
454 }
455 dFree(server);
456
457 } else if (!dStrAsciiCasecmp(scheme, "http") ||
458 !dStrAsciiCasecmp(scheme, "https")) {
459 /* http request */
460
461#ifndef ENABLE_TLS
462 if (!dStrAsciiCasecmp(scheme, "https")) {
463 if (web->flags & WEB_RootUrl)
464 a_UIcmd_set_msg(web->bw,
465 "HTTPS was disabled at compilation time.");
466 a_Web_free(web);
467 return 0;
468 }
469#endif
470 if (reload) {
472 /* create a new connection and start the CCC operations */
473 conn = Capi_conn_new(web->url, web->bw, "http", "none");
474 /* start the reception branch before the query one because the DNS
475 * may callback immediately. This may avoid a race condition. */
476 a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, "http");
477 a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, web);
478 }
479 use_cache = 1;
480
481 } else if (!dStrAsciiCasecmp(scheme, "about")) {
482 /* internal request */
483 use_cache = 1;
484 }
485 }
486
487 if (use_cache) {
488 if (!conn || (conn && Capi_conn_valid(conn))) {
489 /* not aborted, let's continue... */
490 ret = a_Cache_open_url(web, Call, CbData);
491 }
492 } else {
493 a_Web_free(web);
494 }
495 return ret;
496}
497
502{
503 int status = 0;
504
505 if (flags) {
506 status |= CAPI_IsCached;
507 if (flags & CA_IsEmpty)
508 status |= CAPI_IsEmpty;
509 if (flags & CA_InProgress)
510 status |= CAPI_InProgress;
511 else
512 status |= CAPI_Completed;
513
514 /* CAPI_Aborted is not yet used/defined */
515 }
516 return status;
517}
518
523{
524 uint_t flags = a_Cache_get_flags(Url);
525 int status = flags ? Capi_map_cache_flags(flags) : 0;
526 return status;
527}
528
533{
535 int status = flags ? Capi_map_cache_flags(flags) : 0;
536 return status;
537}
538
543int a_Capi_get_buf(const DilloUrl *Url, char **PBuf, int *BufSize)
544{
545 return a_Cache_get_buf(Url, PBuf, BufSize);
546}
547
552{
554}
555
559const char *a_Capi_get_content_type(const DilloUrl *url)
560{
561 return a_Cache_get_content_type(url);
562}
563
567const char *a_Capi_set_content_type(const DilloUrl *url, const char *ctype,
568 const char *from)
569{
570 return a_Cache_set_content_type(url, ctype, from);
571}
572
578int a_Capi_dpi_send_data(const DilloUrl *url, void *bw,
579 char *data, int data_sz, char *server, int flags)
580{
581 capi_conn_t *conn;
582 DataBuf *dbuf;
583
584 if (flags & 1) {
585 /* open a new connection to server */
586
587 /* Create a new connection data struct and add it to the list */
588 conn = Capi_conn_new(url, bw, server, data);
589 /* start the CCC operations */
590 a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, server);
591 a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, server);
592
593 } else {
594 /* Re-use an open connection */
595 conn = Capi_conn_find(server);
596 if (conn && conn->InfoSend) {
597 /* found & active */
598 dbuf = a_Chain_dbuf_new(data, data_sz, 0);
599 a_Capi_ccc(OpSend, 1, BCK, conn->InfoSend, dbuf, NULL);
600 dFree(dbuf);
601 } else {
602 MSG(" ERROR: [a_Capi_dpi_send_data] No open connection found\n");
603 }
604 }
605
606 return 0;
607}
608
613int a_Capi_dpi_send_cmd(DilloUrl *url, void *bw, char *cmd, char *server,
614 int flags)
615{
616 return a_Capi_dpi_send_data(url, bw, cmd, strlen(cmd), server, flags);
617}
618
623void a_Capi_stop_client(int Key, int force)
624{
625 CacheClient_t *Client;
626
627 _MSG("a_Capi_stop_client: force=%d\n", force);
628
629 Client = a_Cache_client_get_if_unique(Key);
630 if (Client && (force || Client->BufSize == 0)) {
631 /* remove empty entries too */
633 }
635}
636
640void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
641 void *Data1, void *Data2)
642{
643 capi_conn_t *conn;
644
645 dReturn_if_fail( a_Chain_check("a_Capi_ccc", Op, Branch, Dir, Info) );
646
647 if (Branch == 1) {
648 if (Dir == BCK) {
649 /* Command sending branch */
650 switch (Op) {
651 case OpStart:
652 /* Data1 = conn; Data2 = {Web | server} */
653 conn = Data1;
654 Capi_conn_ref(conn);
655 Info->LocalKey = conn;
656 conn->InfoSend = Info;
657 if (strcmp(conn->server, "http") == 0 ||
658 strcmp(conn->server, "https") == 0) {
660 a_Chain_bcb(OpStart, Info, Data2, NULL);
661 } else {
663 a_Chain_bcb(OpStart, Info, Data2, NULL);
664 }
665 break;
666 case OpSend:
667 /* Data1 = dbuf */
668 a_Chain_bcb(OpSend, Info, Data1, NULL);
669 break;
670 case OpEnd:
671 conn = Info->LocalKey;
672 conn->InfoSend = NULL;
673 a_Chain_bcb(OpEnd, Info, NULL, NULL);
674 Capi_conn_unref(conn);
675 dFree(Info);
676 break;
677 case OpAbort:
678 conn = Info->LocalKey;
679 conn->InfoSend = NULL;
680 a_Chain_bcb(OpAbort, Info, NULL, NULL);
681 Capi_conn_unref(conn);
682 dFree(Info);
683 break;
684 default:
685 MSG_WARN("Unused CCC Capi 1B\n");
686 break;
687 }
688 } else { /* 1 FWD */
689 /* Command sending branch (status) */
690 switch (Op) {
691 case OpSend:
692 if (!Data2) {
693 MSG_WARN("Capi.c: Opsend [1F] Data2 = NULL\n");
694 } else if (strcmp(Data2, "FD") == 0) {
695 conn = Info->LocalKey;
696 conn->SockFD = *(int*)Data1;
697 /* communicate the FD through the answer branch */
698 a_Capi_ccc(OpSend, 2, BCK, conn->InfoRecv, &conn->SockFD, "FD");
699 } else if (strcmp(Data2, "DpidOK") == 0) {
700 /* resume pending dpi requests */
702 }
703 break;
704 case OpAbort:
705 conn = Info->LocalKey;
706 conn->InfoSend = NULL;
707 a_Cache_process_dbuf(IOAbort, NULL, 0, conn->url);
708 if (Data2) {
709 if (!strcmp(Data2, "DpidERROR")) {
710 a_UIcmd_set_msg(conn->bw,
711 "ERROR: can't start dpid daemon "
712 "(URL scheme = '%s')!",
713 conn->url ? URL_SCHEME(conn->url) : "");
714 } else if (!strcmp(Data2, "Both") && conn->InfoRecv) {
715 /* abort the other branch too */
716 a_Capi_ccc(OpAbort, 2, BCK, conn->InfoRecv, NULL, NULL);
717 }
718 }
719 /* if URL == expect-url */
720 a_Nav_cancel_expect_if_eq(conn->bw, conn->url);
721 /* finish conn */
722 Capi_conn_unref(conn);
723 dFree(Info);
724 break;
725 default:
726 MSG_WARN("Unused CCC Capi 1F\n");
727 break;
728 }
729 }
730
731 } else if (Branch == 2) {
732 if (Dir == BCK) {
733 /* Answer branch */
734 switch (Op) {
735 case OpStart:
736 /* Data1 = conn; Data2 = {"http" | "<dpi server name>"} */
737 conn = Data1;
738 Capi_conn_ref(conn);
739 Info->LocalKey = conn;
740 conn->InfoRecv = Info;
741 if (strcmp(conn->server, "http") == 0)
743 else
745 a_Chain_bcb(OpStart, Info, NULL, Data2);
746 break;
747 case OpSend:
748 /* Data1 = FD */
749 if (Data2 && strcmp(Data2, "FD") == 0) {
750 a_Chain_bcb(OpSend, Info, Data1, Data2);
751 }
752 break;
753 case OpAbort:
754 conn = Info->LocalKey;
755 conn->InfoRecv = NULL;
756 a_Chain_bcb(OpAbort, Info, NULL, NULL);
757 /* remove the cache entry for this URL */
759 Capi_conn_unref(conn);
760 dFree(Info);
761 break;
762 default:
763 MSG_WARN("Unused CCC Capi 2B\n");
764 break;
765 }
766 } else { /* 2 FWD */
767 /* Server listening branch */
768 switch (Op) {
769 case OpSend:
770 conn = Info->LocalKey;
771 if (strcmp(Data2, "send_page_2eof") == 0) {
772 /* Data1 = dbuf */
773 DataBuf *dbuf = Data1;
774 bool_t finished = a_Cache_process_dbuf(IORead, dbuf->Buf,
775 dbuf->Size, conn->url);
776 if (finished && Capi_conn_valid(conn) && conn->InfoRecv) {
777 /* If we have a persistent connection where cache tells us
778 * that we've received the full response, and cache didn't
779 * trigger an abort and tear everything down, tell upstream.
780 */
781 a_Chain_bcb(OpSend, conn->InfoRecv, NULL, "reply_complete");
782 }
783 } else if (strcmp(Data2, "send_status_message") == 0) {
784 a_UIcmd_set_msg(conn->bw, "%s", Data1);
785 } else if (strcmp(Data2, "chat") == 0) {
786 a_UIcmd_set_msg(conn->bw, "%s", Data1);
787 a_Bookmarks_chat_add(NULL, NULL, Data1);
788 } else if (strcmp(Data2, "dialog") == 0) {
789 a_Dpiapi_dialog(conn->bw, conn->server, Data1);
790 } else if (strcmp(Data2, "reload_request") == 0) {
791 a_Nav_reload(conn->bw);
792 } else if (strcmp(Data2, "start_send_page") == 0) {
793 /* prepare the cache to receive the data stream for this URL
794 *
795 * a_Capi_open_url() already added a new cache entry,
796 * and a client for it.
797 */
798 }
799 break;
800 case OpEnd:
801 conn = Info->LocalKey;
802 conn->InfoRecv = NULL;
803
804 a_Cache_process_dbuf(IOClose, NULL, 0, conn->url);
805
806 if (conn->InfoSend) {
807 /* Propagate OpEnd to the sending branch too */
808 a_Capi_ccc(OpEnd, 1, BCK, conn->InfoSend, NULL, NULL);
809 }
810 Capi_conn_unref(conn);
811 dFree(Info);
812 break;
813 case OpAbort:
814 conn = Info->LocalKey;
815 conn->InfoRecv = NULL;
816 a_Cache_process_dbuf(IOAbort, NULL, 0, conn->url);
817 if (Data2) {
818 if (!strcmp(Data2, "Both") && conn->InfoSend) {
819 /* abort the other branch too */
820 a_Capi_ccc(OpAbort, 1, BCK, conn->InfoSend, NULL, NULL);
821 }
822 }
823 /* if URL == expect-url */
824 a_Nav_cancel_expect_if_eq(conn->bw, conn->url);
825 /* finish conn */
826 Capi_conn_unref(conn);
827 dFree(Info);
828 break;
829 default:
830 MSG_WARN("Unused CCC Capi 2F\n");
831 break;
832 }
833 }
834 }
835}
#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:175
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:543
@ PENDING
Definition capi.c:55
@ ABORTED
Definition capi.c:57
@ TIMEOUT
Definition capi.c:56
static bool_t Capi_request_permitted(DilloWeb *web)
Shall we permit this request to open a URL?
Definition capi.c:349
static void Capi_conn_unref(capi_conn_t *conn)
Decrement the reference count (and remove from list when zero)
Definition capi.c:136
static Dlist * CapiConns
Data list for active dpi connections.
Definition capi.c:64
int a_Capi_dpi_send_cmd(DilloUrl *url, void *bw, char *cmd, char *server, int flags)
Send a dpi cmd.
Definition capi.c:613
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:567
static char * Capi_dpi_build_cmd(DilloWeb *web, char *server)
Build the dpip command tag, according to URL and server.
Definition capi.c:303
static capi_conn_t * Capi_conn_valid(capi_conn_t *conn)
Validate a capi_conn_t pointer.
Definition capi.c:116
void a_Capi_set_vsource_url(const DilloUrl *url)
Store the last URL requested by "view source".
Definition capi.c:224
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:156
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:233
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:95
static DilloUrl * CapiVsUrl
Last URL asked for view source.
Definition capi.c:67
static capi_conn_t * Capi_conn_find(char *server)
Find connection data by server.
Definition capi.c:167
void a_Capi_unref_buf(const DilloUrl *Url)
Unref the cache's buffer when no longer using it.
Definition capi.c:551
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:270
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:640
int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData)
Most used function for requesting a URL.
Definition capi.c:394
int a_Capi_get_flags_with_redirection(const DilloUrl *Url)
Same as a_Capi_get_flags() but following redirections.
Definition capi.c:532
void a_Capi_stop_client(int Key, int force)
Remove a client from the cache client queue.
Definition capi.c:623
static void Capi_conn_ref(capi_conn_t *conn)
Increment the reference count and add to the list if not present.
Definition capi.c:124
static int Capi_map_cache_flags(uint_t flags)
Convert cache-defined flags to Capi ones.
Definition capi.c:501
static void Capi_dpi_send_source(BrowserWindow *bw, DilloUrl *url)
Send the requested URL's source to the "view source" dpi.
Definition capi.c:323
void a_Capi_init(void)
Initialize capi&cache data.
Definition capi.c:81
const char * a_Capi_get_content_type(const DilloUrl *url)
Get the Content-Type associated with the URL.
Definition capi.c:559
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:578
void a_Capi_conn_abort_by_url(const DilloUrl *url)
Abort the connection for a given url, using its CCC.
Definition capi.c:200
int a_Capi_get_flags(const DilloUrl *Url)
Return status information of an URL's content-transfer process.
Definition capi.c:522
#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:882
#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
DilloPrefs prefs
Global Data.
Definition prefs.c:33
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
char * http_user_agent
Definition prefs.h:47
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:1563
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