Allow to specify a proxy to be used by libcurl.
---
docs/drvesx.html.in | 20 ++++++++++++++++-
src/esx/esx_driver.c | 12 +++++++---
src/esx/esx_util.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/esx/esx_util.h | 4 +++
src/esx/esx_vi.c | 17 ++++++++++++--
src/esx/esx_vi.h | 4 ++-
6 files changed, 105 insertions(+), 9 deletions(-)
diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in
index d454904..3c48c77 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
<a href="#questions">questions</a> with the default
answer.
If set to 0, questions are reported as errors. The default
- value it 0.
+ value it 0. <span class="since">Since
0.7.5</span>.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>proxy</code>
+ </td>
+ <td>
+ <code>[type://]hostname[:port]</code>
+ </td>
+ <td>
+ Allows to specify a proxy for HTTP and HTTPS communication.
+ <span class="since">Since 0.8.2</span>.
+ The optional <code>type</code> part may be one of:
+ <code>http</code>, <code>socks</code>,
<code>socks4</code>,
+ <code>socks4a</code> or <code>socks5</code>. The
default is
+ <code>http</code> and <code>socks</code> is
synonymous for
+ <code>socks5</code>. The optional
<code>port</code> allows to
+ override the default port 1080.
</td>
</tr>
</table>
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 0c12a31..3854f85 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -279,7 +279,7 @@ esxCapsInit(esxPrivate *priv)
/*
- * URI format: {esx|gsx}://[<user>@]<server>[:<port>]/[<query
parameter> ...]
+ * URI format: {esx|gsx}://[<username>@]<hostname>[:<port>]/[<query
parameter> ...]
*
* 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={<vcenter>|*}
* - no_verify={0|1}
* - auto_answer={0|1}
+ * - proxy=[{http|socks|socks4|socks4a|socks5}://]<hostname>[:<port>]
*
* 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 <type> part is http and socks is synonymous for
+ * socks5. The optional <port> 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;
}
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index dba9bc3..27c3a12 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: [<type>://]<hostname>[:<port>] */
+ (*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 ae6e38b..26c456d 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 4332f2b..8c43d67 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 521be0c..f5e89e9 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,
--
1.7.0.4