[libvirt] [PATCH] esx: Add proxy query parameter

Matthias Bolte matthias.bolte at googlemail.com
Fri Jun 4 00:06:27 UTC 2010


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




More information about the libvir-list mailing list