1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-15 14:05:03 -05:00

urlapi: CURLU_NO_AUTHORITY allows empty authority/host part

CURLU_NO_AUTHORITY is intended for use with unknown schemes (i.e. not
"file:///") to override cURL's default demand that an authority exists.

Closes #4349
This commit is contained in:
Jens Finkhaeuser 2019-09-19 15:54:53 +02:00 committed by Daniel Stenberg
parent 346188f6e4
commit 0a4ecbdf1c
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 57 additions and 11 deletions

View File

@ -111,6 +111,12 @@ instead "guesses" which scheme that was intended based on the host name. If
the outermost sub-domain name matches DICT, FTP, IMAP, LDAP, POP3 or SMTP then the outermost sub-domain name matches DICT, FTP, IMAP, LDAP, POP3 or SMTP then
that scheme will be used, otherwise it picks HTTP. Conflicts with the that scheme will be used, otherwise it picks HTTP. Conflicts with the
\fICURLU_DEFAULT_SCHEME\fP option which takes precedence if both are set. \fICURLU_DEFAULT_SCHEME\fP option which takes precedence if both are set.
.IP CURLU_NO_AUTHORITY
If set, skips authority checks. The RFC allows individual schemes to omit the
host part (normally the only mandatory part of the authority), but libcurl
cannot know whether this is permitted for custom schemes. Specifying the flag
permits empty authority sections, similar to how file scheme is handled.
.SH RETURN VALUE .SH RETURN VALUE
Returns a CURLUcode error value, which is CURLUE_OK (0) if everything went Returns a CURLUcode error value, which is CURLUE_OK (0) if everything went
fine. fine.

View File

@ -779,6 +779,7 @@ CURLU_DISALLOW_USER 7.62.0
CURLU_GUESS_SCHEME 7.62.0 CURLU_GUESS_SCHEME 7.62.0
CURLU_NON_SUPPORT_SCHEME 7.62.0 CURLU_NON_SUPPORT_SCHEME 7.62.0
CURLU_NO_DEFAULT_PORT 7.62.0 CURLU_NO_DEFAULT_PORT 7.62.0
CURLU_NO_AUTHORITY 7.67.0
CURLU_PATH_AS_IS 7.62.0 CURLU_PATH_AS_IS 7.62.0
CURLU_URLDECODE 7.62.0 CURLU_URLDECODE 7.62.0
CURLU_URLENCODE 7.62.0 CURLU_URLENCODE 7.62.0

View File

@ -77,6 +77,8 @@ typedef enum {
#define CURLU_URLENCODE (1<<7) /* URL encode on set */ #define CURLU_URLENCODE (1<<7) /* URL encode on set */
#define CURLU_APPENDQUERY (1<<8) /* append a form style part */ #define CURLU_APPENDQUERY (1<<8) /* append a form style part */
#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ #define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
scheme is unknown. */
typedef struct Curl_URL CURLU; typedef struct Curl_URL CURLU;

View File

@ -784,6 +784,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(junkscan(schemep)) if(junkscan(schemep))
return CURLUE_MALFORMED_INPUT; return CURLUE_MALFORMED_INPUT;
} }
else { else {
/* no scheme! */ /* no scheme! */
@ -804,11 +805,14 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
p++; p++;
len = p - hostp; len = p - hostp;
if(!len) if(len) {
return CURLUE_MALFORMED_INPUT;
memcpy(hostname, hostp, len); memcpy(hostname, hostp, len);
hostname[len] = 0; hostname[len] = 0;
}
else {
if(!(flags & CURLU_NO_AUTHORITY))
return CURLUE_MALFORMED_INPUT;
}
if((flags & CURLU_GUESS_SCHEME) && !schemep) { if((flags & CURLU_GUESS_SCHEME) && !schemep) {
/* legacy curl-style guess based on host name */ /* legacy curl-style guess based on host name */
@ -889,9 +893,14 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(result) if(result)
return result; return result;
if(0 == strlen(hostname) && (flags & CURLU_NO_AUTHORITY)) {
/* Skip hostname check, it's allowed to be empty. */
}
else {
result = hostname_check(u, hostname); result = hostname_check(u, hostname);
if(result) if(result)
return result; return result;
}
u->host = strdup(hostname); u->host = strdup(hostname);
if(!u->host) if(!u->host)
@ -1432,11 +1441,16 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
} }
if(what == CURLUPART_HOST) { if(what == CURLUPART_HOST) {
if(0 == strlen(newp) && (flags & CURLU_NO_AUTHORITY)) {
/* Skip hostname check, it's allowed to be empty. */
}
else {
if(hostname_check(u, (char *)newp)) { if(hostname_check(u, (char *)newp)) {
free((char *)newp); free((char *)newp);
return CURLUE_MALFORMED_INPUT; return CURLUE_MALFORMED_INPUT;
} }
} }
}
free(*storep); free(*storep);
*storep = (char *)newp; *storep = (char *)newp;

View File

@ -414,6 +414,18 @@ static struct urltestcase get_url_list[] = {
{"tp://example.com/path/html", {"tp://example.com/path/html",
"tp://example.com/path/html", "tp://example.com/path/html",
CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
{"custom-scheme://host?expected=test-good",
"custom-scheme://host/?expected=test-good",
CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
{"custom-scheme://?expected=test-bad",
"",
CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
{"custom-scheme://?expected=test-new-good",
"custom-scheme:///?expected=test-new-good",
CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK},
{"custom-scheme://host?expected=test-still-good",
"custom-scheme://host/?expected=test-still-good",
CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK},
{NULL, NULL, 0, 0, 0} {NULL, NULL, 0, 0, 0}
}; };
@ -551,6 +563,17 @@ static struct setcase set_parts_list[] = {
"scheme=ftp,", "scheme=ftp,",
"ftp://example.com:80/", "ftp://example.com:80/",
0, 0, CURLUE_OK, CURLUE_OK}, 0, 0, CURLUE_OK, CURLUE_OK},
{"custom-scheme://host",
"host=\"\",",
"custom-scheme://host/",
CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK,
CURLUE_MALFORMED_INPUT},
{"custom-scheme://host",
"host=\"\",",
"custom-scheme:///",
CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY,
CURLUE_OK, CURLUE_OK},
{NULL, NULL, NULL, 0, 0, 0, 0} {NULL, NULL, NULL, 0, 0, 0, 0}
}; };