Move more internal URL stuff to RAII.

This commit is contained in:
2025-04-13 00:31:27 -04:00
parent a189fff1ad
commit 4005fa7e14
2 changed files with 54 additions and 63 deletions

View File

@ -52,6 +52,7 @@
#include "msg.hh" #include "msg.hh"
#include <string> #include <string>
#include <memory>
static const char *HEX = "0123456789ABCDEF"; static const char *HEX = "0123456789ABCDEF";
@ -72,24 +73,21 @@ char *a_Url_str(const DilloUrl *u)
dReturn_val_if_fail (url != NULL, NULL); dReturn_val_if_fail (url != NULL, NULL);
if (!url->url_string) { if (!url->url_string.has_value()) {
url->url_string = dStr_sized_new(60); url->url_string= url->scheme ? url->scheme : "";
dStr_sprintf( url->url_string.value()+= url->scheme ? ":" : "";
url->url_string, "%s%s%s%s%s%s%s%s%s%s", url->url_string.value()+= url->authority ? "//" : "";
url->scheme ? url->scheme : "", url->url_string.value()+= url->authority ? url->authority : "";
url->scheme ? ":" : "", url->url_string.value()+= // (url->path && url->path[0] != '/' && url->authority) ? "/" : "",
url->authority ? "//" : "", url->url_string.value()+= (url->authority && (!url->path || *url->path != '/')) ? "/" : "";
url->authority ? url->authority : "", url->url_string.value()+= url->path ? url->path : "";
// (url->path && url->path[0] != '/' && url->authority) ? "/" : "", url->url_string.value()+= url->query ? "?" : "";
(url->authority && (!url->path || *url->path != '/')) ? "/" : "", url->url_string.value()+= url->query ? url->query : "";
url->path ? url->path : "", url->url_string.value()+= url->fragment ? "#" : "";
url->query ? "?" : "", url->url_string.value()+= url->fragment ? url->fragment : "";
url->query ? url->query : "",
url->fragment ? "#" : "",
url->fragment ? url->fragment : "");
} }
return url->url_string->str; return url->url_string.value().data();
} }
/** /**
@ -209,8 +207,6 @@ static DilloUrl *Url_object_new(const char *uri_str)
*/ */
DilloUrl::~DilloUrl() DilloUrl::~DilloUrl()
{ {
if (this->url_string)
dStr_free(this->url_string, TRUE);
if (this->hostname != this->authority) if (this->hostname != this->authority)
dFree((char *)this->hostname); dFree((char *)this->hostname);
dFree((char *)this->buffer); dFree((char *)this->buffer);
@ -219,49 +215,47 @@ DilloUrl::~DilloUrl()
/** /**
* Resolve the URL as RFC3986 suggests. * Resolve the URL as RFC3986 suggests.
*/ */
static Dstr *Url_resolve_relative(const char *RelStr, static std::string Url_resolve_relative(const char *RelStr,
const char *BaseStr) const char *BaseStr)
{ {
const char *p, *s, *e; const char *p, *s, *e;
int i; int i;
Dstr *SolvedUrl; std::string SolvedUrl;
std::string Path; std::string Path;
DilloUrl *RelUrl, *BaseUrl = NULL; std::unique_ptr< DilloUrl > BaseUrl;
/* parse relative URL */ /* parse relative URL */
RelUrl = Url_object_new(RelStr); std::unique_ptr< DilloUrl > RelUrl{ Url_object_new(RelStr) };
if (RelUrl->scheme == NULL) { if (RelUrl->scheme == NULL) {
/* only required when there's no <scheme> in RelStr */ /* only required when there's no <scheme> in RelStr */
BaseUrl = Url_object_new(BaseStr); BaseUrl.reset( Url_object_new(BaseStr) );
} }
SolvedUrl = dStr_sized_new(64);
/* path empty && scheme and authority undefined */ /* path empty && scheme and authority undefined */
if (!RelUrl->path && !RelUrl->scheme && !RelUrl->authority) { if (!RelUrl->path && !RelUrl->scheme && !RelUrl->authority) {
dStr_append(SolvedUrl, BaseStr); SolvedUrl+= BaseStr;
if ((p = strchr(SolvedUrl->str, '#'))) if ((p = strchr(SolvedUrl.c_str(), '#')))
dStr_truncate(SolvedUrl, p - SolvedUrl->str); while( SolvedUrl.size() > ( p - SolvedUrl.c_str() ) ) SolvedUrl.pop_back();
if (!BaseUrl->path) if (!BaseUrl->path)
dStr_append_c(SolvedUrl, '/'); SolvedUrl+= '/';
if (RelUrl->query) { /* query */ if (RelUrl->query) { /* query */
if (BaseUrl->query) if (BaseUrl->query)
dStr_truncate(SolvedUrl, BaseUrl->query - BaseUrl->buffer - 1); while( SolvedUrl.size() > BaseUrl->query - BaseUrl->buffer - 1 ) SolvedUrl.pop_back();
dStr_append_c(SolvedUrl, '?'); SolvedUrl+= '?';
dStr_append(SolvedUrl, RelUrl->query); SolvedUrl+= RelUrl->query;
} }
if (RelUrl->fragment) { /* fragment */ if (RelUrl->fragment) { /* fragment */
dStr_append_c(SolvedUrl, '#'); SolvedUrl+= '#';
dStr_append(SolvedUrl, RelUrl->fragment); SolvedUrl+= RelUrl->fragment;
} }
goto done;
return SolvedUrl;
} else if (RelUrl->scheme) { /* scheme */ } else if (RelUrl->scheme) { /* scheme */
dStr_append(SolvedUrl, RelStr); SolvedUrl+= RelStr;
goto done;
return SolvedUrl;
} else if (RelUrl->authority) { /* authority */ } else if (RelUrl->authority) { /* authority */
// Set the Path buffer and goto "STEP 7"; // Set the Path buffer and goto "STEP 7";
if (RelUrl->path) if (RelUrl->path)
@ -308,41 +302,38 @@ static Dstr *Url_resolve_relative(const char *RelStr,
/* scheme */ /* scheme */
if (BaseUrl->scheme) { if (BaseUrl->scheme) {
dStr_append(SolvedUrl, BaseUrl->scheme); SolvedUrl+= BaseUrl->scheme;
dStr_append_c(SolvedUrl, ':'); SolvedUrl+= ':';
} }
/* authority */ /* authority */
if (RelUrl->authority) { if (RelUrl->authority) {
dStr_append(SolvedUrl, "//"); SolvedUrl+= "//";
dStr_append(SolvedUrl, RelUrl->authority); SolvedUrl+= RelUrl->authority;
} else if (BaseUrl->authority) { } else if (BaseUrl->authority) {
dStr_append(SolvedUrl, "//"); SolvedUrl+= "//";
dStr_append(SolvedUrl, BaseUrl->authority); SolvedUrl+= BaseUrl->authority;
} }
/* path */ /* path */
if ((RelUrl->authority || BaseUrl->authority) && if ((RelUrl->authority || BaseUrl->authority) &&
((Path.size() == 0 && (RelUrl->query || RelUrl->fragment)) || ((Path.size() == 0 && (RelUrl->query || RelUrl->fragment)) ||
(Path.size() && Path.at(0) != '/'))) (Path.size() && Path.at(0) != '/')))
dStr_append_c(SolvedUrl, '/'); /* hack? */ SolvedUrl+= '/'; /* hack? */
dStr_append(SolvedUrl, Path.c_str()); SolvedUrl+= Path.c_str();
/* query */ /* query */
if (RelUrl->query) { if (RelUrl->query) {
dStr_append_c(SolvedUrl, '?'); SolvedUrl+= '?';
dStr_append(SolvedUrl, RelUrl->query); SolvedUrl+= RelUrl->query;
} }
/* fragment */ /* fragment */
if (RelUrl->fragment) { if (RelUrl->fragment) {
dStr_append_c(SolvedUrl, '#'); SolvedUrl+= '#';
dStr_append(SolvedUrl, RelUrl->fragment); SolvedUrl+= RelUrl->fragment;
} }
done:
delete RelUrl;
delete BaseUrl;
return SolvedUrl; return SolvedUrl;
} }
@ -373,7 +364,7 @@ DilloUrl* a_Url_new(const char *url_str, const char *base_url)
DilloUrl *url; DilloUrl *url;
char *urlstr = (char *)url_str; /* auxiliary variable, don't free */ char *urlstr = (char *)url_str; /* auxiliary variable, don't free */
char *p, *str1 = NULL, *str2 = NULL; char *p, *str1 = NULL, *str2 = NULL;
Dstr *SolvedUrl; std::string SolvedUrl;
int i, n_ic, n_ic_spc; int i, n_ic, n_ic_spc;
if (!url_str) if (!url_str)
@ -422,7 +413,7 @@ DilloUrl* a_Url_new(const char *url_str, const char *base_url)
_MSG("SolvedUrl = %s\n", SolvedUrl->str); _MSG("SolvedUrl = %s\n", SolvedUrl->str);
/* Fill url data */ /* Fill url data */
url = Url_object_new(SolvedUrl->str); url = Url_object_new(SolvedUrl.c_str());
url->data = ""; url->data = "";
url->url_string = SolvedUrl; url->url_string = SolvedUrl;
url->illegal_chars = n_ic; url->illegal_chars = n_ic;
@ -463,8 +454,7 @@ DilloUrl* a_Url_new(const char *url_str, const char *base_url)
} }
} }
dStr_free(url->url_string, TRUE); url->url_string.reset();
url->url_string = NULL;
} }
return url; return url;
@ -481,7 +471,7 @@ DilloUrl* a_Url_dup(const DilloUrl *ori)
url = Url_object_new(URL_STR_(ori)); url = Url_object_new(URL_STR_(ori));
dReturn_val_if_fail (url != NULL, NULL); dReturn_val_if_fail (url != NULL, NULL);
url->url_string = dStr_new(URL_STR(ori)); url->url_string = URL_STR(ori);
url->port = ori->port; url->port = ori->port;
url->flags = ori->flags; url->flags = ori->flags;
url->ismap_url_len = ori->ismap_url_len; url->ismap_url_len = ori->ismap_url_len;
@ -547,12 +537,12 @@ void a_Url_set_ismap_coords(DilloUrl *u, char *coord_str)
if (!u->ismap_url_len) { if (!u->ismap_url_len) {
/* Save base-url length (without coords) */ /* Save base-url length (without coords) */
u->ismap_url_len = URL_STR_(u) ? u->url_string->len : 0; u->ismap_url_len = URL_STR_(u) ? u->url_string.value().size() : 0;
} }
if (u->url_string) { if (u->url_string.has_value()) {
dStr_truncate(u->url_string, u->ismap_url_len); while( u->url_string.value().size() > u->ismap_url_len ) u->url_string.value().pop_back();
dStr_append(u->url_string, coord_str); u->url_string.value()+= coord_str;
u->query = u->url_string->str + u->ismap_url_len + 1; u->query = u->url_string.value().c_str() + u->ismap_url_len + 1;
} }
} }

View File

@ -18,6 +18,7 @@
extern "C++" extern "C++"
{ {
#include <string> #include <string>
#include <optional>
} }
@ -93,7 +94,7 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
struct DilloUrl { struct DilloUrl {
Dstr *url_string; std::optional< std::string > url_string;
const char *buffer; const char *buffer;
const char *scheme; /**/ const char *scheme; /**/
const char *authority; /**/ const char *authority; /**/