mirror of
https://github.com/curl/curl.git
synced 2026-07-25 13:47:23 +03:00
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:
parent
193215db3c
commit
e6f8445ede
24 changed files with 487 additions and 45 deletions
|
|
@ -36,11 +36,7 @@ void config_init(struct OperationConfig *config)
|
|||
config->use_httpget = FALSE;
|
||||
config->create_dirs = FALSE;
|
||||
config->maxredirs = DEFAULT_MAXREDIRS;
|
||||
config->proto = CURLPROTO_ALL;
|
||||
config->proto_present = FALSE;
|
||||
config->proto_redir = CURLPROTO_ALL & /* All except FILE, SCP and SMB */
|
||||
~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
|
||||
CURLPROTO_SMBS);
|
||||
config->proto_redir_present = FALSE;
|
||||
config->proto_default = NULL;
|
||||
config->tcp_nodelay = TRUE; /* enabled by default */
|
||||
|
|
@ -172,6 +168,8 @@ static void free_config_fields(struct OperationConfig *config)
|
|||
Curl_safefree(config->ftp_alternative_to_user);
|
||||
|
||||
Curl_safefree(config->aws_sigv4);
|
||||
Curl_safefree(config->proto_str);
|
||||
Curl_safefree(config->proto_redir_str);
|
||||
}
|
||||
|
||||
void config_free(struct OperationConfig *config)
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ struct OperationConfig {
|
|||
bool disable_epsv;
|
||||
bool disable_eprt;
|
||||
bool ftp_pret;
|
||||
long proto;
|
||||
char *proto_str;
|
||||
bool proto_present;
|
||||
long proto_redir;
|
||||
char *proto_redir_str;
|
||||
bool proto_redir_present;
|
||||
char *proto_default;
|
||||
curl_off_t resume_from;
|
||||
|
|
|
|||
|
|
@ -1184,12 +1184,16 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
|||
break;
|
||||
case 'D': /* --proto */
|
||||
config->proto_present = TRUE;
|
||||
if(proto2num(config, &config->proto, nextarg))
|
||||
return PARAM_BAD_USE;
|
||||
err = proto2num(config, (unsigned int)CURLPROTO_ALL,
|
||||
&config->proto_str, nextarg);
|
||||
if(err)
|
||||
return err;
|
||||
break;
|
||||
case 'E': /* --proto-redir */
|
||||
config->proto_redir_present = TRUE;
|
||||
if(proto2num(config, &config->proto_redir, nextarg))
|
||||
if(proto2num(config, CURLPROTO_HTTP|CURLPROTO_HTTPS|
|
||||
CURLPROTO_FTP|CURLPROTO_FTPS,
|
||||
&config->proto_redir_str, nextarg))
|
||||
return PARAM_BAD_USE;
|
||||
break;
|
||||
case 'F': /* --resolve */
|
||||
|
|
|
|||
|
|
@ -1989,9 +1989,10 @@ static CURLcode single_transfer(struct GlobalConfig *global,
|
|||
my_setopt(curl, CURLOPT_NEW_FILE_PERMS, config->create_file_mode);
|
||||
|
||||
if(config->proto_present)
|
||||
my_setopt_flags(curl, CURLOPT_PROTOCOLS, config->proto);
|
||||
my_setopt_str(curl, CURLOPT_PROTOCOLS_STR, config->proto_str);
|
||||
if(config->proto_redir_present)
|
||||
my_setopt_flags(curl, CURLOPT_REDIR_PROTOCOLS, config->proto_redir);
|
||||
my_setopt_str(curl, CURLOPT_REDIR_PROTOCOLS_STR,
|
||||
config->proto_redir_str);
|
||||
|
||||
if(config->content_disposition
|
||||
&& (urlnode->flags & GETOUT_USEREMOTE))
|
||||
|
|
|
|||
|
|
@ -275,8 +275,8 @@ ParameterError str2udouble(double *valp, const char *str, long max)
|
|||
}
|
||||
|
||||
/*
|
||||
* Parse the string and modify the long in the given address. Return
|
||||
* non-zero on failure, zero on success.
|
||||
* Parse the string and provide an allocated libcurl compatible protocol
|
||||
* string output. Return non-zero on failure, zero on success.
|
||||
*
|
||||
* The string is a list of protocols
|
||||
*
|
||||
|
|
@ -285,17 +285,22 @@ ParameterError str2udouble(double *valp, const char *str, long max)
|
|||
* data.
|
||||
*/
|
||||
|
||||
long proto2num(struct OperationConfig *config, long *val, const char *str)
|
||||
ParameterError proto2num(struct OperationConfig *config,
|
||||
unsigned int val, char **ostr, const char *str)
|
||||
{
|
||||
char *buffer;
|
||||
const char *sep = ",";
|
||||
char *token;
|
||||
char obuf[256];
|
||||
size_t olen = sizeof(obuf);
|
||||
char *optr;
|
||||
struct sprotos const *pp;
|
||||
|
||||
static struct sprotos {
|
||||
const char *name;
|
||||
long bit;
|
||||
unsigned int bit;
|
||||
} const protos[] = {
|
||||
{ "all", CURLPROTO_ALL },
|
||||
{ "all", (unsigned int)CURLPROTO_ALL },
|
||||
{ "http", CURLPROTO_HTTP },
|
||||
{ "https", CURLPROTO_HTTPS },
|
||||
{ "ftp", CURLPROTO_FTP },
|
||||
|
|
@ -305,6 +310,7 @@ long proto2num(struct OperationConfig *config, long *val, const char *str)
|
|||
{ "telnet", CURLPROTO_TELNET },
|
||||
{ "ldap", CURLPROTO_LDAP },
|
||||
{ "ldaps", CURLPROTO_LDAPS },
|
||||
{ "mqtt", CURLPROTO_MQTT },
|
||||
{ "dict", CURLPROTO_DICT },
|
||||
{ "file", CURLPROTO_FILE },
|
||||
{ "tftp", CURLPROTO_TFTP },
|
||||
|
|
@ -316,6 +322,7 @@ long proto2num(struct OperationConfig *config, long *val, const char *str)
|
|||
{ "smtps", CURLPROTO_SMTPS },
|
||||
{ "rtsp", CURLPROTO_RTSP },
|
||||
{ "gopher", CURLPROTO_GOPHER },
|
||||
{ "gophers", CURLPROTO_GOPHERS },
|
||||
{ "smb", CURLPROTO_SMB },
|
||||
{ "smbs", CURLPROTO_SMBS },
|
||||
{ NULL, 0 }
|
||||
|
|
@ -335,8 +342,6 @@ long proto2num(struct OperationConfig *config, long *val, const char *str)
|
|||
token = strtok(NULL, sep)) {
|
||||
enum e_action { allow, deny, set } action = allow;
|
||||
|
||||
struct sprotos const *pp;
|
||||
|
||||
/* Process token modifiers */
|
||||
while(!ISALNUM(*token)) { /* may be NULL if token is all modifiers */
|
||||
switch (*token++) {
|
||||
|
|
@ -359,13 +364,13 @@ long proto2num(struct OperationConfig *config, long *val, const char *str)
|
|||
if(curl_strequal(token, pp->name)) {
|
||||
switch(action) {
|
||||
case deny:
|
||||
*val &= ~(pp->bit);
|
||||
val &= ~(pp->bit);
|
||||
break;
|
||||
case allow:
|
||||
*val |= pp->bit;
|
||||
val |= pp->bit;
|
||||
break;
|
||||
case set:
|
||||
*val = pp->bit;
|
||||
val = pp->bit;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
@ -376,12 +381,25 @@ long proto2num(struct OperationConfig *config, long *val, const char *str)
|
|||
/* If they have specified only this protocol, we say treat it as
|
||||
if no protocols are allowed */
|
||||
if(action == set)
|
||||
*val = 0;
|
||||
val = 0;
|
||||
warnf(config->global, "unrecognized protocol '%s'\n", token);
|
||||
}
|
||||
}
|
||||
Curl_safefree(buffer);
|
||||
return 0;
|
||||
|
||||
optr = obuf;
|
||||
for(pp = &protos[1]; pp->name; pp++) {
|
||||
if(val & pp->bit) {
|
||||
size_t n = msnprintf(optr, olen, "%s%s",
|
||||
olen != sizeof(obuf) ? "," : "",
|
||||
pp->name);
|
||||
olen -= n;
|
||||
optr += n;
|
||||
}
|
||||
}
|
||||
*ostr = strdup(obuf);
|
||||
|
||||
return *ostr ? PARAM_OK : PARAM_NO_MEM;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ ParameterError oct2nummax(long *val, const char *str, long max);
|
|||
ParameterError str2unummax(long *val, const char *str, long max);
|
||||
ParameterError str2udouble(double *val, const char *str, long max);
|
||||
|
||||
long proto2num(struct OperationConfig *config, long *val, const char *str);
|
||||
ParameterError proto2num(struct OperationConfig *config,
|
||||
unsigned int val, char **obuf,
|
||||
const char *str);
|
||||
|
||||
int check_protocol(const char *str);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue