setopt: add CURLOPT_PROTOCOLS_STR and CURLOPT_REDIR_PROTOCOLS_STR

... as replacements for deprecated CURLOPT_PROTOCOLS and
CURLOPT_REDIR_PROTOCOLS as these new ones do not risk running into the
32 bit limit the old ones are facing.

CURLINFO_PROTCOOL is now deprecated.

The curl tool is updated to use the new options.

Added test 1597 to verify the libcurl protocol parser.

Closes #8992
This commit is contained in:
Daniel Stenberg 2022-06-13 09:30:45 +02:00
parent 193215db3c
commit e6f8445ede
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
24 changed files with 487 additions and 45 deletions

View file

@ -148,6 +148,85 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
#define C_SSLVERSION_VALUE(x) (x & 0xffff)
#define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
static CURLcode protocol2num(char *str, curl_off_t *val)
{
bool found_comma = FALSE;
static struct scheme {
const char *name;
long bit;
} const protos[] = {
{ "dict", CURLPROTO_DICT },
{ "file", CURLPROTO_FILE },
{ "ftp", CURLPROTO_FTP },
{ "ftps", CURLPROTO_FTPS },
{ "gopher", CURLPROTO_GOPHER },
{ "gophers", CURLPROTO_GOPHERS },
{ "http", CURLPROTO_HTTP },
{ "https", CURLPROTO_HTTPS },
{ "imap", CURLPROTO_IMAP },
{ "imaps", CURLPROTO_IMAPS },
{ "ldap", CURLPROTO_LDAP },
{ "ldaps", CURLPROTO_LDAPS },
{ "mqtt", CURLPROTO_MQTT },
{ "pop3", CURLPROTO_POP3 },
{ "pop3s", CURLPROTO_POP3S },
{ "rtmp", CURLPROTO_RTMP },
{ "rtmpe", CURLPROTO_RTMPE },
{ "rtmps", CURLPROTO_RTMPS },
{ "rtmpt", CURLPROTO_RTMPT },
{ "rtmpte", CURLPROTO_RTMPTE },
{ "rtmpts", CURLPROTO_RTMPTS },
{ "rtsp", CURLPROTO_RTSP },
{ "scp", CURLPROTO_SCP },
{ "sftp", CURLPROTO_SFTP },
{ "smb", CURLPROTO_SMB },
{ "smbs", CURLPROTO_SMBS },
{ "smtp", CURLPROTO_SMTP },
{ "smtps", CURLPROTO_SMTPS },
{ "telnet", CURLPROTO_TELNET },
{ "tftp", CURLPROTO_TFTP },
{ NULL, 0 }
};
if(!str)
return CURLE_BAD_FUNCTION_ARGUMENT;
else if(curl_strequal(str, "all")) {
*val = ~0;
return CURLE_OK;
}
*val = 0;
do {
size_t tlen;
struct scheme const *pp;
char *token;
token = strchr(str, ',');
found_comma = token ? TRUE : FALSE;
if(!token)
token = strchr(str, '\0');
tlen = token - str;
if(tlen) {
for(pp = protos; pp->name; pp++) {
if((strlen(pp->name) == tlen) &&
curl_strnequal(str, pp->name, tlen)) {
*val |= pp->bit;
break;
}
}
if(!(pp->name))
/* protocol name didn't match */
return CURLE_BAD_FUNCTION_ARGUMENT;
}
if(found_comma)
str = token + 1;
} while(found_comma);
if(!*val)
/* no matching protocol */
return CURLE_BAD_FUNCTION_ARGUMENT;
return CURLE_OK;
}
/*
* Do not make Curl_vsetopt() static: it is called from
* packages/OS400/ccsidcurl.c.
@ -2560,14 +2639,30 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
transfer, which thus helps the app which takes URLs from users or other
external inputs and want to restrict what protocol(s) to deal
with. Defaults to CURLPROTO_ALL. */
data->set.allowed_protocols = (unsigned int)va_arg(param, long);
data->set.allowed_protocols = (curl_off_t)va_arg(param, long);
break;
case CURLOPT_REDIR_PROTOCOLS:
/* set the bitmask for the protocols that libcurl is allowed to follow to,
as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
to be set in both bitmasks to be allowed to get redirected to. */
data->set.redir_protocols = (unsigned int)va_arg(param, long);
data->set.redir_protocols = (curl_off_t)va_arg(param, long);
break;
case CURLOPT_PROTOCOLS_STR:
argptr = va_arg(param, char *);
result = protocol2num(argptr, &bigsize);
if(result)
return result;
data->set.allowed_protocols = bigsize;
break;
case CURLOPT_REDIR_PROTOCOLS_STR:
argptr = va_arg(param, char *);
result = protocol2num(argptr, &bigsize);
if(result)
return result;
data->set.redir_protocols = bigsize;
break;
case CURLOPT_DEFAULT_PROTOCOL: