From 9756d1da7637d1913b7ca2b589e4635f32ed3e00 Mon Sep 17 00:00:00 2001 From: Nathaniel Waisbrot Date: Sat, 22 Aug 2015 21:49:26 -0400 Subject: CURLOPT_DEFAULT_PROTOCOL: added - Add new option CURLOPT_DEFAULT_PROTOCOL to allow specifying a default protocol for schemeless URLs. - Add new tool option --proto-default to expose CURLOPT_DEFAULT_PROTOCOL. In the case of schemeless URLs libcurl will behave in this way: When the option is used libcurl will use the supplied default. When the option is not used, libcurl will follow its usual plan of guessing from the hostname and falling back to 'http'. --- src/tool_cfgable.c | 1 + src/tool_cfgable.h | 1 + src/tool_getparam.c | 23 +++++++++++++++-------- src/tool_getparam.h | 1 + src/tool_help.c | 3 ++- src/tool_helpers.c | 2 ++ src/tool_operate.c | 6 ++++++ src/tool_paramhlp.c | 21 +++++++++++++++++++++ src/tool_paramhlp.h | 3 ++- 9 files changed, 51 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c index ba6c468c5..7ad86cad3 100644 --- a/src/tool_cfgable.c +++ b/src/tool_cfgable.c @@ -40,6 +40,7 @@ void config_init(struct OperationConfig* config) ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB | CURLPROTO_SMBS); config->proto_redir_present = FALSE; + config->proto_default = NULL; } static void free_config_fields(struct OperationConfig *config) diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index c6a691447..826b7fe1f 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -51,6 +51,7 @@ struct OperationConfig { bool proto_present; long proto_redir; bool proto_redir_present; + char *proto_default; curl_off_t resume_from; char *postfields; curl_off_t postfieldsize; diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 4405bce87..e97a1b98c 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -160,8 +160,6 @@ static const struct LongShort aliases[]= { {"$5", "noproxy", TRUE}, {"$6", "socks5-gssapi-service", TRUE}, {"$7", "socks5-gssapi-nec", FALSE}, - {"$O", "proxy-service-name", TRUE}, - {"$P", "service-name", TRUE}, {"$8", "proxy1.0", TRUE}, {"$9", "tftp-blksize", TRUE}, {"$A", "mail-from", TRUE}, @@ -178,6 +176,9 @@ static const struct LongShort aliases[]= { {"$L", "test-event", FALSE}, {"$M", "unix-socket", TRUE}, {"$N", "path-as-is", FALSE}, + {"$O", "proxy-service-name", TRUE}, + {"$P", "service-name", TRUE}, + {"$Q", "proto-default", TRUE}, {"0", "http1.0", FALSE}, {"01", "http1.1", FALSE}, {"02", "http2", FALSE}, @@ -903,12 +904,6 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ case '7': /* --socks5-gssapi-nec*/ config->socks5_gssapi_nec = toggle; break; - case 'O': /* --proxy-service-name */ - GetStr(&config->proxy_service_name, nextarg); - break; - case 'P': /* --service-name */ - GetStr(&config->service_name, nextarg); - break; case '8': /* --proxy1.0 */ /* http 1.0 proxy */ GetStr(&config->proxy, nextarg); @@ -992,6 +987,18 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ case 'N': /* --path-as-is */ config->path_as_is = toggle; break; + case 'O': /* --proxy-service-name */ + GetStr(&config->proxy_service_name, nextarg); + break; + case 'P': /* --service-name */ + GetStr(&config->service_name, nextarg); + break; + case 'Q': /* --proto-default */ + GetStr(&config->proto_default, nextarg); + err = check_protocol(config->proto_default); + if(err) + return err; + break; } break; case '#': /* --progress-bar */ diff --git a/src/tool_getparam.h b/src/tool_getparam.h index ef4366b7f..354497512 100644 --- a/src/tool_getparam.h +++ b/src/tool_getparam.h @@ -37,6 +37,7 @@ typedef enum { PARAM_BAD_NUMERIC, PARAM_NEGATIVE_NUMERIC, PARAM_LIBCURL_DOESNT_SUPPORT, + PARAM_LIBCURL_UNSUPPORTED_PROTOCOL, PARAM_NO_MEM, PARAM_NEXT_OPERATION, PARAM_LAST diff --git a/src/tool_help.c b/src/tool_help.c index 6ad51cb5b..355fe7d7b 100644 --- a/src/tool_help.c +++ b/src/tool_help.c @@ -165,7 +165,8 @@ static const char *const helptext[] = { "Do not switch to GET after following a 303 redirect (H)", " -#, --progress-bar Display transfer progress as a progress bar", " --proto PROTOCOLS Enable/disable PROTOCOLS", - " --proto-redir PROTOCOLS Enable/disable PROTOCOLS on redirect", + " --proto-default PROTOCOL Use PROTOCOL for any URL missing a scheme", + " --proto-redir PROTOCOLS Enable/disable PROTOCOLS on redirect", " -x, --proxy [PROTOCOL://]HOST[:PORT] Use proxy on given port", " --proxy-anyauth Pick \"any\" proxy authentication method (H)", " --proxy-basic Use Basic authentication on the proxy (H)", diff --git a/src/tool_helpers.c b/src/tool_helpers.c index 5479a1c03..b236c4ddf 100644 --- a/src/tool_helpers.c +++ b/src/tool_helpers.c @@ -58,6 +58,8 @@ const char *param2text(int res) return "expected a positive numerical parameter"; case PARAM_LIBCURL_DOESNT_SUPPORT: return "the installed libcurl version doesn't support this"; + case PARAM_LIBCURL_UNSUPPORTED_PROTOCOL: + return "a specified protocol is unsupported by libcurl"; case PARAM_NO_MEM: return "out of memory"; default: diff --git a/src/tool_operate.c b/src/tool_operate.c index ecc0275c3..d18175f04 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1355,6 +1355,10 @@ static CURLcode operate_do(struct GlobalConfig *global, my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH, config->unix_socket_path); + /* new in 7.45.0 */ + if(config->proto_default) + my_setopt_str(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default); + /* initialize retry vars for loop below */ retry_sleep_default = (config->retry_delay) ? config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */ @@ -1850,6 +1854,8 @@ CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]) /* Check if we were asked to list the SSL engines */ else if(res == PARAM_ENGINES_REQUESTED) tool_list_engines(config->easy); + else if(res == PARAM_LIBCURL_UNSUPPORTED_PROTOCOL) + result = CURLE_UNSUPPORTED_PROTOCOL; else result = CURLE_FAILED_INIT; } diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c index d4b96e76d..28872e678 100644 --- a/src/tool_paramhlp.c +++ b/src/tool_paramhlp.c @@ -338,6 +338,27 @@ long proto2num(struct OperationConfig *config, long *val, const char *str) return 0; } +/** + * Check if the given string is a protocol supported by libcurl + * + * @param str the protocol name + * @return PARAM_OK protocol supported + * @return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL protocol not supported + * @return PARAM_REQUIRES_PARAMETER missing parameter + */ +int check_protocol(const char *str) +{ + const char * const *pp; + const curl_version_info_data *curlinfo = curl_version_info(CURLVERSION_NOW); + if(!str) + return PARAM_REQUIRES_PARAMETER; + for(pp = curlinfo->protocols; *pp; pp++) { + if(curlx_raw_equal(*pp, str)) + return PARAM_OK; + } + return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL; +} + /** * Parses the given string looking for an offset (which may be a * larger-than-integer value). The offset CANNOT be negative! diff --git a/src/tool_paramhlp.h b/src/tool_paramhlp.h index 69d7fd422..646caec05 100644 --- a/src/tool_paramhlp.h +++ b/src/tool_paramhlp.h @@ -38,6 +38,8 @@ ParameterError str2udouble(double *val, const char *str); long proto2num(struct OperationConfig *config, long *val, const char *str); +int check_protocol(const char *str); + ParameterError str2offset(curl_off_t *val, const char *str); CURLcode get_args(struct OperationConfig *config, const size_t i); @@ -51,4 +53,3 @@ int ftpcccmethod(struct OperationConfig *config, const char *str); long delegation(struct OperationConfig *config, char *str); #endif /* HEADER_CURL_TOOL_PARAMHLP_H */ - -- cgit v1.2.3