winetest: add support for http_proxy environment variable

Németh Márton nm127 at freemail.hu
Sun Jan 14 08:13:18 CST 2007


Hi,

the http_proxy environment variable contains the HTTP proxy to use 
instead of direct TCP connection to the host. The patch gets the 
http_proxy variable and use it if set.

         NMarci
-------------- next part --------------
diff -u -r wine-0.9.29.orig/ChangeLog wine-0.9.29/ChangeLog
--- wine-0.9.29.orig/ChangeLog	2007-01-09 16:42:47.000000000 +0100
+++ wine-0.9.29/ChangeLog	2007-01-14 15:02:31.000000000 +0100
@@ -1,3 +1,8 @@
+2007-01-14  Márton Németh <nm127 at freemail.hu>
+
+	* programs/winetest/send.c:
+	Added support for http_proxy envrironment variable parsing.
+
 2007-01-09  Alexandre Julliard <julliard at winehq.org>
 
 	* LICENSE, include/wine/wine_common_ver.rc:
diff -u -r wine-0.9.29.orig/programs/winetest/send.c wine-0.9.29/programs/winetest/send.c
--- wine-0.9.29.orig/programs/winetest/send.c	2007-01-09 16:42:47.000000000 +0100
+++ wine-0.9.29/programs/winetest/send.c	2007-01-14 14:35:20.000000000 +0100
@@ -20,31 +20,124 @@
 
 #include <winsock.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <regex.h>
 
 #include "winetest.h"
 
+/**
+ * get_http_proxy()
+ *
+ * Gets the proxy configuration from the http_proxy environment variable.
+ * - If the http_proxy is not found, the the *communication_server is set
+ *   to server. The *port is untouched.
+ * - If the http_proxy found and the syntax is recognised, then a new
+ *   buffer is malloc()ed for *communication_server, and the value will
+ *   be the proxy server name. The *port is set to the proxy port if
+ *   specified, otherwise defaults to 80.
+ *
+ * @param server: input, the real server we want connect to
+ * @param communication_server: output, the name of the host to connect
+ *   (proxy server, if found, otherwise server)
+ * @param port: output if proxy used: the TCP port to connect.
+ *
+ * returns: 1, if proxy found
+ *          0, if direct connection is needed
+ */
+static int
+get_http_proxy(const char* server, char** communication_server, unsigned int* port)
+{
+	char* http_proxy;
+	int retval;
+	regex_t regex;
+	regmatch_t pmatch[4];
+	int length;
+
+	char* proxy_server;
+	int proxy_used = 0;
+
+	*communication_server = (char*)server;
+
+	http_proxy = getenv("http_proxy");
+	if (http_proxy) {
+		/* Proxy configuration found */
+		memset(&regex, 0, sizeof(regex));
+		retval = regcomp(&regex, "^http://([^:]+)(:([0123456789]+))?$", REG_EXTENDED);
+		if (retval != 0) {
+			/* Error compiling regular expression. */
+			proxy_used = 0;
+		} else {
+			retval = regexec(&regex, http_proxy, 4, pmatch, 0);
+			if (retval != 0) {
+				/* Regular expression not matched. */
+				proxy_used = 0;
+			} else {
+				/* Match: pmatch[1]: proxy server name,   */ 
+				/*        pmatch[3] proxy port, if exists */
+
+				length = pmatch[1].rm_eo-pmatch[1].rm_so;
+				proxy_server = malloc(length+1);
+				memset(proxy_server, 0, length+1);
+				strncpy(proxy_server, &http_proxy[pmatch[1].rm_so], length);
+				*communication_server = proxy_server;
+
+				if (pmatch[3].rm_so != -1) {
+					*port = atoi(&http_proxy[pmatch[3].rm_so]);
+				} else {
+					*port = 80;
+				}
+			}
+			regfree(&regex);
+			proxy_used = 1;
+		}
+	} else {
+		/* No proxy configured. */
+		proxy_used = 0;
+	}
+
+	return proxy_used;
+}
+
+
 static SOCKET
 open_http (const char *server)
 {
     WSADATA wsad;
     struct sockaddr_in sa;
     SOCKET s;
-
-    report (R_STATUS, "Opening HTTP connection to %s", server);
+    unsigned int port = 80;
+    char* communication_server = NULL;
+    int proxy_used = 0;
+
+    proxy_used = get_http_proxy(server, &communication_server, &port);
+
+    if (!proxy_used) {
+        report (R_STATUS, "Opening HTTP connection to %s:%u", communication_server, port);
+    } else {
+        report (R_STATUS, "Opening HTTP connection to %s trough proxy server %s:%u", server, communication_server, port);
+    }
     if (WSAStartup (MAKEWORD (2,2), &wsad)) return INVALID_SOCKET;
 
     sa.sin_family = AF_INET;
-    sa.sin_port = htons (80);
-    sa.sin_addr.s_addr = inet_addr (server);
+    sa.sin_port = htons (port);
+    sa.sin_addr.s_addr = inet_addr (communication_server);
     if (sa.sin_addr.s_addr == INADDR_NONE) {
-        struct hostent *host = gethostbyname (server);
+        struct hostent *host = gethostbyname (communication_server);
         if (!host) {
-            report (R_ERROR, "Hostname lookup failed for %s", server);
+            report (R_ERROR, "Hostname lookup failed for %s", communication_server);
+            if (proxy_used) {
+                free(communication_server);
+            }
             goto failure;
         }
         sa.sin_addr.s_addr = ((struct in_addr *)host->h_addr)->s_addr;
     }
+    if (proxy_used) {
+        free(communication_server);
+    }
     s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (s == INVALID_SOCKET) {
         report (R_ERROR, "Can't open network socket: %d",
@@ -114,7 +207,7 @@
 
     /* RFC 2616 */
 #define SEP "--8<--cut-here--8<--"
-    static const char head[] = "POST /submit HTTP/1.0\r\n"
+    static const char head[] = "POST http://test.winehq.org/submit HTTP/1.1\r\n"
         "Host: test.winehq.org\r\n"
         "User-Agent: Winetest Shell\r\n"
         "Content-Type: multipart/form-data; boundary=\"" SEP "\"\r\n"


More information about the wine-patches mailing list