Skip to content

Commit

Permalink
trurl: support ?= for set, to only do it if not already set
Browse files Browse the repository at this point in the history
Idea-by: @emanuele6 in #296

Due to missing support in the libcurl URL API, this is not really
working for the scheme component right now, as that will always be
considered set once a URL has been parsed. The scheme guessing the
parser does sets it internally and there is currently no way provided by
the API to figure that out.

When the URL API has been extended, we can expand this functionality for
working better with scheme.

Closes #298
  • Loading branch information
bagder committed May 13, 2024
1 parent 4cc172c commit 13d7449
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 7 deletions.
28 changes: 28 additions & 0 deletions tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -2484,5 +2484,33 @@
"stderr": "",
"returncode": 0
}
},
{
"input": {
"arguments": [
"example.com:88",
"--set",
"port?=99"
]
},
"expected": {
"stdout": "http://example.com:88/\n",
"stderr": "",
"returncode": 0
}
},
{
"input": {
"arguments": [
"example.com",
"--set",
"port?=99"
]
},
"expected": {
"stdout": "http://example.com:99/\n",
"stderr": "",
"returncode": 0
}
}
]
5 changes: 5 additions & 0 deletions trurl.1
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ options, host, port, path, query, fragment and zoneid.
If a simple "="-assignment is used, the data is URL encoded when applied. If
":=" is used, the data is assumed to already be URL encoded and stored as-is.

If "?=" is used, the set is only performed if the component is not already
set. It avoids overwriting any already set data.

You can also combine : and ? into "?:=" if desired.

If no URL or \fI--url-file\fP argument is provided, trurl tries to create
a URL using the components provided by the \fI--set\fP options. If not enough
components are specified, this fails.
Expand Down
41 changes: 34 additions & 7 deletions trurl.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,20 +899,47 @@ static const struct var *setone(CURLU *uh, const char *setline,
if(ptr && (ptr > setline)) {
size_t vlen = ptr - setline;
bool urlencode = true;
bool conditional = false;
bool found = false;
if(ptr[-1] == ':') {
urlencode = false;
vlen--;
if(vlen) {
int back = -1;
size_t reqlen = 1;
while(vlen > reqlen) {
if(ptr[back] == ':') {
urlencode = false;
vlen--;
}
else if(ptr[back] == '?') {
conditional = true;
vlen--;
}
else
break;
reqlen++;
back--;
}
}
v = comp2var(setline, vlen);
if(v) {
CURLUcode rc;
CURLUcode rc = CURLUE_OK;
bool skip = false;
if((v->part == CURLUPART_HOST) && ('[' == ptr[1]))
/* when setting an IPv6 numerical address, disable URL encoding */
urlencode = false;
rc = curl_url_set(uh, v->part, ptr[1] ? &ptr[1] : NULL,
(o->curl ? 0 : CURLU_NON_SUPPORT_SCHEME)|
(urlencode ? CURLU_URLENCODE : 0) );

if(conditional) {
char *piece;
rc = curl_url_get(uh, v->part, &piece, 0);
if(!rc) {
skip = true;
curl_free(piece);
}
}

if(!skip)
rc = curl_url_set(uh, v->part, ptr[1] ? &ptr[1] : NULL,
(o->curl ? 0 : CURLU_NON_SUPPORT_SCHEME)|
(urlencode ? CURLU_URLENCODE : 0) );
if(rc)
warnf("Error setting %s: %s", v->name, curl_url_strerror(rc));
found = true;
Expand Down

0 comments on commit 13d7449

Please sign in to comment.