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 "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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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; /**/
|
||||||
|
|||||||
Reference in New Issue
Block a user