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();
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 *TypeHdr; /**< MIME type string as from the HTTP Header */
char *TypeMeta; /**< MIME type string from META HTTP-EQUIV */
char *TypeNorm; /**< MIME type string normalized */
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 */
Dstr *Data; /**< Pointer to raw data */
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 );
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)
{
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 );
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)
{
NewEntry->Url = a_Url_dup(Url).release();
NewEntry->Url = a_Url_dup(Url);
NewEntry->TypeDet = NULL;
NewEntry->TypeHdr = NULL;
NewEntry->TypeMeta = NULL;
@ -238,7 +238,7 @@ static CacheEntry_t *Cache_entry_search_with_redirect(const DilloUrl *Url)
}
/* Test for a working redirection */
if (entry->Flags & CA_Redirect && entry->Location) {
Url = entry->Location;
Url = entry->Location.get();
} else
break;
}
@ -300,13 +300,11 @@ static void Cache_auth_free(Dlist *auth)
CacheEntry_t::~CacheEntry_t()
{
auto *const entry= this;
delete const_cast< DilloUrl * >( entry->Url );
dFree(entry->TypeDet);
dFree(entry->TypeHdr);
dFree(entry->TypeMeta);
dFree(entry->TypeNorm);
dStr_free(entry->Header, TRUE);
delete const_cast< DilloUrl * >( entry->Location );
Cache_auth_free(entry->Auth);
dStr_free(entry->Data, 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 */
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);
--i;
}
@ -345,7 +343,7 @@ static void Cache_entry_remove(CacheEntry_t *entry, DilloUrl *url)
dList_remove(DelayedQueue, entry);
/* remove from dicache */
a_Dicache_invalidate_entry(entry->Url);
a_Dicache_invalidate_entry(entry->Url.get());
/* remove from cache */
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))) {
/* 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);
} else {
/* URL not cached: create an entry, send our client to the queue,
* and open a new connection */
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;
@ -685,9 +683,9 @@ static void Cache_parse_header(CacheEntry_t *entry)
if (header[9] == '3' && header[10] == '0' &&
(location_str = Cache_parse_field(header, "Location"))) {
/* 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) &&
dStrAsciiCasecmp(URL_SCHEME(entry->Location), "dpi") == 0 &&
dStrAsciiCasecmp(URL_SCHEME(entry->Url), "dpi") != 0)) {
@ -695,7 +693,7 @@ static void Cache_parse_header(CacheEntry_t *entry)
* urls.
*/
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 {
entry->Flags |= CA_Redirect;
if (header[11] == '1')
@ -732,10 +730,10 @@ static void Cache_parse_header(CacheEntry_t *entry)
}
if (prefs.http_strict_transport_security &&
!dStrAsciiCasecmp(URL_SCHEME(entry->Url), "https") &&
a_Url_host_type(URL_HOST(entry->Url)) == URL_HOST_NAME &&
!dStrAsciiCasecmp(URL_SCHEME(entry->Url.get()), "https") &&
a_Url_host_type(URL_HOST(entry->Url.get())) == URL_HOST_NAME &&
(hsts = Cache_parse_field(header, "Strict-Transport-Security"))) {
a_Hsts_set(hsts, entry->Url);
a_Hsts_set(hsts, entry->Url.get());
dFree(hsts);
}
@ -769,7 +767,7 @@ static void Cache_parse_header(CacheEntry_t *entry)
CacheClient_t *client;
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 );
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. */
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);
break;
}
@ -811,8 +809,8 @@ static void Cache_parse_header(CacheEntry_t *entry)
if ((Type = Cache_parse_field(header, "Content-Type"))) {
/* This HTTP Content-Type is not trusted. It's checked against real data
* in Cache_process_queue(); only then CA_GotContentType becomes true. */
a_Cache_set_content_type(entry->Url, Type, "http");
_MSG("TypeHdr {%s} {%s}\n", Type, URL_STR(entry->Url));
a_Cache_set_content_type(entry->Url.get(), Type, "http");
_MSG("TypeHdr {%s} {%s}\n", Type, URL_STR(entry->Url.get()));
_MSG("TypeMeta {%s}\n", entry->TypeMeta);
dFree(Type);
}
@ -868,7 +866,7 @@ static void Cache_finish_msg(CacheEntry_t *entry)
if ((entry->Flags & CA_GotLength) &&
(entry->ExpectedSize != entry->TransferSize)) {
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;
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) {
entry->Flags |= CA_Aborted;
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);
} else {
int i;
CacheClient_t *Client;
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;
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;
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;
return 0;
}
@ -1025,10 +1023,10 @@ static int Cache_redirect(CacheEntry_t *entry, int Flags, BrowserWindow *bw)
if (Flags & WEB_RootUrl) {
/* 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)
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 {
/* Sub entity redirection (most probably an image) */
if (!entry->Data->len) {
@ -1077,7 +1075,7 @@ static void Cache_auth_entry(CacheEntry_t *entry, BrowserWindow *bw)
busy = 1;
data = dNew(CacheAuthData_t, 1);
data->auth = entry->Auth;
data->url = a_Url_dup(entry->Url).release();
data->url = a_Url_dup(entry->Url.get()).release();
data->bw = bw;
entry->Auth = NULL;
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->Buf = dStrconcat("<!doctype html><html><body>"
"Flenser blocked a redirection from <a href=\"",
URL_STR(entry->Url), "\">", URL_STR(entry->Url),
"</a> to <a href=\"", URL_STR(entry->Location), "\">",
URL_STR(entry->Location), "</a> based on your domainrc "
URL_STR(entry->Url.get()), "\">", URL_STR(entry->Url.get()),
"</a> to <a href=\"", URL_STR(entry->Location.get()), "\">",
URL_STR(entry->Location.get()), "</a> based on your domainrc "
"settings.</body></html>", NULL);
client->BufSize = strlen(reinterpret_cast< const char * >( client->Buf ));
(client->Callback)(CA_Send, client);
@ -1206,7 +1204,7 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
Busy = TRUE;
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*) */
Client_bw = ClientWeb->bw; /* 'bw' in a local var */
@ -1326,20 +1324,19 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
if (AbortEntry) {
/* Abort the entry, remove it from cache, and maybe offer download. */
DilloUrl *url = a_Url_dup(entry->Url).release();
a_Capi_conn_abort_by_url(url);
auto url = a_Url_dup(entry->Url.get());
a_Capi_conn_abort_by_url(url.get());
entry = NULL;
if (OfferDownload) {
/* Remove entry when 'conn' is already done */
Cache_entry_remove(NULL, url);
if (a_Cache_download_enabled(url)) {
Cache_entry_remove(NULL, url.get());
if (a_Cache_download_enabled(url.get())) {
Cache_savelink_t *data = dNew(Cache_savelink_t, 1);
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 ); } );
}
}
delete url;
} else if (entry->Auth && !(entry->Flags & CA_InProgress)) {
Cache_auth_entry(entry, Client_bw);
}