diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in
index d4549046e7..3c48c772a8 100644
--- a/docs/drvesx.html.in
+++ b/docs/drvesx.html.in
@@ -116,7 +116,25 @@ type://[username@]hostname[:port]/[?extraparameters]
If set to 1, the driver answers all
questions with the default answer.
If set to 0, questions are reported as errors. The default
- value it 0.
+ value it 0. Since 0.7.5.
+
+
+
+
+ proxy
+ |
+
+ [type://]hostname[:port]
+ |
+
+ Allows to specify a proxy for HTTP and HTTPS communication.
+ Since 0.8.2.
+ The optional type part may be one of:
+ http , socks , socks4 ,
+ socks4a or socks5 . The default is
+ http and socks is synonymous for
+ socks5 . The optional port allows to
+ override the default port 1080.
|
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 0c12a3192b..c5cf2e8485 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -279,7 +279,7 @@ esxCapsInit(esxPrivate *priv)
/*
- * URI format: {esx|gsx}://[@][:]/[ ...]
+ * URI format: {esx|gsx}://[@][:]/[ ...]
*
* If no port is specified the default port is set dependent on the scheme and
* transport parameter:
@@ -293,6 +293,7 @@ esxCapsInit(esxPrivate *priv)
* - vcenter={|*}
* - no_verify={0|1}
* - auto_answer={0|1}
+ * - proxy=[{http|socks|socks4|socks4a|socks5}://][:]
*
* If no transport parameter is specified https is used.
*
@@ -308,6 +309,10 @@ esxCapsInit(esxPrivate *priv)
* If the auto_answer parameter is set to 1, the driver will respond to all
* virtual machine questions with the default answer, otherwise virtual machine
* questions will be reported as errors. The default value it 0.
+ *
+ * The proxy parameter allows to specify a proxy for to be used by libcurl.
+ * The default for the optional part is http and socks is synonymous for
+ * socks5. The optional part allows to override the default port 1080.
*/
static virDrvOpenStatus
esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
@@ -421,7 +426,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
if (esxVI_Context_Alloc(&priv->host) < 0 ||
esxVI_Context_Connect(priv->host, url, hostIpAddress, username,
- password, parsedQuery->noVerify) < 0) {
+ password, parsedQuery) < 0) {
goto cleanup;
}
@@ -554,8 +559,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
}
if (esxVI_Context_Connect(priv->vCenter, url, vCenterIpAddress,
- username, password,
- parsedQuery->noVerify) < 0) {
+ username, password, parsedQuery) < 0) {
goto cleanup;
}
@@ -590,7 +594,6 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
VIR_FREE(priv);
}
-
esxUtil_FreeParsedQuery(&parsedQuery);
VIR_FREE(url);
VIR_FREE(vCenter);
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index dba9bc3b8e..27c3a12e7b 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -49,6 +49,7 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri)
int i;
int noVerify;
int autoAnswer;
+ char *tmp;
if (parsedQuery == NULL || *parsedQuery != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
@@ -120,6 +121,61 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri)
}
(*parsedQuery)->autoAnswer = autoAnswer != 0;
+ } else if (STRCASEEQ(queryParam->name, "proxy")) {
+ /* Expected format: [://][:] */
+ (*parsedQuery)->proxy = true;
+ (*parsedQuery)->proxy_type = CURLPROXY_HTTP;
+ VIR_FREE((*parsedQuery)->proxy_hostname);
+ (*parsedQuery)->proxy_port = 1080;
+
+ if ((tmp = STRSKIP(queryParam->value, "http://")) != NULL) {
+ (*parsedQuery)->proxy_type = CURLPROXY_HTTP;
+ } else if ((tmp = STRSKIP(queryParam->value, "socks://")) != NULL ||
+ (tmp = STRSKIP(queryParam->value, "socks5://")) != NULL) {
+ (*parsedQuery)->proxy_type = CURLPROXY_SOCKS5;
+ } else if ((tmp = STRSKIP(queryParam->value, "socks4://")) != NULL) {
+ (*parsedQuery)->proxy_type = CURLPROXY_SOCKS4;
+ } else if ((tmp = STRSKIP(queryParam->value, "socks4a://")) != NULL) {
+ (*parsedQuery)->proxy_type = CURLPROXY_SOCKS4A;
+ } else if ((tmp = strstr(queryParam->value, "://")) != NULL) {
+ *tmp = '\0';
+
+ ESX_ERROR(VIR_ERR_INVALID_ARG,
+ _("Query parameter 'proxy' contains unexpected "
+ "type '%s' (should be (http|socks(|4|4a|5))"),
+ queryParam->value);
+ goto cleanup;
+ } else {
+ tmp = queryParam->value;
+ }
+
+ (*parsedQuery)->proxy_hostname = strdup(tmp);
+
+ if ((*parsedQuery)->proxy_hostname == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if ((tmp = strchr((*parsedQuery)->proxy_hostname, ':')) != NULL) {
+ if (tmp == (*parsedQuery)->proxy_hostname) {
+ ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
+ _("Query parameter 'proxy' doesn't contain a "
+ "hostname"));
+ goto cleanup;
+ }
+
+ *tmp++ = '\0';
+
+ if (virStrToLong_i(tmp, NULL, 10,
+ &(*parsedQuery)->proxy_port) < 0 ||
+ (*parsedQuery)->proxy_port < 1 ||
+ (*parsedQuery)->proxy_port > 65535) {
+ ESX_ERROR(VIR_ERR_INVALID_ARG,
+ _("Query parameter 'proxy' has unexpected port"
+ "value '%s' (should be [1..65535])"), tmp);
+ goto cleanup;
+ }
+ }
} else {
VIR_WARN("Ignoring unexpected query parameter '%s'",
queryParam->name);
@@ -161,6 +217,7 @@ esxUtil_FreeParsedQuery(esxUtil_ParsedQuery **parsedQuery)
VIR_FREE((*parsedQuery)->transport);
VIR_FREE((*parsedQuery)->vCenter);
+ VIR_FREE((*parsedQuery)->proxy_hostname);
VIR_FREE(*parsedQuery);
}
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index ae6e38bdbd..26c456d802 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -36,6 +36,10 @@ struct _esxUtil_ParsedQuery {
char *vCenter;
bool noVerify;
bool autoAnswer;
+ bool proxy;
+ int proxy_type;
+ char *proxy_hostname;
+ int proxy_port;
};
int esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri);
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 4332f2b9c0..8c43d67a88 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -277,7 +277,7 @@ esxVI_CURL_Perform(esxVI_Context *ctx, const char *url)
int
esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
const char *ipAddress, const char *username,
- const char *password, bool noVerify)
+ const char *password, esxUtil_ParsedQuery *parsedQuery)
{
int result = -1;
esxVI_String *propertyNameList = NULL;
@@ -328,8 +328,10 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
curl_easy_setopt(ctx->curl_handle, CURLOPT_USERAGENT, "libvirt-esx");
curl_easy_setopt(ctx->curl_handle, CURLOPT_HEADER, 0);
curl_easy_setopt(ctx->curl_handle, CURLOPT_FOLLOWLOCATION, 0);
- curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYPEER, noVerify ? 0 : 1);
- curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYHOST, noVerify ? 0 : 2);
+ curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYPEER,
+ parsedQuery->noVerify ? 0 : 1);
+ curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYHOST,
+ parsedQuery->noVerify ? 0 : 2);
curl_easy_setopt(ctx->curl_handle, CURLOPT_COOKIEFILE, "");
curl_easy_setopt(ctx->curl_handle, CURLOPT_HTTPHEADER, ctx->curl_headers);
curl_easy_setopt(ctx->curl_handle, CURLOPT_READFUNCTION,
@@ -343,6 +345,15 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
curl_easy_setopt(ctx->curl_handle, CURLOPT_VERBOSE, 1);
#endif
+ if (parsedQuery->proxy) {
+ curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXY,
+ parsedQuery->proxy_hostname);
+ curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXYTYPE,
+ parsedQuery->proxy_type);
+ curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXYPORT,
+ parsedQuery->proxy_port);
+ }
+
if (virMutexInit(&ctx->curl_lock) < 0) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not initialize CURL mutex"));
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 521be0cfcc..f5e89e9ec8 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -31,6 +31,7 @@
# include "virterror_internal.h"
# include "datatypes.h"
# include "esx_vi_types.h"
+# include "esx_util.h"
@@ -161,7 +162,8 @@ int esxVI_Context_Alloc(esxVI_Context **ctx);
void esxVI_Context_Free(esxVI_Context **ctx);
int esxVI_Context_Connect(esxVI_Context *ctx, const char *ipAddress,
const char *url, const char *username,
- const char *password, bool noVerify);
+ const char *password,
+ esxUtil_ParsedQuery *parsedQuery);
int esxVI_Context_DownloadFile(esxVI_Context *ctx, const char *url,
char **content);
int esxVI_Context_UploadFile(esxVI_Context *ctx, const char *url,