Move more internal URL stuff to RAII.
This commit is contained in:
114
src/url.cc
114
src/url.cc
@ -52,6 +52,7 @@
|
||||
#include "msg.hh"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
static const char *HEX = "0123456789ABCDEF";
|
||||
|
||||
@ -72,24 +73,21 @@ char *a_Url_str(const DilloUrl *u)
|
||||
|
||||
dReturn_val_if_fail (url != NULL, NULL);
|
||||
|
||||
if (!url->url_string) {
|
||||
url->url_string = dStr_sized_new(60);
|
||||
dStr_sprintf(
|
||||
url->url_string, "%s%s%s%s%s%s%s%s%s%s",
|
||||
url->scheme ? url->scheme : "",
|
||||
url->scheme ? ":" : "",
|
||||
url->authority ? "//" : "",
|
||||
url->authority ? url->authority : "",
|
||||
// (url->path && url->path[0] != '/' && url->authority) ? "/" : "",
|
||||
(url->authority && (!url->path || *url->path != '/')) ? "/" : "",
|
||||
url->path ? url->path : "",
|
||||
url->query ? "?" : "",
|
||||
url->query ? url->query : "",
|
||||
url->fragment ? "#" : "",
|
||||
url->fragment ? url->fragment : "");
|
||||
if (!url->url_string.has_value()) {
|
||||
url->url_string= url->scheme ? url->scheme : "";
|
||||
url->url_string.value()+= url->scheme ? ":" : "";
|
||||
url->url_string.value()+= url->authority ? "//" : "";
|
||||
url->url_string.value()+= url->authority ? url->authority : "";
|
||||
url->url_string.value()+= // (url->path && url->path[0] != '/' && url->authority) ? "/" : "",
|
||||
url->url_string.value()+= (url->authority && (!url->path || *url->path != '/')) ? "/" : "";
|
||||
url->url_string.value()+= url->path ? url->path : "";
|
||||
url->url_string.value()+= url->query ? "?" : "";
|
||||
url->url_string.value()+= url->query ? url->query : "";
|
||||
url->url_string.value()+= url->fragment ? "#" : "";
|
||||
url->url_string.value()+= 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()
|
||||
{
|
||||
if (this->url_string)
|
||||
dStr_free(this->url_string, TRUE);
|
||||
if (this->hostname != this->authority)
|
||||
dFree((char *)this->hostname);
|
||||
dFree((char *)this->buffer);
|
||||
@ -219,49 +215,47 @@ DilloUrl::~DilloUrl()
|
||||
/**
|
||||
* 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 *p, *s, *e;
|
||||
int i;
|
||||
Dstr *SolvedUrl;
|
||||
std::string SolvedUrl;
|
||||
std::string Path;
|
||||
DilloUrl *RelUrl, *BaseUrl = NULL;
|
||||
std::unique_ptr< DilloUrl > BaseUrl;
|
||||
|
||||
/* parse relative URL */
|
||||
RelUrl = Url_object_new(RelStr);
|
||||
std::unique_ptr< DilloUrl > RelUrl{ Url_object_new(RelStr) };
|
||||
|
||||
if (RelUrl->scheme == NULL) {
|
||||
/* 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 */
|
||||
if (!RelUrl->path && !RelUrl->scheme && !RelUrl->authority) {
|
||||
dStr_append(SolvedUrl, BaseStr);
|
||||
if ((p = strchr(SolvedUrl->str, '#')))
|
||||
dStr_truncate(SolvedUrl, p - SolvedUrl->str);
|
||||
SolvedUrl+= BaseStr;
|
||||
if ((p = strchr(SolvedUrl.c_str(), '#')))
|
||||
while( SolvedUrl.size() > ( p - SolvedUrl.c_str() ) ) SolvedUrl.pop_back();
|
||||
if (!BaseUrl->path)
|
||||
dStr_append_c(SolvedUrl, '/');
|
||||
SolvedUrl+= '/';
|
||||
|
||||
if (RelUrl->query) { /* query */
|
||||
if (BaseUrl->query)
|
||||
dStr_truncate(SolvedUrl, BaseUrl->query - BaseUrl->buffer - 1);
|
||||
dStr_append_c(SolvedUrl, '?');
|
||||
dStr_append(SolvedUrl, RelUrl->query);
|
||||
while( SolvedUrl.size() > BaseUrl->query - BaseUrl->buffer - 1 ) SolvedUrl.pop_back();
|
||||
SolvedUrl+= '?';
|
||||
SolvedUrl+= RelUrl->query;
|
||||
}
|
||||
if (RelUrl->fragment) { /* fragment */
|
||||
dStr_append_c(SolvedUrl, '#');
|
||||
dStr_append(SolvedUrl, RelUrl->fragment);
|
||||
SolvedUrl+= '#';
|
||||
SolvedUrl+= RelUrl->fragment;
|
||||
}
|
||||
goto done;
|
||||
|
||||
return SolvedUrl;
|
||||
} else if (RelUrl->scheme) { /* scheme */
|
||||
dStr_append(SolvedUrl, RelStr);
|
||||
goto done;
|
||||
SolvedUrl+= RelStr;
|
||||
|
||||
return SolvedUrl;
|
||||
} else if (RelUrl->authority) { /* authority */
|
||||
// Set the Path buffer and goto "STEP 7";
|
||||
if (RelUrl->path)
|
||||
@ -308,41 +302,38 @@ static Dstr *Url_resolve_relative(const char *RelStr,
|
||||
|
||||
/* scheme */
|
||||
if (BaseUrl->scheme) {
|
||||
dStr_append(SolvedUrl, BaseUrl->scheme);
|
||||
dStr_append_c(SolvedUrl, ':');
|
||||
SolvedUrl+= BaseUrl->scheme;
|
||||
SolvedUrl+= ':';
|
||||
}
|
||||
|
||||
/* authority */
|
||||
if (RelUrl->authority) {
|
||||
dStr_append(SolvedUrl, "//");
|
||||
dStr_append(SolvedUrl, RelUrl->authority);
|
||||
SolvedUrl+= "//";
|
||||
SolvedUrl+= RelUrl->authority;
|
||||
} else if (BaseUrl->authority) {
|
||||
dStr_append(SolvedUrl, "//");
|
||||
dStr_append(SolvedUrl, BaseUrl->authority);
|
||||
SolvedUrl+= "//";
|
||||
SolvedUrl+= BaseUrl->authority;
|
||||
}
|
||||
|
||||
/* path */
|
||||
if ((RelUrl->authority || BaseUrl->authority) &&
|
||||
((Path.size() == 0 && (RelUrl->query || RelUrl->fragment)) ||
|
||||
(Path.size() && Path.at(0) != '/')))
|
||||
dStr_append_c(SolvedUrl, '/'); /* hack? */
|
||||
dStr_append(SolvedUrl, Path.c_str());
|
||||
SolvedUrl+= '/'; /* hack? */
|
||||
SolvedUrl+= Path.c_str();
|
||||
|
||||
/* query */
|
||||
if (RelUrl->query) {
|
||||
dStr_append_c(SolvedUrl, '?');
|
||||
dStr_append(SolvedUrl, RelUrl->query);
|
||||
SolvedUrl+= '?';
|
||||
SolvedUrl+= RelUrl->query;
|
||||
}
|
||||
|
||||
/* fragment */
|
||||
if (RelUrl->fragment) {
|
||||
dStr_append_c(SolvedUrl, '#');
|
||||
dStr_append(SolvedUrl, RelUrl->fragment);
|
||||
SolvedUrl+= '#';
|
||||
SolvedUrl+= RelUrl->fragment;
|
||||
}
|
||||
|
||||
done:
|
||||
delete RelUrl;
|
||||
delete BaseUrl;
|
||||
return SolvedUrl;
|
||||
}
|
||||
|
||||
@ -373,7 +364,7 @@ DilloUrl* a_Url_new(const char *url_str, const char *base_url)
|
||||
DilloUrl *url;
|
||||
char *urlstr = (char *)url_str; /* auxiliary variable, don't free */
|
||||
char *p, *str1 = NULL, *str2 = NULL;
|
||||
Dstr *SolvedUrl;
|
||||
std::string SolvedUrl;
|
||||
int i, n_ic, n_ic_spc;
|
||||
|
||||
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);
|
||||
|
||||
/* Fill url data */
|
||||
url = Url_object_new(SolvedUrl->str);
|
||||
url = Url_object_new(SolvedUrl.c_str());
|
||||
url->data = "";
|
||||
url->url_string = SolvedUrl;
|
||||
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 = NULL;
|
||||
url->url_string.reset();
|
||||
}
|
||||
|
||||
return url;
|
||||
@ -481,7 +471,7 @@ DilloUrl* a_Url_dup(const DilloUrl *ori)
|
||||
url = Url_object_new(URL_STR_(ori));
|
||||
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->flags = ori->flags;
|
||||
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) {
|
||||
/* 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) {
|
||||
dStr_truncate(u->url_string, u->ismap_url_len);
|
||||
dStr_append(u->url_string, coord_str);
|
||||
u->query = u->url_string->str + u->ismap_url_len + 1;
|
||||
if (u->url_string.has_value()) {
|
||||
while( u->url_string.value().size() > u->ismap_url_len ) u->url_string.value().pop_back();
|
||||
u->url_string.value()+= coord_str;
|
||||
u->query = u->url_string.value().c_str() + u->ismap_url_len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
extern "C++"
|
||||
{
|
||||
#include <string>
|
||||
#include <optional>
|
||||
}
|
||||
|
||||
|
||||
@ -93,7 +94,7 @@ extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct DilloUrl {
|
||||
Dstr *url_string;
|
||||
std::optional< std::string > url_string;
|
||||
const char *buffer;
|
||||
const char *scheme; /**/
|
||||
const char *authority; /**/
|
||||
|
Reference in New Issue
Block a user