diff options
Diffstat (limited to 'Utilities/cmcurl/lib/url.c')
-rw-r--r-- | Utilities/cmcurl/lib/url.c | 339 |
1 files changed, 206 insertions, 133 deletions
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c index 87446db..584635b 100644 --- a/Utilities/cmcurl/lib/url.c +++ b/Utilities/cmcurl/lib/url.c @@ -71,6 +71,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "netrc.h" #include "formdata.h" +#include "mime.h" #include "vtls/vtls.h" #include "hostip.h" #include "transfer.h" @@ -274,6 +275,7 @@ static const struct Curl_handler Curl_handler_dummy = { ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ 0, /* defport */ 0, /* protocol */ PROTOPT_NONE /* flags */ @@ -283,7 +285,7 @@ void Curl_freeset(struct Curl_easy *data) { /* Free all dynamic strings stored in the data->set substructure. */ enum dupstring i; - for(i=(enum dupstring)0; i < STRING_LAST; i++) { + for(i = (enum dupstring)0; i < STRING_LAST; i++) { Curl_safefree(data->set.str[i]); } @@ -370,7 +372,7 @@ CURLcode Curl_dupset(struct Curl_easy *dst, struct Curl_easy *src) memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); /* duplicate all strings */ - for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { + for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { result = setstropt(&dst->set.str[i], src->set.str[i]); if(result) return result; @@ -478,6 +480,8 @@ CURLcode Curl_close(struct Curl_easy *data) Curl_http2_cleanup_dependencies(data); Curl_convert_close(data); + Curl_mime_cleanpart(&data->set.mimepost); + /* No longer a dirty share, if it exists */ if(data->share) { Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); @@ -545,6 +549,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ + /* SOCKS5 proxy auth defaults to username/password + GSS-API */ + set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI; + /* make libcurl quiet by default: */ set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ @@ -664,6 +671,8 @@ CURLcode Curl_open(struct Curl_easy **curl) result = CURLE_OUT_OF_MEMORY; } + Curl_mime_initpart(&data->set.mimepost, data); + data->state.headerbuff = malloc(HEADERSIZE); if(!data->state.headerbuff) { DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n")); @@ -672,7 +681,7 @@ CURLcode Curl_open(struct Curl_easy **curl) else { result = Curl_init_userdefined(&data->set); - data->state.headersize=HEADERSIZE; + data->state.headersize = HEADERSIZE; Curl_convert_init(data); @@ -829,6 +838,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, then this can be changed to HEAD later on) */ data->set.httpreq = HTTPREQ_GET; break; + case CURLOPT_REQUEST_TARGET: + result = setstropt(&data->set.str[STRING_TARGET], + va_arg(param, char *)); + break; case CURLOPT_FILETIME: /* * Try to get the file time of the remote document. The time will @@ -1139,6 +1152,20 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, data->set.httpreq = HTTPREQ_POST_FORM; data->set.opt_no_body = FALSE; /* this is implied */ break; +#endif /* CURL_DISABLE_HTTP */ + + case CURLOPT_MIMEPOST: + /* + * Set to make us do MIME/form POST + */ + result = curl_mime_subparts(&data->set.mimepost, + va_arg(param, curl_mime *)); + if(!result) { + data->set.mimepost.freefunc = NULL; /* Avoid free upon easy cleanup. */ + data->set.httpreq = HTTPREQ_POST_MIME; + data->set.opt_no_body = FALSE; /* this is implied */ + } + break; case CURLOPT_REFERER: /* @@ -1168,6 +1195,7 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, data->set.headers = va_arg(param, struct curl_slist *); break; +#ifndef CURL_DISABLE_HTTP case CURLOPT_PROXYHEADER: /* * Set a list with proxy headers to use (or replace internals with) @@ -1319,7 +1347,7 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, } break; -#endif /* CURL_DISABLE_COOKIES */ +#endif /* !CURL_DISABLE_COOKIES */ case CURLOPT_HTTPGET: /* @@ -1345,6 +1373,16 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, data->set.httpversion = arg; break; + case CURLOPT_EXPECT_100_TIMEOUT_MS: + /* + * Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. + */ + data->set.expect_100_timeout = va_arg(param, long); + break; + +#endif /* CURL_DISABLE_HTTP */ + case CURLOPT_HTTPAUTH: /* * Set HTTP Authentication type BITMASK. @@ -1396,16 +1434,6 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, } break; - case CURLOPT_EXPECT_100_TIMEOUT_MS: - /* - * Time to wait for a response to a HTTP request containing an - * Expect: 100-continue header before sending the data anyway. - */ - data->set.expect_100_timeout = va_arg(param, long); - break; - -#endif /* CURL_DISABLE_HTTP */ - case CURLOPT_CUSTOMREQUEST: /* * Set a custom string to use as request @@ -1537,6 +1565,11 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, break; #endif /* CURL_DISABLE_PROXY */ + case CURLOPT_SOCKS5_AUTH: + data->set.socks5auth = va_arg(param, unsigned long); + if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) + result = CURLE_NOT_BUILT_IN; + break; #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) case CURLOPT_SOCKS5_GSSAPI_NEC: /* @@ -1646,28 +1679,28 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, * The low speed limit that if transfers are below this for * CURLOPT_LOW_SPEED_TIME, the transfer is aborted. */ - data->set.low_speed_limit=va_arg(param, long); + data->set.low_speed_limit = va_arg(param, long); break; case CURLOPT_MAX_SEND_SPEED_LARGE: /* * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE * bytes per second the transfer is throttled.. */ - data->set.max_send_speed=va_arg(param, curl_off_t); + data->set.max_send_speed = va_arg(param, curl_off_t); break; case CURLOPT_MAX_RECV_SPEED_LARGE: /* * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per * second the transfer is throttled.. */ - data->set.max_recv_speed=va_arg(param, curl_off_t); + data->set.max_recv_speed = va_arg(param, curl_off_t); break; case CURLOPT_LOW_SPEED_TIME: /* * The low speed time that if transfers are below the set * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted. */ - data->set.low_speed_time=va_arg(param, long); + data->set.low_speed_time = va_arg(param, long); break; case CURLOPT_URL: /* @@ -1862,13 +1895,13 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, break; case CURLOPT_RESUME_FROM: /* - * Resume transfer at the give file position + * Resume transfer at the given file position */ data->set.set_resume_from = va_arg(param, long); break; case CURLOPT_RESUME_FROM_LARGE: /* - * Resume transfer at the give file position + * Resume transfer at the given file position */ data->set.set_resume_from = va_arg(param, curl_off_t); break; @@ -2166,24 +2199,26 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, TRUE : FALSE; break; case CURLOPT_SSL_CTX_FUNCTION: -#ifdef have_curlssl_ssl_ctx /* * Set a SSL_CTX callback */ - data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); -#else - result = CURLE_NOT_BUILT_IN; +#ifdef USE_SSL + if(Curl_ssl->have_ssl_ctx) + data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); + else #endif + result = CURLE_NOT_BUILT_IN; break; case CURLOPT_SSL_CTX_DATA: -#ifdef have_curlssl_ssl_ctx /* * Set a SSL_CTX callback parameter pointer */ - data->set.ssl.fsslctxp = va_arg(param, void *); -#else - result = CURLE_NOT_BUILT_IN; +#ifdef USE_SSL + if(Curl_ssl->have_ssl_ctx) + data->set.ssl.fsslctxp = va_arg(param, void *); + else #endif + result = CURLE_NOT_BUILT_IN; break; case CURLOPT_SSL_FALSESTART: /* @@ -2197,35 +2232,38 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE; break; case CURLOPT_CERTINFO: -#ifdef have_curlssl_certinfo - data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE; -#else - result = CURLE_NOT_BUILT_IN; +#ifdef USE_SSL + if(Curl_ssl->have_certinfo) + data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE; + else #endif + result = CURLE_NOT_BUILT_IN; break; case CURLOPT_PINNEDPUBLICKEY: -#ifdef have_curlssl_pinnedpubkey /* only by supported backends */ /* * Set pinned public key for SSL connection. * Specify file name of the public key in DER format. */ - result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG], - va_arg(param, char *)); -#else - result = CURLE_NOT_BUILT_IN; +#ifdef USE_SSL + if(Curl_ssl->have_pinnedpubkey) + result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG], + va_arg(param, char *)); + else #endif + result = CURLE_NOT_BUILT_IN; break; case CURLOPT_PROXY_PINNEDPUBLICKEY: -#ifdef have_curlssl_pinnedpubkey /* only by supported backends */ /* * Set pinned public key for SSL connection. * Specify file name of the public key in DER format. */ - result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY], - va_arg(param, char *)); -#else - result = CURLE_NOT_BUILT_IN; +#ifdef USE_SSL + if(Curl_ssl->have_pinnedpubkey) + result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY], + va_arg(param, char *)); + else #endif + result = CURLE_NOT_BUILT_IN; break; case CURLOPT_CAINFO: /* @@ -2243,30 +2281,32 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, va_arg(param, char *)); break; case CURLOPT_CAPATH: -#ifdef have_curlssl_ca_path /* not supported by all backends */ /* * Set CA path info for SSL connection. Specify directory name of the CA * certificates which have been prepared using openssl c_rehash utility. */ - /* This does not work on windows. */ - result = setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG], - va_arg(param, char *)); -#else - result = CURLE_NOT_BUILT_IN; +#ifdef USE_SSL + if(Curl_ssl->have_ca_path) + /* This does not work on windows. */ + result = setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG], + va_arg(param, char *)); + else #endif + result = CURLE_NOT_BUILT_IN; break; case CURLOPT_PROXY_CAPATH: -#ifdef have_curlssl_ca_path /* not supported by all backends */ /* * Set CA path info for SSL connection proxy. Specify directory name of the * CA certificates which have been prepared using openssl c_rehash utility. */ - /* This does not work on windows. */ - result = setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY], - va_arg(param, char *)); -#else - result = CURLE_NOT_BUILT_IN; +#ifdef USE_SSL + if(Curl_ssl->have_ca_path) + /* This does not work on windows. */ + result = setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY], + va_arg(param, char *)); + else #endif + result = CURLE_NOT_BUILT_IN; break; case CURLOPT_CRLFILE: /* @@ -2897,7 +2937,7 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, return CURLE_NOT_BUILT_IN; #else arg = va_arg(param, long); - if((arg>=1) && (arg <= 256)) + if((arg >= 1) && (arg <= 256)) data->set.stream_weight = (int)arg; break; #endif @@ -2923,6 +2963,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, case CURLOPT_SUPPRESS_CONNECT_HEADERS: data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE; break; + case CURLOPT_SSH_COMPRESSION: + data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE; + break; default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; @@ -3023,7 +3066,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */ Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */ Curl_safefree(conn->master_buffer); - Curl_safefree(conn->connect_buffer); + Curl_safefree(conn->connect_state); conn_reset_all_postponed_data(conn); @@ -3260,9 +3303,9 @@ Curl_oldest_idle_connection(struct Curl_easy *data) struct curl_hash_iterator iter; struct curl_llist_element *curr; struct curl_hash_element *he; - time_t highscore=-1; + time_t highscore =- 1; time_t score; - struct timeval now; + struct curltime now; struct connectdata *conn_candidate = NULL; struct connectbundle *bundle; @@ -3323,9 +3366,9 @@ find_oldest_idle_connection_in_bundle(struct Curl_easy *data, struct connectbundle *bundle) { struct curl_llist_element *curr; - time_t highscore=-1; + time_t highscore = -1; time_t score; - struct timeval now; + struct curltime now; struct connectdata *conn_candidate = NULL; struct connectdata *conn; @@ -3367,11 +3410,19 @@ static bool disconnect_if_dead(struct connectdata *conn, handles in pipeline and the connection isn't already marked in use */ bool dead; - if(conn->handler->protocol & CURLPROTO_RTSP) - /* RTSP is a special case due to RTP interleaving */ - dead = Curl_rtsp_connisdead(conn); - else + + if(conn->handler->connection_check) { + /* The protocol has a special method for checking the state of the + connection. Use it to check if the connection is dead. */ + unsigned int state; + + state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD); + dead = (state & CONNRESULT_DEAD); + } + else { + /* Use the general method for determining the death of a connection */ dead = SocketIsDead(conn->sock[FIRSTSOCKET]); + } if(dead) { conn->data = data; @@ -3405,7 +3456,7 @@ static int call_disconnect_if_dead(struct connectdata *conn, */ static void prune_dead_connections(struct Curl_easy *data) { - struct timeval now = Curl_tvnow(); + struct curltime now = Curl_tvnow(); time_t elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup); if(elapsed >= 1000L) { @@ -3946,7 +3997,7 @@ int Curl_doing_getsock(struct connectdata *conn, CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done) { - CURLcode result=CURLE_OK; + CURLcode result = CURLE_OK; if(conn && conn->handler->connecting) { *done = FALSE; @@ -3965,7 +4016,7 @@ CURLcode Curl_protocol_connecting(struct connectdata *conn, CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) { - CURLcode result=CURLE_OK; + CURLcode result = CURLE_OK; if(conn && conn->handler->doing) { *done = FALSE; @@ -3985,7 +4036,7 @@ CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done) { - CURLcode result=CURLE_OK; + CURLcode result = CURLE_OK; *protocol_done = FALSE; @@ -4013,7 +4064,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, return CURLE_OK; if(conn->bits.tunnel_proxy && conn->bits.httpproxy && - (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE)) + Curl_connect_ongoing(conn)) /* when using an HTTP tunnel proxy, await complete tunnel establishment before proceeding further. Return CURLE_OK so we'll be called again */ return CURLE_OK; @@ -4072,7 +4123,7 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) if(len && (host->name[len-1] == '.')) /* strip off a single trailing dot if present, primarily for SNI but there's no use for it */ - host->name[len-1]=0; + host->name[len-1] = 0; /* Check name for non-ASCII and convert hostname to ACE form if we can */ if(!is_ASCII_name(host->name)) { @@ -4125,7 +4176,7 @@ static void free_fixed_hostname(struct hostname *host) host->encalloc = NULL; } #elif defined(USE_WIN32_IDN) - free(host->encalloc); /* must be freed withidn_free() since this was + free(host->encalloc); /* must be freed with free() since this was allocated by curl_win32_idn_to_ascii */ host->encalloc = NULL; #else @@ -4145,7 +4196,12 @@ static void llist_dtor(void *user, void *element) */ static struct connectdata *allocate_conn(struct Curl_easy *data) { - struct connectdata *conn = calloc(1, sizeof(struct connectdata)); +#ifdef USE_SSL +#define SSL_EXTRA + 4 * Curl_ssl->sizeof_ssl_backend_data - sizeof(long long) +#else +#define SSL_EXTRA 0 +#endif + struct connectdata *conn = calloc(1, sizeof(struct connectdata) + SSL_EXTRA); if(!conn) return NULL; @@ -4228,6 +4284,23 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->ip_version = data->set.ipver; +#ifdef USE_SSL + /* + * To save on malloc()s, the SSL backend-specific data has been allocated + * at the end of the connectdata struct. + */ + { + char *p = (char *)&conn->align_data__do_not_use; + conn->ssl[0].backend = (struct ssl_backend_data *)p; + conn->ssl[1].backend = + (struct ssl_backend_data *)(p + Curl_ssl->sizeof_ssl_backend_data); + conn->proxy_ssl[0].backend = + (struct ssl_backend_data *)(p + Curl_ssl->sizeof_ssl_backend_data * 2); + conn->proxy_ssl[1].backend = + (struct ssl_backend_data *)(p + Curl_ssl->sizeof_ssl_backend_data * 3); + } +#endif + #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ defined(NTLM_WB_ENABLED) conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; @@ -4363,11 +4436,16 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, return CURLE_URL_MALFORMAT; } - /* Make sure we don't mistake a drive letter for a scheme, for example: + /* MSDOS/Windows style drive prefix, eg c: in c:foo */ +#define STARTS_WITH_DRIVE_PREFIX(str) \ + ((('a' <= str[0] && str[0] <= 'z') || \ + ('A' <= str[0] && str[0] <= 'Z')) && \ + (str[1] == ':')) + + /* Don't mistake a drive letter for a scheme if the default protocol is file. curld --proto-default file c:/foo/bar.txt */ - if((('a' <= data->change.url[0] && data->change.url[0] <= 'z') || - ('A' <= data->change.url[0] && data->change.url[0] <= 'Z')) && - data->change.url[1] == ':' && data->set.str[STRING_DEFAULT_PROTOCOL] && + if(STARTS_WITH_DRIVE_PREFIX(data->change.url) && + data->set.str[STRING_DEFAULT_PROTOCOL] && strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file")) { ; /* do nothing */ } @@ -4386,8 +4464,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, if((url_has_scheme && strncasecompare(data->change.url, "file:", 5)) || (!url_has_scheme && data->set.str[STRING_DEFAULT_PROTOCOL] && strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file"))) { - bool path_has_drive = FALSE; - if(url_has_scheme) rc = sscanf(data->change.url, "%*15[^\n/:]:%[^\n]", path); else @@ -4406,20 +4482,15 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, /* This cannot be done with strcpy() in a portable manner, since the memory areas overlap! */ - memmove(path, path + 2, strlen(path + 2)+1); + memmove(path, path + 2, strlen(path + 2) + 1); } - /* the path may start with a drive letter. for backwards compatibility - we skip some processing on those paths. */ - path_has_drive = (('a' <= path[0] && path[0] <= 'z') || - ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':'; - /* * we deal with file://<host>/<path> differently since it supports no * hostname other than "localhost" and "127.0.0.1", which is unique among * the URL protocols specified in RFC 1738 */ - if(path[0] != '/' && !path_has_drive) { + if(path[0] != '/' && !STARTS_WITH_DRIVE_PREFIX(path)) { /* the URL includes a host name, it must match "localhost" or "127.0.0.1" to be valid */ char *ptr; @@ -4452,14 +4523,11 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, ptr++; /* This cannot be made with strcpy, as the memory chunks overlap! */ - memmove(path, ptr, strlen(ptr)+1); - - path_has_drive = (('a' <= path[0] && path[0] <= 'z') || - ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':'; + memmove(path, ptr, strlen(ptr) + 1); } #if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__) - if(path_has_drive) { + if(STARTS_WITH_DRIVE_PREFIX(path)) { failf(data, "File drive letters are only accepted in MSDOS/Windows."); return CURLE_URL_MALFORMAT; } @@ -4471,7 +4539,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, else { /* clear path */ char slashbuf[4]; - path[0]=0; + path[0] = 0; rc = sscanf(data->change.url, "%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]", @@ -4556,7 +4624,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, */ at = strchr(conn->host.name, '@'); if(at) - query = strchr(at+1, '?'); + query = strchr(at + 1, '?'); else query = strchr(conn->host.name, '?'); @@ -4574,15 +4642,15 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, /* move the existing path plus the zero byte forward, to make room for the host-name part */ - memmove(path+hostlen+1, path, pathlen+1); + memmove(path + hostlen + 1, path, pathlen + 1); /* now copy the trailing host part in front of the existing path */ - memcpy(path+1, query, hostlen); + memcpy(path + 1, query, hostlen); path[0]='/'; /* prepend the missing slash */ rebuild_url = TRUE; - *query=0; /* now cut off the hostname at the ? */ + *query = 0; /* now cut off the hostname at the ? */ } else if(!path[0]) { /* if there's no path set, use a single slash */ @@ -4598,7 +4666,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, /* We need this function to deal with overlapping memory areas. We know that the memory area 'path' points to is 'urllen' bytes big and that is bigger than the path. Use +1 to move the zero byte too. */ - memmove(&path[1], path, strlen(path)+1); + memmove(&path[1], path, strlen(path) + 1); path[0] = '/'; rebuild_url = TRUE; } @@ -4704,7 +4772,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, if(*endp == ']') { /* The address scope was well formed. Knock it out of the hostname. */ - memmove(percent, endp, strlen(endp)+1); + memmove(percent, endp, strlen(endp) + 1); conn->scope_id = (unsigned int)scope; } else { @@ -4974,7 +5042,7 @@ static char *detect_proxy(struct connectdata *conn) strcpy(envp, "_proxy"); /* read the protocol proxy: */ - prox=curl_getenv(proxy_env); + prox = curl_getenv(proxy_env); /* * We don't try the uppercase version of HTTP_PROXY because of @@ -4991,7 +5059,7 @@ static char *detect_proxy(struct connectdata *conn) if(!prox && !strcasecompare("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); - prox=curl_getenv(proxy_env); + prox = curl_getenv(proxy_env); } if(prox) @@ -4999,7 +5067,7 @@ static char *detect_proxy(struct connectdata *conn) else { proxy = curl_getenv("all_proxy"); /* default proxy to use */ if(!proxy) - proxy=curl_getenv("ALL_PROXY"); + proxy = curl_getenv("ALL_PROXY"); } return proxy; @@ -5034,7 +5102,7 @@ static CURLcode parse_proxy(struct Curl_easy *data, /* Parse the protocol part if present */ endofprot = strstr(proxy, "://"); if(endofprot) { - proxyptr = endofprot+3; + proxyptr = endofprot + 3; if(checkprefix("https", proxy)) proxytype = CURLPROXY_HTTPS; else if(checkprefix("socks5h", proxy)) @@ -5056,13 +5124,14 @@ static CURLcode parse_proxy(struct Curl_easy *data, else proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */ -#ifndef HTTPS_PROXY_SUPPORT - if(proxytype == CURLPROXY_HTTPS) { - failf(data, "Unsupported proxy \'%s\'" - ", libcurl is built without the HTTPS-proxy support.", proxy); - return CURLE_NOT_BUILT_IN; - } +#ifdef USE_SSL + if(!Curl_ssl->support_https_proxy) #endif + if(proxytype == CURLPROXY_HTTPS) { + failf(data, "Unsupported proxy \'%s\', libcurl is built without the " + "HTTPS-proxy support.", proxy); + return CURLE_NOT_BUILT_IN; + } sockstype = proxytype == CURLPROXY_SOCKS5_HOSTNAME || proxytype == CURLPROXY_SOCKS5 || @@ -5133,11 +5202,14 @@ static CURLcode parse_proxy(struct Curl_easy *data, conn->port = port; } else { - if(proxyptr[0]=='/') + if(proxyptr[0]=='/') { /* If the first character in the proxy string is a slash, fail immediately. The following code will otherwise clear the string which will lead to code running as if no proxy was set! */ + Curl_safefree(proxyuser); + Curl_safefree(proxypasswd); return CURLE_COULDNT_RESOLVE_PROXY; + } /* without a port number after the host name, some people seem to use a slash so we strip everything from the first slash */ @@ -5280,22 +5352,21 @@ static CURLcode create_conn_helper_init_proxy(struct connectdata *conn) } } - no_proxy = curl_getenv("no_proxy"); - if(!no_proxy) - no_proxy = curl_getenv("NO_PROXY"); + if(!data->set.str[STRING_NOPROXY]) { + no_proxy = curl_getenv("no_proxy"); + if(!no_proxy) + no_proxy = curl_getenv("NO_PROXY"); + } - if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY]) || - (!data->set.str[STRING_NOPROXY] && - check_noproxy(conn->host.name, no_proxy))) { + if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ? + data->set.str[STRING_NOPROXY] : no_proxy)) { Curl_safefree(proxy); Curl_safefree(socksproxy); } - else if(!proxy && !socksproxy) #ifndef CURL_DISABLE_HTTP + else if(!proxy && !socksproxy) /* if the host is not in the noproxy list, detect proxy. */ proxy = detect_proxy(conn); -#else /* !CURL_DISABLE_HTTP */ - proxy = NULL; #endif /* CURL_DISABLE_HTTP */ Curl_safefree(no_proxy); @@ -5348,12 +5419,15 @@ static CURLcode create_conn_helper_init_proxy(struct connectdata *conn) result = CURLE_UNSUPPORTED_PROTOCOL; goto out; #else - /* force this connection's protocol to become HTTP if not already - compatible - if it isn't tunneling through */ - if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) && - !conn->bits.tunnel_proxy) - conn->handler = &Curl_handler_http; - + /* force this connection's protocol to become HTTP if compatible */ + if(!(conn->handler->protocol & PROTO_FAMILY_HTTP)) { + if((conn->handler->flags & PROTOPT_PROXY_AS_HTTP) && + !conn->bits.tunnel_proxy) + conn->handler = &Curl_handler_http; + else + /* if not converting to HTTP over the proxy, enforce tunneling */ + conn->bits.tunnel_proxy = TRUE; + } conn->bits.httpproxy = TRUE; #endif } @@ -5740,7 +5814,7 @@ static CURLcode parse_remote_port(struct Curl_easy *data, char *rest; long port; - port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */ + port = strtol(portptr + 1, &rest, 10); /* Port number must be decimal */ if((port < 0) || (port > 0xffff)) { /* Single unix standard says port numbers are 16 bits long */ @@ -6096,7 +6170,7 @@ static CURLcode resolve_server(struct Curl_easy *data, struct connectdata *conn, bool *async) { - CURLcode result=CURLE_OK; + CURLcode result = CURLE_OK; time_t timeout_ms = Curl_timeleft(data, NULL, TRUE); /************************************************************* @@ -6259,11 +6333,10 @@ static void reuse_conn(struct connectdata *old_conn, free_fixed_hostname(&conn->conn_to_host); Curl_safefree(conn->host.rawalloc); Curl_safefree(conn->conn_to_host.rawalloc); - conn->host=old_conn->host; - conn->bits.conn_to_host = old_conn->bits.conn_to_host; + conn->host = old_conn->host; conn->conn_to_host = old_conn->conn_to_host; - conn->bits.conn_to_port = old_conn->bits.conn_to_port; conn->conn_to_port = old_conn->conn_to_port; + conn->remote_port = old_conn->remote_port; /* persist connection info in session handle */ Curl_persistconninfo(conn); @@ -6362,9 +6435,9 @@ static CURLcode create_conn(struct Curl_easy *data, * other parts of the code will rely on this fact ***********************************************************/ #define LEAST_PATH_ALLOC 256 - urllen=strlen(data->change.url); + urllen = strlen(data->change.url); if(urllen < LEAST_PATH_ALLOC) - urllen=LEAST_PATH_ALLOC; + urllen = LEAST_PATH_ALLOC; /* * We malloc() the buffers below urllen+2 to make room for 2 possibilities: @@ -6375,14 +6448,14 @@ static CURLcode create_conn(struct Curl_easy *data, Curl_safefree(data->state.pathbuffer); data->state.path = NULL; - data->state.pathbuffer = malloc(urllen+2); + data->state.pathbuffer = malloc(urllen + 2); if(NULL == data->state.pathbuffer) { result = CURLE_OUT_OF_MEMORY; /* really bad error */ goto out; } data->state.path = data->state.pathbuffer; - conn->host.rawalloc = malloc(urllen+2); + conn->host.rawalloc = malloc(urllen + 2); if(NULL == conn->host.rawalloc) { Curl_safefree(data->state.pathbuffer); data->state.path = NULL; @@ -7015,7 +7088,7 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) k->buf = data->state.buffer; k->hbufp = data->state.headerbuff; - k->ignorebody=FALSE; + k->ignorebody = FALSE; Curl_speedinit(data); |