summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/url.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/url.c')
-rw-r--r--Utilities/cmcurl/lib/url.c339
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);