📄 capi.c
字号:
/* * File: capi.c * * Copyright 2002 Jorge Arellano Cid <jcid@dillo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *//* * Cache API * This is the module that manages the cache and starts the CCC chains * to get the requests served. Kind of a broker. */#include <string.h>#include "msg.h"#include "capi.h"#include "IO/Url.h"#include "chain.h"#include "list.h"#include "interface.h"#include "history.h"#include "nav.h"#include "misc.h"/* for testing dpi chat */#include "bookmark.h"#define DEBUG_LEVEL 5#include "debug.h"typedef struct { DilloWeb *web; DilloUrl *url; /* local copy of web->url. Used when the latter is freed */ void *bw; gchar *server; gchar *datastr; gint SockFD; gint Flags; gint DpiPipe[2]; ChainLink *InfoSend; ChainLink *InfoRecv; ChainLink *InfoPipe; gint Ref;} dpi_conn_t;/* Flags for conn */enum { PENDING = 1, TIMEOUT = 2, /* unused */ ABORTED = 4};/* * Local data *//* Data list for active dpi connections */static dpi_conn_t **DpiConn = NULL;static gint DpiConnSize;static gint DpiConnMax = 4;/* ID for the timeout function that waits for dpid to start */static guint dpi_conn_timeout_id = 0;/* * Forward declarations */void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2);/* ------------------------------------------------------------------------- *//* * Create a new connection data structure */static dpi_conn_t * Capi_dpi_conn_new(DilloWeb *web, void *bw, char *server, gchar *datastr){ dpi_conn_t *conn; conn = g_new(dpi_conn_t, 1); conn->web = web; conn->url = (web) ? a_Url_dup(web->url) : NULL; conn->bw = bw; conn->server = g_strdup(server); conn->datastr = g_strdup(datastr); conn->SockFD = -1; conn->Flags = PENDING; conn->InfoSend = a_Chain_new(); conn->InfoRecv = NULL; /* will be set later */ conn->InfoPipe = NULL; /* may be set later */ conn->Ref = 0; /* Reference count */ return conn;}/* * Increment the reference count and add to the list if not present */static void Capi_dpi_conn_ref(dpi_conn_t *conn){ if (++conn->Ref == 1) { /* add the connection data to list */ a_List_add(DpiConn, DpiConnSize, DpiConnMax); DpiConn[DpiConnSize] = conn; DpiConnSize++; }}/* * Decrement the reference count (and remove from list when zero) */static void Capi_dpi_conn_unref(dpi_conn_t *conn){ gint i, j; --conn->Ref; if (conn->Ref == 0) { for (i = 0; i < DpiConnSize; ++i) if (DpiConn[i] == conn) { /* remove conn preserving the list order */ for (j = i; j + 1 < DpiConnSize; ++j) DpiConn[j] = DpiConn[j + 1]; --DpiConnSize; /* free dynamic memory */ a_Url_free(conn->url); g_free(conn->server); g_free(conn->datastr); g_free(conn); break; } }}/* * Find connection data by server */static dpi_conn_t *Capi_dpi_conn_find(gchar *server){ gint i; for (i = 0; i < DpiConnSize; ++i) if (strcmp(server, DpiConn[i]->server) == 0) return DpiConn[i]; return NULL;}/* * Resume connections that were waiting for dpid to start. */static void Capi_dpi_conn_resume(void){ gint i; DataBuf *dbuf; for (i = 0; i < DpiConnSize; ++i) if (DpiConn[i]->Flags & PENDING) { dpi_conn_t *conn = DpiConn[i]; dbuf = a_Chain_dbuf_new(conn->datastr, strlen(conn->datastr), 0); a_Capi_ccc(OpSend, 1, BCK, conn->InfoSend, dbuf, NULL); g_free(dbuf); conn->Flags &= ~PENDING; }}/* * Test dpid and resume connections if it already started. */static gint Capi_dpi_conn_timeout(gpointer data){ static gint try = 0; gint i; ++try; DEBUG_MSG(5, "Capi_dpi_conn_timeout:: try %d\n", try); for (i = 0; i < DpiConnSize; ++i) if (DpiConn[i]->Flags & PENDING) { dpi_conn_t *conn = DpiConn[i]; a_Chain_bcb(OpStart, conn->InfoSend, conn->server, NULL); break; } for (i = 0; i < DpiConnSize; ++i) if (DpiConn[i]->Flags & PENDING) return TRUE; try = 0; dpi_conn_timeout_id = 0; return FALSE;}/* ------------------------------------------------------------------------- *//* * Safety test: only allow dpi-urls from dpi-generated pages. */static gint Capi_verify_dpi_url_request(DilloWeb *web){ DilloUrl *referer; gint allow = FALSE; /* test POST and GET */ if (strchr(URL_STR(web->url), '?') || URL_DATA_(web->url)) { /* safety measure: only allow dpi requests from dpi-generated urls */ if (a_Nav_stack_size(web->bw)) { referer = a_History_get_url(NAV_TOP(web->bw)); if (g_strncasecmp(URL_STR(referer), "dpi:/", 5) == 0) allow = TRUE; } } else { allow = TRUE; } if (!allow) { MSG("Capi_verify_dpi_url_request: Permission Denied!\n"); MSG(" URL_STR : %s\n", URL_STR(web->url)); if (URL_DATA_(web->url)) MSG(" URL_DATA: %s\n", URL_DATA(web->url)); } return allow;}/* * If the url belongs to a dpi server, return its name. */gint a_Capi_url_uses_dpi(gchar *url_str, gchar **server_ptr){ gchar *p, *server = NULL; if (g_strncasecmp(url_str, "dpi:/", 5) == 0) { /* dpi prefix, get this server's name */ p = strchr(url_str + 5, '/'); server = p ? g_strndup(url_str + 5, p - url_str - 5) : g_strdup("?"); if (strcmp(server, "bm") == 0) { g_free(server); server = g_strdup("bookmarks"); } } else if (g_strncasecmp(url_str, "ftp:/", 5) == 0) { server = g_strdup("ftp"); } else if (g_strncasecmp(url_str, "https:/", 7) == 0) { server = g_strdup("https"); } return ((*server_ptr = server) ? 1 : 0);}/* * Build the dpip command tag, according to URL and server. * todo: make it PROXY-aware (AFAIS, it should be easy) */gchar *a_Capi_dpi_build_cmd(DilloUrl *url, gchar *server){ gchar *cmd, *http_query, *s_http_query; if (strcmp(server, "https") == 0) { /* Let's be kind and make the HTTP query string for the dpi */ http_query = a_Http_make_query_str(url, FALSE); s_http_query = a_Misc_stuff_chars(http_query, "'\""); cmd = g_strdup_printf("<dpi cmd='open_url' url='%s' query='%s'>", URL_STR(url), s_http_query); g_free(s_http_query); g_free(http_query); } else { /* For everyone else, the url_str is enough... */ cmd = g_strdup_printf("<dpi cmd='open_url' url='%s'>", URL_STR(url)); } return cmd;}/* * Most used function. * todo: clean up the ad-hoc bindings with an API that allows dynamic * addition of new plugins.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -