* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include <limits.h>
#endif
-#ifdef USE_LIBIDN2
-#include <idn2.h>
-
+#ifdef USE_LIBIDN
+#include <idna.h>
+#include <tld.h>
+#include <stringprep.h>
+#ifdef HAVE_IDN_FREE_H
+#include <idn-free.h>
+#else
+/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
+void idn_free (void *ptr);
+#endif
+#ifndef HAVE_IDN_FREE
+/* if idn_free() was not found in this version of libidn use free() instead */
+#define idn_free(x) (free)(x)
+#endif
#elif defined(USE_WIN32_IDN)
/* prototype for curl_win32_idn_to_ascii() */
bool curl_win32_idn_to_ascii(const char *in, char **out);
-#endif /* USE_LIBIDN2 */
+#endif /* USE_LIBIDN */
#include "urldata.h"
#include "netrc.h"
#include "sendf.h"
#include "progress.h"
#include "cookie.h"
-#include "strcase.h"
+#include "strequal.h"
#include "strerror.h"
#include "escape.h"
#include "strtok.h"
#include "multiif.h"
#include "easyif.h"
#include "speedcheck.h"
+#include "rawstr.h"
#include "warnless.h"
#include "non-ascii.h"
#include "inet_pton.h"
-#include "getinfo.h"
/* And now for the protocols */
#include "ftp.h"
}
data->change.url = NULL;
- Curl_safefree(data->state.buffer);
Curl_safefree(data->state.headerbuff);
Curl_flush_cookies(data, 1);
/* this destroys the channel and we cannot use it anymore after this */
Curl_resolver_cleanup(data->state.resolver);
- Curl_http2_cleanup_dependencies(data);
Curl_convert_close(data);
/* No longer a dirty share, if it exists */
set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
/* Set the default size of the SSL session ID cache */
- set->general_ssl.max_ssl_sessions = 5;
+ set->ssl.max_ssl_sessions = 5;
- set->proxyport = 0;
+ set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
* libcurl 7.10 introduced SSL verification *by default*! This needs to be
* switched off unless wanted.
*/
- set->ssl.primary.verifypeer = TRUE;
- set->ssl.primary.verifyhost = TRUE;
+ set->ssl.verifypeer = TRUE;
+ set->ssl.verifyhost = TRUE;
#ifdef USE_TLS_SRP
set->ssl.authtype = CURL_TLSAUTH_NONE;
#endif
set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
type */
- set->general_ssl.sessionid = TRUE; /* session ID caching enabled by
- default */
- set->proxy_ssl = set->ssl;
+ set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
set->new_file_perms = 0644; /* Default permissions */
set->new_directory_perms = 0755; /* Default permissions */
/* This is our preferred CA cert bundle/path since install time */
#if defined(CURL_CA_BUNDLE)
- result = setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE);
- if(result)
- return result;
-
- result = setstropt(&set->str[STRING_SSL_CAFILE_PROXY], CURL_CA_BUNDLE);
+ result = setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE);
if(result)
return result;
#endif
#if defined(CURL_CA_PATH)
- result = setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH);
- if(result)
- return result;
-
- result = setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH);
+ result = setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH);
if(result)
return result;
#endif
/* We do some initial setup here, all those fields that can't be just 0 */
- data->state.buffer = malloc(BUFSIZE + 1);
- if(!data->state.buffer) {
- DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
- result = CURLE_OUT_OF_MEMORY;
- }
-
data->state.headerbuff = malloc(HEADERSIZE);
if(!data->state.headerbuff) {
DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
Curl_convert_init(data);
- Curl_initinfo(data);
-
/* most recent connection is not yet defined */
data->state.lastconnect = NULL;
if(result) {
Curl_resolver_cleanup(data->state.resolver);
- free(data->state.buffer);
free(data->state.headerbuff);
Curl_freeset(data);
free(data);
break;
case CURLOPT_SSL_CIPHER_LIST:
/* set a list of cipher we want to use in the SSL connection */
- result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
- va_arg(param, char *));
- break;
- case CURLOPT_PROXY_SSL_CIPHER_LIST:
- /* set a list of cipher we want to use in the SSL connection for proxy */
- result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY],
+ result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
va_arg(param, char *));
break;
*/
data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
- case CURLOPT_KEEP_SENDING_ON_ERROR:
- data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
- TRUE : FALSE;
- break;
case CURLOPT_UPLOAD:
case CURLOPT_PUT:
/*
* implementations are lame.
*/
#ifdef USE_SSL
- data->set.ssl.primary.version = va_arg(param, long);
-#else
- result = CURLE_UNKNOWN_OPTION;
-#endif
- break;
- case CURLOPT_PROXY_SSLVERSION:
- /*
- * Set explicit SSL version to try to connect with for proxy, as some SSL
- * implementations are lame.
- */
-#ifdef USE_SSL
- data->set.proxy_ssl.primary.version = va_arg(param, long);
+ data->set.ssl.version = va_arg(param, long);
#else
result = CURLE_UNKNOWN_OPTION;
#endif
(data->set.postfieldsize > (curl_off_t)((size_t)-1))))
result = CURLE_OUT_OF_MEMORY;
else {
- char *p;
+ char * p;
(void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
if(argptr == NULL)
break;
- if(strcasecompare(argptr, "ALL")) {
+ if(Curl_raw_equal(argptr, "ALL")) {
/* clear all cookies */
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
Curl_cookie_clearall(data->cookies);
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
}
- else if(strcasecompare(argptr, "SESS")) {
+ else if(Curl_raw_equal(argptr, "SESS")) {
/* clear session cookies */
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
Curl_cookie_clearsess(data->cookies);
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
}
- else if(strcasecompare(argptr, "FLUSH")) {
+ else if(Curl_raw_equal(argptr, "FLUSH")) {
/* flush cookies to file, takes care of the locking */
Curl_flush_cookies(data, 0);
}
- else if(strcasecompare(argptr, "RELOAD")) {
+ else if(Curl_raw_equal(argptr, "RELOAD")) {
/* reload cookies from file */
Curl_cookie_loadfiles(data);
break;
case CURLOPT_PROXY:
/*
- * Set proxy server:port to use as proxy.
+ * Set proxy server:port to use as HTTP proxy.
*
- * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL)
- * we explicitly say that we don't want to use a proxy
- * (even though there might be environment variables saying so).
+ * If the proxy is set to "" we explicitly say that we don't want to use a
+ * proxy (even though there might be environment variables saying so).
*
* Setting it to NULL, means no proxy but allows the environment variables
- * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL).
+ * to decide for us.
*/
result = setstropt(&data->set.str[STRING_PROXY],
va_arg(param, char *));
break;
- case CURLOPT_PRE_PROXY:
- /*
- * Set proxy server:port to use as SOCKS proxy.
- *
- * If the proxy is set to "" or NULL we explicitly say that we don't want
- * to use the socks proxy.
- */
- result = setstropt(&data->set.str[STRING_PRE_PROXY],
- va_arg(param, char *));
- break;
-
case CURLOPT_PROXYTYPE:
/*
* Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
/*
* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
*/
- switch(va_arg(param, long)) {
+ switch (va_arg(param, long)) {
case 0:
data->set.proxy_transfer_mode = FALSE;
break;
/*
* String that holds file name of the SSL certificate to use
*/
- result = setstropt(&data->set.str[STRING_CERT_ORIG],
- va_arg(param, char *));
- break;
- case CURLOPT_PROXY_SSLCERT:
- /*
- * String that holds file name of the SSL certificate to use for proxy
- */
- result = setstropt(&data->set.str[STRING_CERT_PROXY],
+ result = setstropt(&data->set.str[STRING_CERT],
va_arg(param, char *));
break;
case CURLOPT_SSLCERTTYPE:
/*
* String that holds file type of the SSL certificate to use
*/
- result = setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
- va_arg(param, char *));
- break;
- case CURLOPT_PROXY_SSLCERTTYPE:
- /*
- * String that holds file type of the SSL certificate to use for proxy
- */
- result = setstropt(&data->set.str[STRING_CERT_TYPE_PROXY],
+ result = setstropt(&data->set.str[STRING_CERT_TYPE],
va_arg(param, char *));
break;
case CURLOPT_SSLKEY:
/*
* String that holds file name of the SSL key to use
*/
- result = setstropt(&data->set.str[STRING_KEY_ORIG],
- va_arg(param, char *));
- break;
- case CURLOPT_PROXY_SSLKEY:
- /*
- * String that holds file name of the SSL key to use for proxy
- */
- result = setstropt(&data->set.str[STRING_KEY_PROXY],
+ result = setstropt(&data->set.str[STRING_KEY],
va_arg(param, char *));
break;
case CURLOPT_SSLKEYTYPE:
/*
* String that holds file type of the SSL key to use
*/
- result = setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
- va_arg(param, char *));
- break;
- case CURLOPT_PROXY_SSLKEYTYPE:
- /*
- * String that holds file type of the SSL key to use for proxy
- */
- result = setstropt(&data->set.str[STRING_KEY_TYPE_PROXY],
+ result = setstropt(&data->set.str[STRING_KEY_TYPE],
va_arg(param, char *));
break;
case CURLOPT_KEYPASSWD:
/*
* String that holds the SSL or SSH private key password.
*/
- result = setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
- va_arg(param, char *));
- break;
- case CURLOPT_PROXY_KEYPASSWD:
- /*
- * String that holds the SSL private key password for proxy.
- */
- result = setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY],
+ result = setstropt(&data->set.str[STRING_KEY_PASSWD],
va_arg(param, char *));
break;
case CURLOPT_SSLENGINE:
/*
* Enable peer SSL verifying.
*/
- data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ?
- TRUE : FALSE;
- break;
- case CURLOPT_PROXY_SSL_VERIFYPEER:
- /*
- * Enable peer SSL verifying for proxy.
- */
- data->set.proxy_ssl.primary.verifypeer =
- (0 != va_arg(param, long))?TRUE:FALSE;
+ data->set.ssl.verifypeer = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
case CURLOPT_SSL_VERIFYHOST:
/*
return CURLE_BAD_FUNCTION_ARGUMENT;
}
- data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
- break;
- case CURLOPT_PROXY_SSL_VERIFYHOST:
- /*
- * Enable verification of the host name in the peer certificate for proxy
- */
- arg = va_arg(param, long);
-
- /* Obviously people are not reading documentation and too many thought
- this argument took a boolean when it wasn't and misused it. We thus ban
- 1 as a sensible input and we warn about its use. Then we only have the
- 2 action internally stored as TRUE. */
-
- if(1 == arg) {
- failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
- return CURLE_BAD_FUNCTION_ARGUMENT;
- }
-
- data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
+ data->set.ssl.verifyhost = (0 != arg) ? TRUE : FALSE;
break;
case CURLOPT_SSL_VERIFYSTATUS:
/*
break;
}
- data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ?
- TRUE : FALSE;
+ data->set.ssl.verifystatus = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
case CURLOPT_SSL_CTX_FUNCTION:
#ifdef have_curlssl_ssl_ctx
* 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;
-#endif
- 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],
+ result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
va_arg(param, char *));
#else
result = CURLE_NOT_BUILT_IN;
/*
* Set CA info for SSL connection. Specify file name of the CA certificate
*/
- result = setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
- va_arg(param, char *));
- break;
- case CURLOPT_PROXY_CAINFO:
- /*
- * Set CA info SSL connection for proxy. Specify file name of the
- * CA certificate
- */
- result = setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
+ result = setstropt(&data->set.str[STRING_SSL_CAFILE],
va_arg(param, char *));
break;
case CURLOPT_CAPATH:
* 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;
-#endif
- 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],
+ result = setstropt(&data->set.str[STRING_SSL_CAPATH],
va_arg(param, char *));
#else
result = CURLE_NOT_BUILT_IN;
* Set CRL file info for SSL connection. Specify file name of the CRL
* to check certificates revocation
*/
- result = setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
- va_arg(param, char *));
- break;
- case CURLOPT_PROXY_CRLFILE:
- /*
- * Set CRL file info for SSL connection for proxy. Specify file name of the
- * CRL to check certificates revocation
- */
- result = setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY],
+ result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
va_arg(param, char *));
break;
case CURLOPT_ISSUERCERT:
* Set Issuer certificate file
* to check certificates issuer
*/
- result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
+ result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
va_arg(param, char *));
break;
case CURLOPT_TELNETOPTIONS:
*/
data->set.buffer_size = va_arg(param, long);
- if(data->set.buffer_size > MAX_BUFSIZE)
- data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
- else if(data->set.buffer_size < 1)
- data->set.buffer_size = BUFSIZE;
-
- /* Resize only if larger than default buffer size. */
- if(data->set.buffer_size > BUFSIZE) {
- data->state.buffer = realloc(data->state.buffer,
- data->set.buffer_size + 1);
- if(!data->state.buffer) {
- DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
- result = CURLE_OUT_OF_MEMORY;
- }
- }
+ if((data->set.buffer_size> (BUFSIZE -1)) ||
+ (data->set.buffer_size < 1))
+ data->set.buffer_size = 0; /* huge internal default */
break;
}
#endif /* CURL_DISABLE_HTTP */
if(data->share->sslsession) {
- data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
+ data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
data->state.session = data->share->sslsession;
}
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
case CURLOPT_SSL_OPTIONS:
arg = va_arg(param, long);
- data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
- data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
- break;
-
- case CURLOPT_PROXY_SSL_OPTIONS:
- arg = va_arg(param, long);
- data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
- data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+ data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
+ data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
break;
#endif
break;
case CURLOPT_SSL_SESSIONID_CACHE:
- data->set.general_ssl.sessionid = (0 != va_arg(param, long)) ?
- TRUE : FALSE;
+ data->set.ssl.sessionid = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
#ifdef USE_LIBSSH2
break;
#ifdef USE_TLS_SRP
case CURLOPT_TLSAUTH_USERNAME:
- result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
+ result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
va_arg(param, char *));
- if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
+ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
break;
- case CURLOPT_PROXY_TLSAUTH_USERNAME:
- result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
- va_arg(param, char *));
- if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
- !data->set.proxy_ssl.authtype)
- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
- break;
case CURLOPT_TLSAUTH_PASSWORD:
- result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
+ result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
va_arg(param, char *));
- if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
+ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
break;
- case CURLOPT_PROXY_TLSAUTH_PASSWORD:
- result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
- va_arg(param, char *));
- if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
- !data->set.proxy_ssl.authtype)
- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
- break;
case CURLOPT_TLSAUTH_TYPE:
- if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
+ if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
data->set.ssl.authtype = CURL_TLSAUTH_SRP;
else
data->set.ssl.authtype = CURL_TLSAUTH_NONE;
break;
- case CURLOPT_PROXY_TLSAUTH_TYPE:
- if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
- else
- data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
- break;
#endif
case CURLOPT_DNS_SERVERS:
result = Curl_set_dns_servers(data, va_arg(param, char *));
#ifdef USE_UNIX_SOCKETS
case CURLOPT_UNIX_SOCKET_PATH:
- data->set.abstract_unix_socket = FALSE;
- result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
- va_arg(param, char *));
- break;
- case CURLOPT_ABSTRACT_UNIX_SOCKET:
- data->set.abstract_unix_socket = TRUE;
result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
va_arg(param, char *));
break;
return CURLE_NOT_BUILT_IN;
#else
struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
- if(!dep || GOOD_EASY_HANDLE(dep)) {
- if(data->set.stream_depends_on) {
- Curl_http2_remove_child(data->set.stream_depends_on, data);
- }
- Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E));
+ if(dep && GOOD_EASY_HANDLE(dep)) {
+ data->set.stream_depends_on = dep;
+ data->set.stream_depends_e = (option == CURLOPT_STREAM_DEPENDS_E);
}
break;
#endif
#endif /* DEBUGBUILD */
}
else {
- DEBUGASSERT(psnd->allocated_size == 0);
- DEBUGASSERT(psnd->recv_size == 0);
- DEBUGASSERT(psnd->recv_processed == 0);
- DEBUGASSERT(psnd->bindsock == CURL_SOCKET_BAD);
+ DEBUGASSERT (psnd->allocated_size == 0);
+ DEBUGASSERT (psnd->recv_size == 0);
+ DEBUGASSERT (psnd->recv_processed == 0);
+ DEBUGASSERT (psnd->bindsock == CURL_SOCKET_BAD);
}
}
Curl_safefree(conn->passwd);
Curl_safefree(conn->oauth_bearer);
Curl_safefree(conn->options);
- Curl_safefree(conn->http_proxy.user);
- Curl_safefree(conn->socks_proxy.user);
- Curl_safefree(conn->http_proxy.passwd);
- Curl_safefree(conn->socks_proxy.passwd);
+ Curl_safefree(conn->proxyuser);
+ Curl_safefree(conn->proxypasswd);
Curl_safefree(conn->allocptr.proxyuserpwd);
Curl_safefree(conn->allocptr.uagent);
Curl_safefree(conn->allocptr.userpwd);
Curl_safefree(conn->trailer);
Curl_safefree(conn->host.rawalloc); /* host name buffer */
Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
- Curl_safefree(conn->secondaryhostname);
- 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->proxy.rawalloc); /* proxy name buffer */
Curl_safefree(conn->master_buffer);
conn_reset_all_postponed_data(conn);
conn->recv_pipe = NULL;
Curl_safefree(conn->localdev);
- Curl_free_primary_ssl_config(&conn->ssl_config);
- Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
-
-#ifdef USE_UNIX_SOCKETS
- Curl_safefree(conn->unix_domain_socket);
-#endif
+ Curl_free_ssl_config(&conn->ssl_config);
free(conn); /* free all the connection oriented data */
}
free_fixed_hostname(&conn->host);
free_fixed_hostname(&conn->conn_to_host);
- free_fixed_hostname(&conn->http_proxy.host);
- free_fixed_hostname(&conn->socks_proxy.host);
+ free_fixed_hostname(&conn->proxy);
Curl_ssl_close(conn, FIRSTSOCKET);
int sval;
bool ret_val = TRUE;
- sval = SOCKET_READABLE(sock, 0);
+ sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
if(sval == 0)
/* timeout */
ret_val = FALSE;
const struct connectdata *conn)
{
/* If a HTTP protocol and pipelining is enabled */
- if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
- (!conn->bits.protoconnstart || !conn->bits.close)) {
+ if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
(handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
struct curl_hash_iterator iter;
struct curl_llist_element *curr;
struct curl_hash_element *he;
- time_t highscore=-1;
- time_t score;
+ long highscore=-1;
+ long score;
struct timeval now;
struct connectdata *conn_candidate = NULL;
struct connectbundle *bundle;
return conn_candidate;
}
-static bool
-proxy_info_matches(const struct proxy_info* data,
- const struct proxy_info* needle)
-{
- if((data->proxytype == needle->proxytype) &&
- (data->port == needle->port) &&
- Curl_safe_strcasecompare(data->host.name, needle->host.name) &&
- Curl_safe_strcasecompare(data->user, needle->user) &&
- Curl_safe_strcasecompare(data->passwd, needle->passwd))
- return TRUE;
-
- return FALSE;
-}
-
-
/*
* This function finds the connection in the connection
* bundle that has been unused for the longest time.
struct connectbundle *bundle)
{
struct curl_llist_element *curr;
- time_t highscore=-1;
- time_t score;
+ long highscore=-1;
+ long score;
struct timeval now;
struct connectdata *conn_candidate = NULL;
struct connectdata *conn;
static void prune_dead_connections(struct Curl_easy *data)
{
struct timeval now = Curl_tvnow();
- time_t elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
+ long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
if(elapsed >= 1000L) {
Curl_conncache_foreach(data->state.conn_cache, data,
max_pipeline_length(data->multi):0;
size_t best_pipe_len = max_pipe_len;
struct curl_llist_element *curr;
+ const char *hostname;
+
+ if(needle->bits.conn_to_host)
+ hostname = needle->conn_to_host.name;
+ else
+ hostname = needle->host.name;
infof(data, "Found bundle for host %s: %p [%s]\n",
- (needle->bits.conn_to_host ? needle->conn_to_host.name :
- needle->host.name), (void *)bundle,
- (bundle->multiuse == BUNDLE_PIPELINING ?
- "can pipeline" :
- (bundle->multiuse == BUNDLE_MULTIPLEX ?
- "can multiplex" : "serially")));
+ hostname, (void *)bundle,
+ (bundle->multiuse== BUNDLE_PIPELINING?
+ "can pipeline":
+ (bundle->multiuse== BUNDLE_MULTIPLEX?
+ "can multiplex":"serially")));
/* We can't pipe if we don't know anything about the server */
if(canPipeline) {
pipeLen = check->send_pipe->size + check->recv_pipe->size;
if(canPipeline) {
- if(check->bits.protoconnstart && check->bits.close)
- continue;
if(!check->bits.multiplex) {
/* If not multiplexing, make sure the pipe has only GET requests */
}
}
-#ifdef USE_UNIX_SOCKETS
- if(needle->unix_domain_socket) {
- if(!check->unix_domain_socket)
- continue;
- if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
- continue;
- if(needle->abstract_unix_socket != check->abstract_unix_socket)
- continue;
- }
- else if(check->unix_domain_socket)
- continue;
-#endif
-
if((needle->handler->flags&PROTOPT_SSL) !=
(check->handler->flags&PROTOPT_SSL))
/* don't do mixed SSL and non-SSL connections */
/* except protocols that have been upgraded via TLS */
continue;
- if(needle->bits.httpproxy != check->bits.httpproxy ||
- needle->bits.socksproxy != check->bits.socksproxy)
+ if(needle->handler->flags&PROTOPT_SSL) {
+ if((data->set.ssl.verifypeer != check->verifypeer) ||
+ (data->set.ssl.verifyhost != check->verifyhost))
+ continue;
+ }
+
+ if(needle->bits.proxy != check->bits.proxy)
+ /* don't do mixed proxy and non-proxy connections */
continue;
- if(needle->bits.socksproxy && !proxy_info_matches(&needle->socks_proxy,
- &check->socks_proxy))
+ if(needle->bits.proxy &&
+ (needle->proxytype != check->proxytype ||
+ needle->bits.httpproxy != check->bits.httpproxy ||
+ needle->bits.tunnel_proxy != check->bits.tunnel_proxy ||
+ !Curl_raw_equal(needle->proxy.name, check->proxy.name) ||
+ needle->port != check->port))
+ /* don't mix connections that use different proxies */
continue;
if(needle->bits.conn_to_host != check->bits.conn_to_host)
* connections that don't use this feature */
continue;
- if(needle->bits.httpproxy) {
- if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
- continue;
-
- if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy)
- continue;
-
- if(needle->http_proxy.proxytype == CURLPROXY_HTTPS) {
- /* use https proxy */
- if(needle->handler->flags&PROTOPT_SSL) {
- /* use double layer ssl */
- if(!Curl_ssl_config_matches(&needle->proxy_ssl_config,
- &check->proxy_ssl_config))
- continue;
- if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
- continue;
- }
- else {
- if(!Curl_ssl_config_matches(&needle->ssl_config,
- &check->ssl_config))
- continue;
- if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
- continue;
- }
- }
- }
-
if(!canPipeline && check->inuse)
/* this request can't be pipelined but the checked connection is
already in use so we skip it */
*/
if((check->localport != needle->localport) ||
(check->localportrange != needle->localportrange) ||
- (needle->localdev &&
- (!check->localdev || strcmp(check->localdev, needle->localdev))))
+ !check->localdev ||
+ !needle->localdev ||
+ strcmp(check->localdev, needle->localdev))
continue;
}
if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
/* This protocol requires credentials per connection,
so verify that we're using the same name and password as well */
- if(strcmp(needle->user, check->user) ||
- strcmp(needle->passwd, check->passwd)) {
+ if(!strequal(needle->user, check->user) ||
+ !strequal(needle->passwd, check->passwd)) {
/* one of them was different */
continue;
}
}
if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
- needle->bits.tunnel_proxy) {
+ (needle->bits.httpproxy && needle->bits.tunnel_proxy)) {
/* The requested connection does not use a HTTP proxy or it uses SSL or
- it is a non-SSL protocol tunneled or it is a non-SSL protocol which
- is allowed to be upgraded via TLS */
-
- if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
+ it is a non-SSL protocol tunneled over the same HTTP proxy name and
+ port number */
+ if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
(get_protocol_family(check->handler->protocol) ==
needle->handler->protocol && check->tls_upgraded)) &&
- (!needle->bits.conn_to_host || strcasecompare(
+ (!needle->bits.conn_to_host || Curl_raw_equal(
needle->conn_to_host.name, check->conn_to_host.name)) &&
(!needle->bits.conn_to_port ||
needle->conn_to_port == check->conn_to_port) &&
- strcasecompare(needle->host.name, check->host.name) &&
+ Curl_raw_equal(needle->host.name, check->host.name) &&
needle->remote_port == check->remote_port) {
/* The schemes match or the the protocol family is the same and the
previous connection was TLS upgraded, and the hostname and host
possible. (Especially we must not reuse the same connection if
partway through a handshake!) */
if(wantNTLMhttp) {
- if(strcmp(needle->user, check->user) ||
- strcmp(needle->passwd, check->passwd))
+ if(!strequal(needle->user, check->user) ||
+ !strequal(needle->passwd, check->passwd))
continue;
}
else if(check->ntlm.state != NTLMSTATE_NONE) {
/* Same for Proxy NTLM authentication */
if(wantProxyNTLMhttp) {
- /* Both check->http_proxy.user and check->http_proxy.passwd can be
- * NULL */
- if(!check->http_proxy.user || !check->http_proxy.passwd)
+ /* Both check->proxyuser and check->proxypasswd can be NULL */
+ if(!check->proxyuser || !check->proxypasswd)
continue;
- if(strcmp(needle->http_proxy.user, check->http_proxy.user) ||
- strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
+ if(!strequal(needle->proxyuser, check->proxyuser) ||
+ !strequal(needle->proxypasswd, check->proxypasswd))
continue;
}
else if(check->proxyntlm.state != NTLMSTATE_NONE) {
Note: this function's sub-functions call failf()
*/
-CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
+CURLcode Curl_connected_proxy(struct connectdata *conn,
+ int sockindex)
{
- CURLcode result = CURLE_OK;
+ if(!conn->bits.proxy || sockindex)
+ /* this magic only works for the primary socket as the secondary is used
+ for FTP only and it has FTP specific magic in ftp.c */
+ return CURLE_OK;
- if(conn->bits.socksproxy) {
+ switch(conn->proxytype) {
#ifndef CURL_DISABLE_PROXY
- /* for the secondary socket (FTP), use the "connect to host"
- * but ignore the "connect to port" (use the secondary port)
- */
- const char * const host = conn->bits.httpproxy ?
- conn->http_proxy.host.name :
- conn->bits.conn_to_host ?
- conn->conn_to_host.name :
- sockindex == SECONDARYSOCKET ?
- conn->secondaryhostname : conn->host.name;
- const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
- sockindex == SECONDARYSOCKET ? conn->secondary_port :
- conn->bits.conn_to_port ? conn->conn_to_port :
- conn->remote_port;
- conn->bits.socksproxy_connecting = TRUE;
- switch(conn->socks_proxy.proxytype) {
- case CURLPROXY_SOCKS5:
- case CURLPROXY_SOCKS5_HOSTNAME:
- result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
- host, port, sockindex, conn);
- break;
+ case CURLPROXY_SOCKS5:
+ case CURLPROXY_SOCKS5_HOSTNAME:
+ return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
+ conn->bits.conn_to_host ? conn->conn_to_host.name :
+ conn->host.name,
+ conn->bits.conn_to_port ? conn->conn_to_port :
+ conn->remote_port,
+ FIRSTSOCKET, conn);
+
+ case CURLPROXY_SOCKS4:
+ return Curl_SOCKS4(conn->proxyuser,
+ conn->bits.conn_to_host ? conn->conn_to_host.name :
+ conn->host.name,
+ conn->bits.conn_to_port ? conn->conn_to_port :
+ conn->remote_port,
+ FIRSTSOCKET, conn, FALSE);
+
+ case CURLPROXY_SOCKS4A:
+ return Curl_SOCKS4(conn->proxyuser,
+ conn->bits.conn_to_host ? conn->conn_to_host.name :
+ conn->host.name,
+ conn->bits.conn_to_port ? conn->conn_to_port :
+ conn->remote_port,
+ FIRSTSOCKET, conn, TRUE);
- case CURLPROXY_SOCKS4:
- case CURLPROXY_SOCKS4A:
- result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
- conn);
- break;
-
- default:
- failf(conn->data, "unknown proxytype option given");
- result = CURLE_COULDNT_CONNECT;
- } /* switch proxytype */
- conn->bits.socksproxy_connecting = FALSE;
-#else
- (void)sockindex;
#endif /* CURL_DISABLE_PROXY */
- }
+ case CURLPROXY_HTTP:
+ case CURLPROXY_HTTP_1_0:
+ /* do nothing here. handled later. */
+ break;
+ default:
+ break;
+ } /* switch proxytype */
- return result;
+ return CURLE_OK;
}
/*
{
if(conn->data->set.verbose)
infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
- conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
- conn->bits.httpproxy ? conn->http_proxy.host.dispname :
- conn->bits.conn_to_host ? conn->conn_to_host.dispname :
- conn->host.dispname,
+ conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
conn->ip_addr_str, conn->port, conn->connection_id);
}
#endif
if(!conn->bits.protoconnstart) {
- result = Curl_proxy_connect(conn, FIRSTSOCKET);
+ result = Curl_proxy_connect(conn);
if(result)
return result;
- if(CONNECT_FIRSTSOCKET_PROXY_SSL())
- /* wait for HTTPS proxy SSL initialization to complete */
- return CURLE_OK;
-
if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
(conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
/* when using an HTTP tunnel proxy, await complete tunnel establishment
*/
static bool is_ASCII_name(const char *hostname)
{
- const unsigned char *ch = (const unsigned char *)hostname;
+ const unsigned char *ch = (const unsigned char*)hostname;
while(*ch) {
if(*ch++ & 0x80)
return TRUE;
}
+#ifdef USE_LIBIDN
+/*
+ * Check if characters in hostname is allowed in Top Level Domain.
+ */
+static bool tld_check_name(struct Curl_easy *data,
+ const char *ace_hostname)
+{
+ size_t err_pos;
+ char *uc_name = NULL;
+ int rc;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ const char *tld_errmsg = "<no msg>";
+#else
+ (void)data;
+#endif
+
+ /* Convert (and downcase) ACE-name back into locale's character set */
+ rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
+ if(rc != IDNA_SUCCESS)
+ return FALSE;
+
+ /* Warning: err_pos receives "the decoded character offset rather than the
+ byte position in the string." And as of libidn 1.32 that character offset
+ is for UTF-8, even if the passed in string is another locale. */
+ rc = tld_check_lz(uc_name, &err_pos, NULL);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+#ifdef HAVE_TLD_STRERROR
+ if(rc != TLD_SUCCESS)
+ tld_errmsg = tld_strerror((Tld_rc)rc);
+#endif
+ if(rc != TLD_SUCCESS)
+ infof(data, "WARNING: TLD check for %s failed; %s\n",
+ uc_name, tld_errmsg);
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
+ if(uc_name)
+ idn_free(uc_name);
+ if(rc != TLD_SUCCESS)
+ return FALSE;
+
+ return TRUE;
+}
+#endif
+
/*
* Perform any necessary IDN conversion of hostname
*/
-static void fix_hostname(struct connectdata *conn, struct hostname *host)
+static void fix_hostname(struct Curl_easy *data,
+ struct connectdata *conn, struct hostname *host)
{
size_t len;
- struct Curl_easy *data = conn->data;
-#ifndef USE_LIBIDN2
+#ifndef USE_LIBIDN
(void)data;
(void)conn;
#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
/* Check name for non-ASCII and convert hostname to ACE form if we can */
if(!is_ASCII_name(host->name)) {
-#ifdef USE_LIBIDN2
- if(idn2_check_version(IDN2_VERSION)) {
+#ifdef USE_LIBIDN
+ if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
char *ace_hostname = NULL;
-#if IDN2_VERSION_NUMBER >= 0x00140000
- /* IDN2_NFC_INPUT: Normalize input string using normalization form C.
- IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional
- processing. */
- int flags = IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL;
-#else
- int flags = IDN2_NFC_INPUT;
-#endif
- int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags);
- if(rc == IDN2_OK) {
- host->encalloc = (char *)ace_hostname;
+
+ int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
+ infof(data, "Input domain encoded as `%s'\n",
+ stringprep_locale_charset());
+ if(rc == IDNA_SUCCESS) {
+ /* tld_check_name() displays a warning if the host name contains
+ "illegal" characters for this TLD */
+ (void)tld_check_name(data, ace_hostname);
+
+ host->encalloc = ace_hostname;
/* change the name pointer to point to the encoded hostname */
host->name = host->encalloc;
}
else
infof(data, "Failed to convert %s to ACE; %s\n", host->name,
- idn2_strerror(rc));
+ Curl_idn_strerror(conn, rc));
}
#elif defined(USE_WIN32_IDN)
char *ace_hostname = NULL;
*/
static void free_fixed_hostname(struct hostname *host)
{
-#if defined(USE_LIBIDN2)
+#if defined(USE_LIBIDN)
if(host->encalloc) {
- idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
+ idn_free(host->encalloc); /* must be freed with idn_free() since this was
allocated by libidn */
host->encalloc = NULL;
}
conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
conn->connection_id = -1; /* no ID */
conn->port = -1; /* unknown at this point */
- conn->remote_port = -1; /* unknown at this point */
+ conn->remote_port = -1; /* unknown */
#if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
conn->data = data; /* Setup the association between this connection
and the Curl_easy */
- conn->http_proxy.proxytype = data->set.proxytype;
- conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
+ conn->proxytype = data->set.proxytype; /* type */
#ifdef CURL_DISABLE_PROXY
conn->bits.proxy = FALSE;
conn->bits.httpproxy = FALSE;
- conn->bits.socksproxy = FALSE;
conn->bits.proxy_user_passwd = FALSE;
conn->bits.tunnel_proxy = FALSE;
conn->bits.proxy = (data->set.str[STRING_PROXY] &&
*data->set.str[STRING_PROXY]) ? TRUE : FALSE;
conn->bits.httpproxy = (conn->bits.proxy &&
- (conn->http_proxy.proxytype == CURLPROXY_HTTP ||
- conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 ||
- conn->http_proxy.proxytype == CURLPROXY_HTTPS)) ?
- TRUE : FALSE;
- conn->bits.socksproxy = (conn->bits.proxy &&
- !conn->bits.httpproxy) ? TRUE : FALSE;
-
- if(data->set.str[STRING_PRE_PROXY] && *data->set.str[STRING_PRE_PROXY]) {
- conn->bits.proxy = TRUE;
- conn->bits.socksproxy = TRUE;
- }
-
- conn->bits.proxy_user_passwd =
- (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE;
+ (conn->proxytype == CURLPROXY_HTTP ||
+ conn->proxytype == CURLPROXY_HTTP_1_0)) ?
+ TRUE : FALSE;
+ conn->bits.proxy_user_passwd = (data->set.str[STRING_PROXYUSERNAME]) ?
+ TRUE : FALSE;
conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
#endif /* CURL_DISABLE_PROXY */
conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
- conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
- conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
- conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
- conn->proxy_ssl_config.verifystatus =
- data->set.proxy_ssl.primary.verifystatus;
- conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
- conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
+ conn->verifypeer = data->set.ssl.verifypeer;
+ conn->verifyhost = data->set.ssl.verifyhost;
conn->ip_version = data->set.ipver;
if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
!conn->master_buffer) {
/* Allocate master_buffer to be used for HTTP/1 pipelining */
- conn->master_buffer = calloc(BUFSIZE, sizeof(char));
+ conn->master_buffer = calloc(BUFSIZE, sizeof (char));
if(!conn->master_buffer)
goto error;
}
variables based on the URL. Now that the handler may be changed later
when the protocol specific setup function is called. */
for(pp = protocols; (p = *pp) != NULL; pp++) {
- if(strcasecompare(p->scheme, protostr)) {
+ if(Curl_raw_equal(p->scheme, protostr)) {
/* Protocol found in table. Check if allowed */
if(!(data->set.allowed_protocols & p->protocol))
/* nope, get out */
char *fragment;
char *path = data->state.path;
char *query;
- int i;
int rc;
+ char protobuf[16] = "";
const char *protop = "";
CURLcode result;
bool rebuild_url = FALSE;
- bool url_has_scheme = FALSE;
- char protobuf[16];
*prot_missing = FALSE;
* proxy -- and we don't know if we will need to use SSL until we parse the
* url ...
************************************************************/
- if(data->change.url[0] == ':') {
- failf(data, "Bad URL, colon is first character");
- return CURLE_URL_MALFORMAT;
- }
-
- /* Make sure we don't mistake a drive letter for a scheme, for example:
- 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] &&
- strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file")) {
- ; /* do nothing */
- }
- else { /* check for a scheme */
- for(i = 0; i < 16 && data->change.url[i]; ++i) {
- if(data->change.url[i] == '/')
- break;
- if(data->change.url[i] == ':') {
- url_has_scheme = TRUE;
- break;
- }
- }
- }
-
- /* handle the file: scheme */
- 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
- rc = sscanf(data->change.url, "%[^\n]", path);
-
- if(rc != 1) {
- failf(data, "Bad URL");
- return CURLE_URL_MALFORMAT;
- }
-
- if(url_has_scheme && path[0] == '/' && path[1] == '/') {
+ if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
+ protobuf, path)) &&
+ Curl_raw_equal(protobuf, "file")) {
+ if(path[0] == '/' && path[1] == '/') {
/* Allow omitted hostname (e.g. file:/<path>). This is not strictly
* speaking a valid file: URL by RFC 1738, but treating file:/<path> as
* file://localhost/<path> is similar to how other schemes treat missing
memory areas overlap! */
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) {
- /* the URL includes a host name, it must match "localhost" or
- "127.0.0.1" to be valid */
- char *ptr;
- if(!checkprefix("localhost/", path) &&
- !checkprefix("127.0.0.1/", path)) {
- failf(data, "Invalid file://hostname/, "
- "expected localhost or 127.0.0.1 or none");
- return CURLE_URL_MALFORMAT;
- }
- ptr = &path[9]; /* now points to the slash after the host */
+ if(path[0] != '/') {
+ /* the URL included a host name, we ignore host names in file:// URLs
+ as the standards don't define what to do with them */
+ char *ptr=strchr(path, '/');
+ if(ptr) {
+ /* there was a slash present
- /* there was a host name and slash present
+ RFC1738 (section 3.1, page 5) says:
- RFC1738 (section 3.1, page 5) says:
+ The rest of the locator consists of data specific to the scheme,
+ and is known as the "url-path". It supplies the details of how the
+ specified resource can be accessed. Note that the "/" between the
+ host (or port) and the url-path is NOT part of the url-path.
- The rest of the locator consists of data specific to the scheme,
- and is known as the "url-path". It supplies the details of how the
- specified resource can be accessed. Note that the "/" between the
- host (or port) and the url-path is NOT part of the url-path.
-
- As most agents use file://localhost/foo to get '/foo' although the
- slash preceding foo is a separator and not a slash for the path,
- a URL as file://localhost//foo must be valid as well, to refer to
- the same file with an absolute path.
- */
-
- if('/' == ptr[1])
- /* if there was two slashes, we skip the first one as that is then
- used truly as a separator */
- ptr++;
+ As most agents use file://localhost/foo to get '/foo' although the
+ slash preceding foo is a separator and not a slash for the path,
+ a URL as file://localhost//foo must be valid as well, to refer to
+ the same file with an absolute path.
+ */
- /* This cannot be made with strcpy, as the memory chunks overlap! */
- memmove(path, ptr, strlen(ptr)+1);
+ if(ptr[1] && ('/' == ptr[1]))
+ /* if there was two slashes, we skip the first one as that is then
+ used truly as a separator */
+ ptr++;
- path_has_drive = (('a' <= path[0] && path[0] <= 'z') ||
- ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':';
- }
-
-#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__)
- if(path_has_drive) {
- failf(data, "File drive letters are only accepted in MSDOS/Windows.");
- return CURLE_URL_MALFORMAT;
+ /* This cannot be made with strcpy, as the memory chunks overlap! */
+ memmove(path, ptr, strlen(ptr)+1);
+ }
}
-#endif
protop = "file"; /* protocol string */
}
path[0]=0;
rc = sscanf(data->change.url,
- "%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]",
+ "%15[^\n:]:%3[/]%[^\n/?]%[^\n]",
protobuf, slashbuf, conn->host.name, path);
if(2 == rc) {
failf(data, "Bad URL");
* The URL was badly formatted, let's try the browser-style _without_
* protocol specified like 'http://'.
*/
- rc = sscanf(data->change.url, "%[^\n/?#]%[^\n]", conn->host.name, path);
+ rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
if(1 > rc) {
/*
* We couldn't even get this format.
}
/* If the URL is malformatted (missing a '/' after hostname before path) we
- * insert a slash here. The only letters except '/' that can start a path is
- * '?' and '#' - as controlled by the two sscanf() patterns above.
+ * insert a slash here. The only letter except '/' we accept to start a path
+ * is '?'.
*/
- if(path[0] != '/') {
+ if(path[0] == '?') {
/* 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. */
data->change.url_alloc = TRUE; /* free this later */
}
- result = findprotocol(data, conn, protop);
- if(result)
- return result;
-
/*
* Parse the login details from the URL and strip them out of
* the host name
* conn->host.name is B
* data->state.path is /C
*/
- return CURLE_OK;
+
+ return findprotocol(data, conn, protop);
}
/*
* Checks if the host is in the noproxy list. returns true if it matches
* and therefore the proxy should NOT be used.
****************************************************************/
-static bool check_noproxy(const char *name, const char *no_proxy)
+static bool check_noproxy(const char* name, const char* no_proxy)
{
/* no_proxy=domain1.dom,host.domain2.dom
* (a comma-separated list of hosts which should
*/
size_t tok_start;
size_t tok_end;
- const char *separator = ", ";
+ const char* separator = ", ";
size_t no_proxy_len;
size_t namelen;
char *endptr;
if(no_proxy && no_proxy[0]) {
- if(strcasecompare("*", no_proxy)) {
+ if(Curl_raw_equal("*", no_proxy)) {
return TRUE;
}
if((tok_end - tok_start) <= namelen) {
/* Match the last part of the name to the domain we are checking. */
const char *checkn = name + namelen - (tok_end - tok_start);
- if(strncasecompare(no_proxy + tok_start, checkn,
+ if(Curl_raw_nequal(no_proxy + tok_start, checkn,
tok_end - tok_start)) {
if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
/* We either have an exact match, or the previous character is a .
{
char *proxy = NULL;
+#ifndef CURL_DISABLE_HTTP
/* If proxy was not specified, we check for default proxy environment
* variables, to enable i.e Lynx compliance:
*
* For compatibility, the all-uppercase versions of these variables are
* checked if the lowercase versions don't exist.
*/
+ char *no_proxy=NULL;
char proxy_env[128];
- const char *protop = conn->handler->scheme;
- char *envp = proxy_env;
- char *prox;
- /* Now, build <protocol>_proxy and check for such a one to use */
- while(*protop)
- *envp++ = (char)tolower((int)*protop++);
+ no_proxy=curl_getenv("no_proxy");
+ if(!no_proxy)
+ no_proxy=curl_getenv("NO_PROXY");
+
+ if(!check_noproxy(conn->host.name, no_proxy)) {
+ /* It was not listed as without proxy */
+ const char *protop = conn->handler->scheme;
+ char *envp = proxy_env;
+ char *prox;
- /* append _proxy */
- strcpy(envp, "_proxy");
+ /* Now, build <protocol>_proxy and check for such a one to use */
+ while(*protop)
+ *envp++ = (char)tolower((int)*protop++);
- /* read the protocol proxy: */
- prox=curl_getenv(proxy_env);
+ /* append _proxy */
+ strcpy(envp, "_proxy");
- /*
- * We don't try the uppercase version of HTTP_PROXY because of
- * security reasons:
- *
- * When curl is used in a webserver application
- * environment (cgi or php), this environment variable can
- * be controlled by the web server user by setting the
- * http header 'Proxy:' to some value.
- *
- * This can cause 'internal' http/ftp requests to be
- * arbitrarily redirected by any external attacker.
- */
- 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));
+ /* read the protocol proxy: */
prox=curl_getenv(proxy_env);
- }
- if(prox)
- proxy = prox; /* use this */
- else {
- proxy = curl_getenv("all_proxy"); /* default proxy to use */
- if(!proxy)
- proxy=curl_getenv("ALL_PROXY");
- }
+ /*
+ * We don't try the uppercase version of HTTP_PROXY because of
+ * security reasons:
+ *
+ * When curl is used in a webserver application
+ * environment (cgi or php), this environment variable can
+ * be controlled by the web server user by setting the
+ * http header 'Proxy:' to some value.
+ *
+ * This can cause 'internal' http/ftp requests to be
+ * arbitrarily redirected by any external attacker.
+ */
+ if(!prox && !Curl_raw_equal("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);
+ }
+
+ if(prox)
+ proxy = prox; /* use this */
+ else {
+ proxy = curl_getenv("all_proxy"); /* default proxy to use */
+ if(!proxy)
+ proxy=curl_getenv("ALL_PROXY");
+ }
+ } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
+ non-proxy */
+ free(no_proxy);
+
+#else /* !CURL_DISABLE_HTTP */
+
+ (void)conn;
+#endif /* CURL_DISABLE_HTTP */
return proxy;
}
* that may exist registered to the same proxy host.
*/
static CURLcode parse_proxy(struct Curl_easy *data,
- struct connectdata *conn, char *proxy,
- curl_proxytype proxytype)
+ struct connectdata *conn, char *proxy)
{
char *prox_portno;
char *endofprot;
char *proxyptr;
char *portptr;
char *atsign;
- long port = -1;
- char *proxyuser = NULL;
- char *proxypasswd = NULL;
- bool sockstype;
/* We do the proxy host string parsing here. We want the host name and the
* port name. Accept a protocol:// prefix
endofprot = strstr(proxy, "://");
if(endofprot) {
proxyptr = endofprot+3;
- if(checkprefix("https", proxy))
- proxytype = CURLPROXY_HTTPS;
- else if(checkprefix("socks5h", proxy))
- proxytype = CURLPROXY_SOCKS5_HOSTNAME;
+ if(checkprefix("socks5h", proxy))
+ conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
else if(checkprefix("socks5", proxy))
- proxytype = CURLPROXY_SOCKS5;
+ conn->proxytype = CURLPROXY_SOCKS5;
else if(checkprefix("socks4a", proxy))
- proxytype = CURLPROXY_SOCKS4A;
+ conn->proxytype = CURLPROXY_SOCKS4A;
else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
- proxytype = CURLPROXY_SOCKS4;
+ conn->proxytype = CURLPROXY_SOCKS4;
else if(checkprefix("http:", proxy))
; /* leave it as HTTP or HTTP/1.0 */
else {
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;
- }
-#endif
-
- sockstype = proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
- proxytype == CURLPROXY_SOCKS5 ||
- proxytype == CURLPROXY_SOCKS4A ||
- proxytype == CURLPROXY_SOCKS4;
-
/* Is there a username and password given in this proxy url? */
atsign = strchr(proxyptr, '@');
if(atsign) {
+ char *proxyuser = NULL;
+ char *proxypasswd = NULL;
CURLcode result =
parse_login_details(proxyptr, atsign - proxyptr,
- &proxyuser, &proxypasswd, NULL);
+ &proxyuser, &proxypasswd, NULL);
+ if(!result) {
+ /* found user and password, rip them out. note that we are
+ unescaping them, as there is otherwise no way to have a
+ username or password with reserved characters like ':' in
+ them. */
+ Curl_safefree(conn->proxyuser);
+ if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
+ conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
+ else
+ conn->proxyuser = strdup("");
+
+ if(!conn->proxyuser)
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ Curl_safefree(conn->proxypasswd);
+ if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
+ conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
+ else
+ conn->proxypasswd = strdup("");
+
+ if(!conn->proxypasswd)
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ if(!result) {
+ conn->bits.proxy_user_passwd = TRUE; /* enable it */
+ atsign++; /* the right side of the @-letter */
+
+ proxyptr = atsign; /* now use this instead */
+ }
+ }
+
+ free(proxyuser);
+ free(proxypasswd);
+
if(result)
return result;
- proxyptr = atsign + 1;
}
/* start scanning for port number at this point */
prox_portno = strchr(portptr, ':');
if(prox_portno) {
char *endp = NULL;
-
+ long port = 0;
*prox_portno = 0x0; /* cut off number from host name */
prox_portno ++;
/* now set the local port number */
if(data->set.proxyport)
/* None given in the proxy string, then get the default one if it is
given */
- port = data->set.proxyport;
- else {
- if(proxytype == CURLPROXY_HTTPS)
- port = CURL_DEFAULT_HTTPS_PROXY_PORT;
- else
- port = CURL_DEFAULT_PROXY_PORT;
- }
+ conn->port = data->set.proxyport;
}
- if(*proxyptr) {
- struct proxy_info *proxyinfo =
- sockstype ? &conn->socks_proxy : &conn->http_proxy;
- proxyinfo->proxytype = proxytype;
-
- if(proxyuser) {
- /* found user and password, rip them out. note that we are unescaping
- them, as there is otherwise no way to have a username or password
- with reserved characters like ':' in them. */
- Curl_safefree(proxyinfo->user);
- proxyinfo->user = curl_easy_unescape(data, proxyuser, 0, NULL);
-
- if(!proxyinfo->user)
- return CURLE_OUT_OF_MEMORY;
-
- Curl_safefree(proxyinfo->passwd);
- if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
- proxyinfo->passwd = curl_easy_unescape(data, proxypasswd, 0, NULL);
- else
- proxyinfo->passwd = strdup("");
-
- if(!proxyinfo->passwd)
- return CURLE_OUT_OF_MEMORY;
+ /* now, clone the cleaned proxy host name */
+ conn->proxy.rawalloc = strdup(proxyptr);
+ conn->proxy.name = conn->proxy.rawalloc;
- conn->bits.proxy_user_passwd = TRUE; /* enable it */
- }
-
- if(port >= 0) {
- proxyinfo->port = port;
- if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
- conn->port = port;
- }
-
- /* now, clone the cleaned proxy host name */
- Curl_safefree(proxyinfo->host.rawalloc);
- proxyinfo->host.rawalloc = strdup(proxyptr);
- proxyinfo->host.name = proxyinfo->host.rawalloc;
-
- if(!proxyinfo->host.rawalloc)
- return CURLE_OUT_OF_MEMORY;
- }
-
- Curl_safefree(proxyuser);
- Curl_safefree(proxypasswd);
+ if(!conn->proxy.rawalloc)
+ return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
{
char proxyuser[MAX_CURL_USER_LENGTH]="";
char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
- CURLcode result;
if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
}
- result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
- FALSE);
- if(!result)
- result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
- NULL, FALSE);
- return result;
+ conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
+ if(!conn->proxyuser)
+ return CURLE_OUT_OF_MEMORY;
+
+ conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
+ if(!conn->proxypasswd)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
}
#endif /* CURL_DISABLE_PROXY */
DEBUGASSERT(!**user);
DEBUGASSERT(!**passwd);
DEBUGASSERT(!**options);
- DEBUGASSERT(conn->handler);
if(!ptr)
goto out;
if(data->set.use_netrc == CURL_NETRC_REQUIRED)
goto out;
- /* We could use the login information in the URL so extract it. Only parse
- options if the handler says we should. */
+ /* We could use the login information in the URL so extract it */
result = parse_login_details(login, ptr - login - 1,
- &userp, &passwdp,
- (conn->handler->flags & PROTOPT_URLOPTIONS)?
- &optionsp:NULL);
+ &userp, &passwdp, &optionsp);
if(result)
goto out;
conn->bits.user_passwd = TRUE; /* enable user+password */
/* Decode the user */
- result = Curl_urldecode(data, userp, 0, &newname, NULL, FALSE);
- if(result) {
+ newname = curl_easy_unescape(data, userp, 0, NULL);
+ if(!newname) {
+ result = CURLE_OUT_OF_MEMORY;
goto out;
}
if(passwdp) {
/* We have a password in the URL so decode it */
- char *newpasswd;
- result = Curl_urldecode(data, passwdp, 0, &newpasswd, NULL, FALSE);
- if(result) {
+ char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
+ if(!newpasswd) {
+ result = CURLE_OUT_OF_MEMORY;
goto out;
}
if(optionsp) {
/* We have an options list in the URL so decode it */
- char *newoptions;
- result = Curl_urldecode(data, optionsp, 0, &newoptions, NULL, FALSE);
- if(result) {
+ char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
+ if(!newoptions) {
+ result = CURLE_OUT_OF_MEMORY;
goto out;
}
*portptr = '\0'; /* cut off the name there */
conn->remote_port = curlx_ultous(port);
}
- else {
- if(rest[0]) {
- failf(data, "Illegal port number");
- return CURLE_URL_MALFORMAT;
- }
+ else
/* Browser behavior adaptation. If there's a colon with no digits after,
just cut off the name there which makes us ignore the colon and just
use the default port. Firefox and Chrome both do that. */
*portptr = '\0';
- }
}
/* only if remote_port was not already parsed off the URL we use the
char *portptr;
int port = -1;
-#if defined(CURL_DISABLE_VERBOSE_STRINGS)
- (void) data;
-#endif
-
*hostname_result = NULL;
*port_result = -1;
int host_match = FALSE;
int port_match = FALSE;
- *host_result = NULL;
- *port_result = -1;
-
if(*ptr == ':') {
/* an empty hostname always matches */
host_match = TRUE;
if(!hostname_to_match)
return CURLE_OUT_OF_MEMORY;
hostname_to_match_len = strlen(hostname_to_match);
- host_match = strncasecompare(ptr, hostname_to_match,
- hostname_to_match_len);
+ host_match = curl_strnequal(ptr, hostname_to_match, hostname_to_match_len);
free(hostname_to_match);
ptr += hostname_to_match_len;
{
CURLcode result = CURLE_OK;
char *host = NULL;
- int port = -1;
+ int port = 0;
- while(conn_to_host && !host && port == -1) {
+ while(conn_to_host && !host) {
result = parse_connect_to_string(data, conn, conn_to_host->data,
&host, &port);
if(result)
return result;
if(host && *host) {
+ bool ipv6host;
conn->conn_to_host.rawalloc = host;
conn->conn_to_host.name = host;
conn->bits.conn_to_host = TRUE;
- infof(data, "Connecting to hostname: %s\n", host);
+ ipv6host = strchr(host, ':') != NULL;
+ infof(data, "Connecting to hostname: %s%s%s\n",
+ ipv6host ? "[" : "", host, ipv6host ? "]" : "");
}
else {
/* no "connect to host" */
conn->bits.conn_to_host = FALSE;
- Curl_safefree(host);
+ free(host);
}
if(port >= 0) {
else {
/* no "connect to port" */
conn->bits.conn_to_port = FALSE;
- port = -1;
}
conn_to_host = conn_to_host->next;
bool *async)
{
CURLcode result=CURLE_OK;
- time_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ long timeout_ms = Curl_timeleft(data, NULL, TRUE);
/*************************************************************
* Resolve the name of the server or proxy
struct Curl_dns_entry *hostaddr;
#ifdef USE_UNIX_SOCKETS
- if(conn->unix_domain_socket) {
+ if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
/* Unix domain sockets are local. The host gets ignored, just use the
* specified domain socket address. Do not cache "DNS entries". There is
* no DNS involved and we already have the filesystem path available */
- const char *path = conn->unix_domain_socket;
+ const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
if(!hostaddr)
result = CURLE_OUT_OF_MEMORY;
+ else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
+ hostaddr->inuse++;
else {
- bool longpath = FALSE;
- hostaddr->addr = Curl_unix2addr(path, &longpath,
- conn->abstract_unix_socket);
- if(hostaddr->addr)
- hostaddr->inuse++;
- else {
- /* Long paths are not supported for now */
- if(longpath) {
- failf(data, "Unix socket path too long: '%s'", path);
- result = CURLE_COULDNT_RESOLVE_HOST;
- }
- else
- result = CURLE_OUT_OF_MEMORY;
- free(hostaddr);
- hostaddr = NULL;
+ /* Long paths are not supported for now */
+ if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
+ failf(data, "Unix socket path too long: '%s'", path);
+ result = CURLE_COULDNT_RESOLVE_HOST;
}
+ else
+ result = CURLE_OUT_OF_MEMORY;
+ free(hostaddr);
+ hostaddr = NULL;
}
}
else
#endif
- if(!conn->bits.proxy) {
+ if(!conn->proxy.name || !*conn->proxy.name) {
struct hostname *connhost;
if(conn->bits.conn_to_host)
connhost = &conn->conn_to_host;
if(conn->bits.conn_to_port)
conn->port = conn->conn_to_port;
else
- conn->port = conn->remote_port;
+ conn->port = conn->remote_port; /* it is the same port */
/* Resolve target host right on */
rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port,
else {
/* This is a proxy that hasn't been resolved yet. */
- struct hostname * const host = conn->bits.socksproxy ?
- &conn->socks_proxy.host : &conn->http_proxy.host;
-
/* resolve proxy */
- rc = Curl_resolv_timeout(conn, host->name, (int)conn->port,
+ rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
&hostaddr, timeout_ms);
if(rc == CURLRESOLV_PENDING)
result = CURLE_OPERATION_TIMEDOUT;
else if(!hostaddr) {
- failf(data, "Couldn't resolve proxy '%s'", host->dispname);
+ failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
result = CURLE_COULDNT_RESOLVE_PROXY;
/* don't return yet, we need to clean up the timeout first */
}
static void reuse_conn(struct connectdata *old_conn,
struct connectdata *conn)
{
- free_fixed_hostname(&old_conn->http_proxy.host);
- free_fixed_hostname(&old_conn->socks_proxy.host);
-
- free(old_conn->http_proxy.host.rawalloc);
- free(old_conn->socks_proxy.host.rawalloc);
+ free_fixed_hostname(&old_conn->proxy);
+ free(old_conn->proxy.rawalloc);
/* free the SSL config struct from this connection struct as this was
allocated in vain and is targeted for destruction */
- Curl_free_primary_ssl_config(&old_conn->ssl_config);
- Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
+ Curl_free_ssl_config(&old_conn->ssl_config);
conn->data = old_conn->data;
conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
if(conn->bits.proxy_user_passwd) {
/* use the new proxy user name and proxy password though */
- Curl_safefree(conn->http_proxy.user);
- Curl_safefree(conn->socks_proxy.user);
- Curl_safefree(conn->http_proxy.passwd);
- Curl_safefree(conn->socks_proxy.passwd);
- conn->http_proxy.user = old_conn->http_proxy.user;
- conn->socks_proxy.user = old_conn->socks_proxy.user;
- conn->http_proxy.passwd = old_conn->http_proxy.passwd;
- conn->socks_proxy.passwd = old_conn->socks_proxy.passwd;
- old_conn->http_proxy.user = NULL;
- old_conn->socks_proxy.user = NULL;
- old_conn->http_proxy.passwd = NULL;
- old_conn->socks_proxy.passwd = NULL;
+ Curl_safefree(conn->proxyuser);
+ Curl_safefree(conn->proxypasswd);
+ conn->proxyuser = old_conn->proxyuser;
+ conn->proxypasswd = old_conn->proxypasswd;
+ old_conn->proxyuser = NULL;
+ old_conn->proxypasswd = NULL;
}
/* host can change, when doing keepalive with a proxy or if the case is
Curl_safefree(old_conn->user);
Curl_safefree(old_conn->passwd);
- Curl_safefree(old_conn->http_proxy.user);
- Curl_safefree(old_conn->socks_proxy.user);
- Curl_safefree(old_conn->http_proxy.passwd);
- Curl_safefree(old_conn->socks_proxy.passwd);
+ Curl_safefree(old_conn->proxyuser);
+ Curl_safefree(old_conn->proxypasswd);
Curl_safefree(old_conn->localdev);
Curl_llist_destroy(old_conn->send_pipe, NULL);
old_conn->recv_pipe = NULL;
Curl_safefree(old_conn->master_buffer);
-
-#ifdef USE_UNIX_SOCKETS
- Curl_safefree(old_conn->unix_domain_socket);
-#endif
}
/**
char *options = NULL;
bool reuse;
char *proxy = NULL;
- char *socksproxy = NULL;
- char *no_proxy = NULL;
bool prot_missing = FALSE;
bool connections_available = TRUE;
bool force_reuse = FALSE;
}
}
- if(data->set.str[STRING_PRE_PROXY]) {
- socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
- /* if global socks proxy is set, this is it */
- if(NULL == socksproxy) {
- failf(data, "memory shortage");
- result = CURLE_OUT_OF_MEMORY;
- goto out;
- }
- }
-
- 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))) {
- Curl_safefree(proxy);
- Curl_safefree(socksproxy);
+ if(data->set.str[STRING_NOPROXY] &&
+ check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
+ free(proxy); /* proxy is in exception list */
+ proxy = NULL;
}
- else if(!proxy && !socksproxy)
-#ifndef CURL_DISABLE_HTTP
- /* if the host is not in the noproxy list, detect proxy. */
+ else if(!proxy)
proxy = detect_proxy(conn);
-#else /* !CURL_DISABLE_HTTP */
- proxy = NULL;
-#endif /* CURL_DISABLE_HTTP */
-
- Curl_safefree(no_proxy);
#ifdef USE_UNIX_SOCKETS
- if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
- if(proxy) {
- free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
- proxy = NULL;
- }
- conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
- if(conn->unix_domain_socket == NULL) {
- result = CURLE_OUT_OF_MEMORY;
- goto out;
- }
- conn->abstract_unix_socket = data->set.abstract_unix_socket;
+ if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
+ free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
+ proxy = NULL;
}
#endif
protocol doesn't work with network */
proxy = NULL;
}
- if(socksproxy && (!*socksproxy ||
- (conn->handler->flags & PROTOPT_NONETWORK))) {
- free(socksproxy); /* Don't bother with an empty socks proxy string or if
- the protocol doesn't work with network */
- socksproxy = NULL;
- }
/***********************************************************************
* If this is supposed to use a proxy, we need to figure out the proxy host
* name, proxy type and port number, so that we can re-use an existing
* connection that may exist registered to the same proxy host.
***********************************************************************/
- if(proxy || socksproxy) {
- if(proxy) {
- result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
- Curl_safefree(proxy); /* parse_proxy copies the proxy string */
- if(result)
- goto out;
- }
+ if(proxy) {
+ result = parse_proxy(data, conn, proxy);
- if(socksproxy) {
- result = parse_proxy(data, conn, socksproxy,
- conn->socks_proxy.proxytype);
- /* parse_proxy copies the socks proxy string */
- Curl_safefree(socksproxy);
- if(result)
- goto out;
- }
+ free(proxy); /* parse_proxy copies the proxy string */
+ proxy = NULL;
- if(conn->http_proxy.host.rawalloc) {
+ if(result)
+ goto out;
+
+ if((conn->proxytype == CURLPROXY_HTTP) ||
+ (conn->proxytype == CURLPROXY_HTTP_1_0)) {
#ifdef CURL_DISABLE_HTTP
/* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
result = CURLE_UNSUPPORTED_PROTOCOL;
conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
}
-
- if(conn->socks_proxy.host.rawalloc) {
- if(!conn->http_proxy.host.rawalloc) {
- /* once a socks proxy */
- if(!conn->socks_proxy.user) {
- conn->socks_proxy.user = conn->http_proxy.user;
- conn->http_proxy.user = NULL;
- Curl_safefree(conn->socks_proxy.passwd);
- conn->socks_proxy.passwd = conn->http_proxy.passwd;
- conn->http_proxy.passwd = NULL;
- }
- }
- conn->bits.socksproxy = TRUE;
- }
- else
- conn->bits.socksproxy = FALSE; /* not a socks proxy */
+ conn->bits.proxy = TRUE;
}
else {
- conn->bits.socksproxy = FALSE;
- conn->bits.httpproxy = FALSE;
- }
- conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
-
- if(!conn->bits.proxy) {
/* we aren't using the proxy after all... */
conn->bits.proxy = FALSE;
conn->bits.httpproxy = FALSE;
- conn->bits.socksproxy = FALSE;
conn->bits.proxy_user_passwd = FALSE;
conn->bits.tunnel_proxy = FALSE;
}
/*************************************************************
* IDN-fix the hostnames
*************************************************************/
- fix_hostname(conn, &conn->host);
+ fix_hostname(data, conn, &conn->host);
if(conn->bits.conn_to_host)
- fix_hostname(conn, &conn->conn_to_host);
- if(conn->bits.httpproxy)
- fix_hostname(conn, &conn->http_proxy.host);
- if(conn->bits.socksproxy)
- fix_hostname(conn, &conn->socks_proxy.host);
+ fix_hostname(data, conn, &conn->conn_to_host);
+ if(conn->proxy.name && *conn->proxy.name)
+ fix_hostname(data, conn, &conn->proxy);
/*************************************************************
* Check whether the host and the "connect to host" are equal.
- * Do this after the hostnames have been IDN-fixed.
+ * Do this after the hostnames have been IDN-fixed .
*************************************************************/
if(conn->bits.conn_to_host &&
- strcasecompare(conn->conn_to_host.name, conn->host.name)) {
+ Curl_raw_equal(conn->conn_to_host.name, conn->host.name)) {
conn->bits.conn_to_host = FALSE;
}
that will be freed as part of the Curl_easy struct, but all cloned
copies will be separately allocated.
*/
- data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
- data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
- data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
- data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
- data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
- data->set.proxy_ssl.primary.random_file =
- data->set.str[STRING_SSL_RANDOM_FILE];
- data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
- data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
- data->set.ssl.primary.cipher_list =
- data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
- data->set.proxy_ssl.primary.cipher_list =
- data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
-
- data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
- data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
- data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
- data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
- data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
- data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
- data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
- data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
- data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
- data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
- data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
- data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
- data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
- data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
- data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
+ data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
+ data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
+ data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
+ data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
+ data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
+ data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+ data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
+ data->set.ssl.clientcert = data->set.str[STRING_CERT];
#ifdef USE_TLS_SRP
- data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
- data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
- data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
- data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
+ data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
+ data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
#endif
- if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
- &conn->ssl_config)) {
- result = CURLE_OUT_OF_MEMORY;
- goto out;
- }
-
- if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
- &conn->proxy_ssl_config)) {
+ if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
conn->connection_id,
conn->bits.proxy?"proxy":"host",
- conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
- conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
- conn->host.dispname);
+ conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
}
else {
/* We have decided that we want a new connection. However, we may not
free(options);
free(passwd);
free(user);
- free(socksproxy);
free(proxy);
return result;
}