Some ownership of the Cache types.

This commit is contained in:
2025-08-18 01:25:20 -04:00
parent 2ce2468007
commit 2d6deff51b

View File

@ -50,13 +50,13 @@ struct CacheEntry_t
{ {
~CacheEntry_t(); ~CacheEntry_t();
const DilloUrl *Url; /**< Cached Url. Url is used as a primary Key */ std::unique_ptr< const DilloUrl > Url; /**< Cached Url. Url is used as a primary Key */
char *TypeDet; /**< MIME type string (detected from data) */ char *TypeDet; /**< MIME type string (detected from data) */
char *TypeHdr; /**< MIME type string as from the HTTP Header */ char *TypeHdr; /**< MIME type string as from the HTTP Header */
char *TypeMeta; /**< MIME type string from META HTTP-EQUIV */ char *TypeMeta; /**< MIME type string from META HTTP-EQUIV */
char *TypeNorm; /**< MIME type string normalized */ char *TypeNorm; /**< MIME type string normalized */
Dstr *Header; /**< HTTP header */ Dstr *Header; /**< HTTP header */
const DilloUrl *Location; /**< New URI for redirects */ std::unique_ptr< const DilloUrl > Location; /**< New URI for redirects */
Dlist *Auth; /**< Authentication fields */ Dlist *Auth; /**< Authentication fields */
Dstr *Data; /**< Pointer to raw data */ Dstr *Data; /**< Pointer to raw data */
Dstr *UTF8Data; /**< Data after charset translation */ Dstr *UTF8Data; /**< Data after charset translation */
@ -101,7 +101,7 @@ static int Cache_entry_cmp(const void *v1, const void *v2)
{ {
const CacheEntry_t *d1 = reinterpret_cast< const CacheEntry_t * >( v1 ), *d2 = reinterpret_cast< const CacheEntry_t * >( v2 ); const CacheEntry_t *d1 = reinterpret_cast< const CacheEntry_t * >( v1 ), *d2 = reinterpret_cast< const CacheEntry_t * >( v2 );
return a_Url_cmp(d1->Url, d2->Url); return a_Url_cmp(d1->Url.get(), d2->Url.get());
} }
/** /**
@ -109,7 +109,7 @@ static int Cache_entry_cmp(const void *v1, const void *v2)
*/ */
static int Cache_entry_by_url_cmp(const void *v1, const void *v2) static int Cache_entry_by_url_cmp(const void *v1, const void *v2)
{ {
const DilloUrl *u1 = reinterpret_cast< const CacheEntry_t * >( v1 )->Url; const DilloUrl *u1 = reinterpret_cast< const CacheEntry_t * >( v1 )->Url.get();
const DilloUrl *u2 = reinterpret_cast< const DilloUrl * >( v2 ); const DilloUrl *u2 = reinterpret_cast< const DilloUrl * >( v2 );
return a_Url_cmp(u1, u2); return a_Url_cmp(u1, u2);
@ -193,7 +193,7 @@ static void Cache_client_dequeue(CacheClient_t *Client)
*/ */
static void Cache_entry_init(CacheEntry_t *NewEntry, const DilloUrl *Url) static void Cache_entry_init(CacheEntry_t *NewEntry, const DilloUrl *Url)
{ {
NewEntry->Url = a_Url_dup(Url).release(); NewEntry->Url = a_Url_dup(Url);
NewEntry->TypeDet = NULL; NewEntry->TypeDet = NULL;
NewEntry->TypeHdr = NULL; NewEntry->TypeHdr = NULL;
NewEntry->TypeMeta = NULL; NewEntry->TypeMeta = NULL;
@ -238,7 +238,7 @@ static CacheEntry_t *Cache_entry_search_with_redirect(const DilloUrl *Url)
} }
/* Test for a working redirection */ /* Test for a working redirection */
if (entry->Flags & CA_Redirect && entry->Location) { if (entry->Flags & CA_Redirect && entry->Location) {
Url = entry->Location; Url = entry->Location.get();
} else } else
break; break;
} }
@ -300,13 +300,11 @@ static void Cache_auth_free(Dlist *auth)
CacheEntry_t::~CacheEntry_t() CacheEntry_t::~CacheEntry_t()
{ {
auto *const entry= this; auto *const entry= this;
delete const_cast< DilloUrl * >( entry->Url );
dFree(entry->TypeDet); dFree(entry->TypeDet);
dFree(entry->TypeHdr); dFree(entry->TypeHdr);
dFree(entry->TypeMeta); dFree(entry->TypeMeta);
dFree(entry->TypeNorm); dFree(entry->TypeNorm);
dStr_free(entry->Header, TRUE); dStr_free(entry->Header, TRUE);
delete const_cast< DilloUrl * >( entry->Location );
Cache_auth_free(entry->Auth); Cache_auth_free(entry->Auth);
dStr_free(entry->Data, 1); dStr_free(entry->Data, 1);
dStr_free(entry->UTF8Data, 1); dStr_free(entry->UTF8Data, 1);
@ -335,7 +333,7 @@ static void Cache_entry_remove(CacheEntry_t *entry, DilloUrl *url)
/* remove all clients for this entry */ /* remove all clients for this entry */
for (i = 0; (Client = reinterpret_cast< CacheClient_t * >( dList_nth_data(ClientQueue, i) )); ++i) { for (i = 0; (Client = reinterpret_cast< CacheClient_t * >( dList_nth_data(ClientQueue, i) )); ++i) {
if (Client->Url == entry->Url) { if (Client->Url == entry->Url.get()) {
a_Cache_stop_client(Client->Key); a_Cache_stop_client(Client->Key);
--i; --i;
} }
@ -345,7 +343,7 @@ static void Cache_entry_remove(CacheEntry_t *entry, DilloUrl *url)
dList_remove(DelayedQueue, entry); dList_remove(DelayedQueue, entry);
/* remove from dicache */ /* remove from dicache */
a_Dicache_invalidate_entry(entry->Url); a_Dicache_invalidate_entry(entry->Url.get());
/* remove from cache */ /* remove from cache */
dList_remove(CachedURLs, entry); dList_remove(CachedURLs, entry);
@ -388,14 +386,14 @@ int a_Cache_open_url(void *web, CA_Callback_t Call, void *CbData)
if ((entry = Cache_entry_search(Url))) { if ((entry = Cache_entry_search(Url))) {
/* URL is cached: feed our client with cached data */ /* URL is cached: feed our client with cached data */
ClientKey = Cache_client_enqueue(entry->Url, Web, Call, CbData); ClientKey = Cache_client_enqueue(entry->Url.get(), Web, Call, CbData);
Cache_delayed_process_queue(entry); Cache_delayed_process_queue(entry);
} else { } else {
/* URL not cached: create an entry, send our client to the queue, /* URL not cached: create an entry, send our client to the queue,
* and open a new connection */ * and open a new connection */
entry = Cache_entry_add(Url); entry = Cache_entry_add(Url);
ClientKey = Cache_client_enqueue(entry->Url, Web, Call, CbData); ClientKey = Cache_client_enqueue(entry->Url.get(), Web, Call, CbData);
} }
return ClientKey; return ClientKey;
@ -685,9 +683,9 @@ static void Cache_parse_header(CacheEntry_t *entry)
if (header[9] == '3' && header[10] == '0' && if (header[9] == '3' && header[10] == '0' &&
(location_str = Cache_parse_field(header, "Location"))) { (location_str = Cache_parse_field(header, "Location"))) {
/* 30x: URL redirection */ /* 30x: URL redirection */
entry->Location = a_Url_new(location_str, URL_STR_(entry->Url)).release(); entry->Location = a_Url_new(location_str, URL_STR_(entry->Url.get()));
if (!a_Domain_permit(entry->Url, entry->Location) || if (!a_Domain_permit(entry->Url.get(), entry->Location.get()) ||
(URL_FLAGS(entry->Location) & (URL_Post + URL_Get) && (URL_FLAGS(entry->Location) & (URL_Post + URL_Get) &&
dStrAsciiCasecmp(URL_SCHEME(entry->Location), "dpi") == 0 && dStrAsciiCasecmp(URL_SCHEME(entry->Location), "dpi") == 0 &&
dStrAsciiCasecmp(URL_SCHEME(entry->Url), "dpi") != 0)) { dStrAsciiCasecmp(URL_SCHEME(entry->Url), "dpi") != 0)) {
@ -695,7 +693,7 @@ static void Cache_parse_header(CacheEntry_t *entry)
* urls. * urls.
*/ */
MSG("Redirection not followed from %s to %s\n", MSG("Redirection not followed from %s to %s\n",
URL_HOST(entry->Url), URL_STR(entry->Location)); URL_HOST(entry->Url.get()), URL_STR(entry->Location.get()));
} else { } else {
entry->Flags |= CA_Redirect; entry->Flags |= CA_Redirect;
if (header[11] == '1') if (header[11] == '1')
@ -732,10 +730,10 @@ static void Cache_parse_header(CacheEntry_t *entry)
} }
if (prefs.http_strict_transport_security && if (prefs.http_strict_transport_security &&
!dStrAsciiCasecmp(URL_SCHEME(entry->Url), "https") && !dStrAsciiCasecmp(URL_SCHEME(entry->Url.get()), "https") &&
a_Url_host_type(URL_HOST(entry->Url)) == URL_HOST_NAME && a_Url_host_type(URL_HOST(entry->Url.get())) == URL_HOST_NAME &&
(hsts = Cache_parse_field(header, "Strict-Transport-Security"))) { (hsts = Cache_parse_field(header, "Strict-Transport-Security"))) {
a_Hsts_set(hsts, entry->Url); a_Hsts_set(hsts, entry->Url.get());
dFree(hsts); dFree(hsts);
} }
@ -769,7 +767,7 @@ static void Cache_parse_header(CacheEntry_t *entry)
CacheClient_t *client; CacheClient_t *client;
for (i = 0; (client = reinterpret_cast< CacheClient_t * >( dList_nth_data(ClientQueue, i) )); ++i) { for (i = 0; (client = reinterpret_cast< CacheClient_t * >( dList_nth_data(ClientQueue, i) )); ++i) {
if (client->Url == entry->Url) { if (client->Url == entry->Url.get()) {
DilloWeb *web = reinterpret_cast< DilloWeb * >( client->Web ); DilloWeb *web = reinterpret_cast< DilloWeb * >( client->Web );
if (!web->requester || if (!web->requester ||
@ -777,7 +775,7 @@ static void Cache_parse_header(CacheEntry_t *entry)
/* If cookies are third party, don't even consider them. */ /* If cookies are third party, don't even consider them. */
char *server_date = Cache_parse_field(header, "Date"); char *server_date = Cache_parse_field(header, "Date");
a_Cookies_set(Cookies, entry->Url, server_date); a_Cookies_set(Cookies, entry->Url.get(), server_date);
dFree(server_date); dFree(server_date);
break; break;
} }
@ -811,8 +809,8 @@ static void Cache_parse_header(CacheEntry_t *entry)
if ((Type = Cache_parse_field(header, "Content-Type"))) { if ((Type = Cache_parse_field(header, "Content-Type"))) {
/* This HTTP Content-Type is not trusted. It's checked against real data /* This HTTP Content-Type is not trusted. It's checked against real data
* in Cache_process_queue(); only then CA_GotContentType becomes true. */ * in Cache_process_queue(); only then CA_GotContentType becomes true. */
a_Cache_set_content_type(entry->Url, Type, "http"); a_Cache_set_content_type(entry->Url.get(), Type, "http");
_MSG("TypeHdr {%s} {%s}\n", Type, URL_STR(entry->Url)); _MSG("TypeHdr {%s} {%s}\n", Type, URL_STR(entry->Url.get()));
_MSG("TypeMeta {%s}\n", entry->TypeMeta); _MSG("TypeMeta {%s}\n", entry->TypeMeta);
dFree(Type); dFree(Type);
} }
@ -868,7 +866,7 @@ static void Cache_finish_msg(CacheEntry_t *entry)
if ((entry->Flags & CA_GotLength) && if ((entry->Flags & CA_GotLength) &&
(entry->ExpectedSize != entry->TransferSize)) { (entry->ExpectedSize != entry->TransferSize)) {
MSG_HTTP("Content-Length (%d) does NOT match message body (%d) for %s\n", MSG_HTTP("Content-Length (%d) does NOT match message body (%d) for %s\n",
entry->ExpectedSize, entry->TransferSize, URL_STR_(entry->Url)); entry->ExpectedSize, entry->TransferSize, URL_STR_(entry->Url.get()));
} }
entry->Flags &= ~CA_InProgress; entry->Flags &= ~CA_InProgress;
if (entry->TransferDecoder) { if (entry->TransferDecoder) {
@ -971,14 +969,14 @@ bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
} else if (Op == IOAbort) { } else if (Op == IOAbort) {
entry->Flags |= CA_Aborted; entry->Flags |= CA_Aborted;
if (entry->Data->len) { if (entry->Data->len) {
MSG("Premature close for %s\n", URL_STR(entry->Url)); MSG("Premature close for %s\n", URL_STR(entry->Url.get()));
Cache_finish_msg(entry); Cache_finish_msg(entry);
} else { } else {
int i; int i;
CacheClient_t *Client; CacheClient_t *Client;
for (i = 0; (Client = reinterpret_cast< CacheClient_t * >( dList_nth_data(ClientQueue, i) )); ++i) { for (i = 0; (Client = reinterpret_cast< CacheClient_t * >( dList_nth_data(ClientQueue, i) )); ++i) {
if (Client->Url == entry->Url) { if (Client->Url == entry->Url.get()) {
DilloWeb *web = (DilloWeb *)Client->Web; DilloWeb *web = (DilloWeb *)Client->Web;
a_Bw_remove_client(web->bw, Client->Key); a_Bw_remove_client(web->bw, Client->Key);
@ -1010,7 +1008,7 @@ static int Cache_redirect(CacheEntry_t *entry, int Flags, BrowserWindow *bw)
entry->Flags |= CA_RedirectLoop; entry->Flags |= CA_RedirectLoop;
if (entry->Flags & CA_RedirectLoop) { if (entry->Flags & CA_RedirectLoop) {
a_UIcmd_set_msg(bw, "ERROR: redirect loop for: %s", URL_STR_(entry->Url)); a_UIcmd_set_msg(bw, "ERROR: redirect loop for: %s", URL_STR_(entry->Url.get()));
bw->redirect_level = 0; bw->redirect_level = 0;
return 0; return 0;
} }
@ -1025,10 +1023,10 @@ static int Cache_redirect(CacheEntry_t *entry, int Flags, BrowserWindow *bw)
if (Flags & WEB_RootUrl) { if (Flags & WEB_RootUrl) {
/* Redirection of the main page */ /* Redirection of the main page */
auto NewUrl = a_Url_new(URL_STR_(entry->Location), URL_STR_(entry->Url)); auto NewUrl = a_Url_new(URL_STR_(entry->Location.get()), URL_STR_(entry->Url.get()));
if (entry->Flags & CA_TempRedirect) if (entry->Flags & CA_TempRedirect)
a_Url_set_flags(NewUrl.get(), URL_FLAGS(NewUrl) | URL_E2EQuery); a_Url_set_flags(NewUrl.get(), URL_FLAGS(NewUrl) | URL_E2EQuery);
a_Nav_push(bw, NewUrl.get(), entry->Url); a_Nav_push(bw, NewUrl.get(), entry->Url.get());
} else { } else {
/* Sub entity redirection (most probably an image) */ /* Sub entity redirection (most probably an image) */
if (!entry->Data->len) { if (!entry->Data->len) {
@ -1077,7 +1075,7 @@ static void Cache_auth_entry(CacheEntry_t *entry, BrowserWindow *bw)
busy = 1; busy = 1;
data = dNew(CacheAuthData_t, 1); data = dNew(CacheAuthData_t, 1);
data->auth = entry->Auth; data->auth = entry->Auth;
data->url = a_Url_dup(entry->Url).release(); data->url = a_Url_dup(entry->Url.get()).release();
data->bw = bw; data->bw = bw;
entry->Auth = NULL; entry->Auth = NULL;
Timeout::add(0.0, [=]{ Cache_auth_callback( data ); } ); Timeout::add(0.0, [=]{ Cache_auth_callback( data ); } );
@ -1149,9 +1147,9 @@ static void Cache_provide_redirection_blocked_page(CacheEntry_t *entry,
&client->CbData); &client->CbData);
client->Buf = dStrconcat("<!doctype html><html><body>" client->Buf = dStrconcat("<!doctype html><html><body>"
"Flenser blocked a redirection from <a href=\"", "Flenser blocked a redirection from <a href=\"",
URL_STR(entry->Url), "\">", URL_STR(entry->Url), URL_STR(entry->Url.get()), "\">", URL_STR(entry->Url.get()),
"</a> to <a href=\"", URL_STR(entry->Location), "\">", "</a> to <a href=\"", URL_STR(entry->Location.get()), "\">",
URL_STR(entry->Location), "</a> based on your domainrc " URL_STR(entry->Location.get()), "</a> based on your domainrc "
"settings.</body></html>", NULL); "settings.</body></html>", NULL);
client->BufSize = strlen(reinterpret_cast< const char * >( client->Buf )); client->BufSize = strlen(reinterpret_cast< const char * >( client->Buf ));
(client->Callback)(CA_Send, client); (client->Callback)(CA_Send, client);
@ -1206,7 +1204,7 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
Busy = TRUE; Busy = TRUE;
for (i = 0; (Client = reinterpret_cast< CacheClient_t * >( dList_nth_data(ClientQueue, i) )); ++i) { for (i = 0; (Client = reinterpret_cast< CacheClient_t * >( dList_nth_data(ClientQueue, i) )); ++i) {
if (Client->Url == entry->Url) { if (Client->Url == entry->Url.get()) {
ClientWeb = reinterpret_cast< DilloWeb * >( Client->Web ); /* It was a (void*) */ ClientWeb = reinterpret_cast< DilloWeb * >( Client->Web ); /* It was a (void*) */
Client_bw = ClientWeb->bw; /* 'bw' in a local var */ Client_bw = ClientWeb->bw; /* 'bw' in a local var */
@ -1326,20 +1324,19 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
if (AbortEntry) { if (AbortEntry) {
/* Abort the entry, remove it from cache, and maybe offer download. */ /* Abort the entry, remove it from cache, and maybe offer download. */
DilloUrl *url = a_Url_dup(entry->Url).release(); auto url = a_Url_dup(entry->Url.get());
a_Capi_conn_abort_by_url(url); a_Capi_conn_abort_by_url(url.get());
entry = NULL; entry = NULL;
if (OfferDownload) { if (OfferDownload) {
/* Remove entry when 'conn' is already done */ /* Remove entry when 'conn' is already done */
Cache_entry_remove(NULL, url); Cache_entry_remove(NULL, url.get());
if (a_Cache_download_enabled(url)) { if (a_Cache_download_enabled(url.get())) {
Cache_savelink_t *data = dNew(Cache_savelink_t, 1); Cache_savelink_t *data = dNew(Cache_savelink_t, 1);
data->bw = Client_bw; data->bw = Client_bw;
data->url = a_Url_dup(url).release(); data->url = a_Url_dup(url.get()).release();
Timeout::add(0.0, [=]{ Cache_savelink_cb( data ); } ); Timeout::add(0.0, [=]{ Cache_savelink_cb( data ); } );
} }
} }
delete url;
} else if (entry->Auth && !(entry->Flags & CA_InProgress)) { } else if (entry->Auth && !(entry->Flags & CA_InProgress)) {
Cache_auth_entry(entry, Client_bw); Cache_auth_entry(entry, Client_bw);
} }