When set, curl_url_set(3) URL encodes the part on entry, except for
**scheme**, **port** and **URL**.
-When setting the path component with URL encoding enabled, the slash character
-is skipped.
+When setting the path component with URL encoding enabled, the following
+characters are left as-is if present:
+
+ ! $ & ' ( ) { } [ ] * + , ; = : @
The query part gets space-to-plus converted before the URL conversion is
applied.
return CURLUE_OK;
}
+static bool allowed_in_path(unsigned char x)
+{
+ switch(x) {
+ case '!': case '$': case '&': case '\'':
+ case '(': case ')': case '{': case '}':
+ case '[': case ']': case '*': case '+':
+ case ',': case ';': case '=': case ':':
+ case '@': case '/':
+ return TRUE;
+ }
+ return FALSE;
+}
+
CURLUcode curl_url_set(CURLU *u, CURLUPart what,
const char *part, unsigned int flags)
{
char **storep = NULL;
bool urlencode = (flags & CURLU_URLENCODE) ? 1 : 0;
bool plusencode = FALSE;
- bool urlskipslash = FALSE;
+ bool pathmode = FALSE;
bool leadingslash = FALSE;
bool appendquery = FALSE;
bool equalsencode = FALSE;
case CURLUPART_PORT:
return set_url_port(u, part);
case CURLUPART_PATH:
- urlskipslash = TRUE;
+ pathmode = TRUE;
leadingslash = TRUE; /* enforce */
storep = &u->path;
break;
return CURLUE_OUT_OF_MEMORY;
}
else if(ISUNRESERVED(*i) ||
- ((*i == '/') && urlskipslash) ||
+ (pathmode && allowed_in_path(*i)) ||
((*i == '=') && equalsencode)) {
if((*i == '=') && equalsencode)
/* only skip the first equals sign */
/* !checksrc! disable SPACEBEFORECOMMA 1 */
static const struct setcase set_parts_list[] = {
+ {"https://example.com/",
+ "path=one /$!$&'()*+;=:@{}[]%,",
+ "https://example.com/one%20/$!$&'()*+;=:@{}[]%25",
+ 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
{NULL, /* start fresh! */
"scheme=https,path=/,url=\"\",", /* incomplete url, redirect to "" */
"https://example.com/",