summaryrefslogtreecommitdiff
path: root/lib/setopt.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2022-06-13 09:30:45 +0200
committerDaniel Stenberg <daniel@haxx.se>2022-07-04 08:35:09 +0200
commite6f8445edef8e7996d1cfb141d6df184efef972c (patch)
tree3b90f03794b92c243a3a09cebfa270d5502258e8 /lib/setopt.c
parent193215db3ca956b1e5c99539bc20cf892870d11f (diff)
downloadcurl-e6f8445edef8e7996d1cfb141d6df184efef972c.tar.gz
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
Diffstat (limited to 'lib/setopt.c')
-rw-r--r--lib/setopt.c99
1 files changed, 97 insertions, 2 deletions
diff --git a/lib/setopt.c b/lib/setopt.c
index 6b16e1c7c..dc6bc2a09 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -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: