diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 59ae0a8..ce8bb64 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -34,6 +34,7 @@ libcore_a_SOURCES = \
 	nicklist.c \
 	nickmatch-cache.c \
 	pidwait.c \
+	proxy.c \
 	queries.c \
 	rawlog.c \
 	recode.c \
@@ -83,6 +84,7 @@ pkginc_core_HEADERS = \
 	nicklist.h \
 	nickmatch-cache.h \
 	pidwait.h \
+	proxy.h \
 	queries.h \
 	rawlog.h \
 	recode.h \
diff --git a/src/core/core.c b/src/core/core.c
index b9debbb..d4d2000 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -40,6 +40,7 @@
 #include "rawlog.h"
 #include "ignore.h"
 #include "recode.h"
+#include "proxy.h"
 
 #include "channels.h"
 #include "queries.h"
@@ -238,6 +239,7 @@ void core_init(void)
 	chatnets_init();
         expandos_init();
 	ignore_init();
+	proxy_init();
 	servers_init();
         write_buffer_init();
 	log_init();
@@ -285,6 +287,7 @@ void core_deinit(void)
 	log_deinit();
         write_buffer_deinit();
 	servers_deinit();
+	proxy_deinit();
 	ignore_deinit();
         expandos_deinit();
 	chatnets_deinit();
diff --git a/src/core/proxy.c b/src/core/proxy.c
new file mode 100644
index 0000000..974585d
--- /dev/null
+++ b/src/core/proxy.c
@@ -0,0 +1,108 @@
+/*
+ proxy.c : network proxy support
+
+    Copyright (C) 2010 Jochen Eisinger
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "module.h"
+#include "proxy.h"
+
+#include "network.h"
+#include "net-sendbuffer.h"
+#include "servers.h"
+#include "signals.h"
+
+static void proxy_server_connected(SERVER_REC *server)
+{
+	server->connect_time = time(NULL);
+	servers = g_slist_append(servers, server);
+	signal_emit("server connected", 1, server);
+}
+
+static void proxy_connect_http_init(SERVER_REC *server, GIOChannel *handle)
+{
+	const char response[] = "HTTP/1.0 200 ";
+	char *str;
+	int error;
+	int ret;
+
+	g_return_if_fail(IS_SERVER(server));
+
+	error = net_geterror(handle);
+	if (error != 0) {
+		server->connection_lost = TRUE;
+		server_connect_failed(server, g_strerror(error));
+		return;
+	}
+
+	if ((ret = net_sendbuffer_receive_line(server->handle, &str, TRUE)) > 0) {
+		if (!strncmp(str, response, strlen(response))) {
+			g_source_remove(server->connect_tag);
+			server->connect_tag = -1;
+			proxy_server_connected(server);
+			return;
+		}
+	}
+
+	if (ret == 0)
+		return;
+
+	server->connection_lost = TRUE;
+	server_connect_failed(server, str);
+}
+
+static void proxy_connect_http(SERVER_REC *server)
+{
+	char *connect_str;
+
+	connect_str = g_strdup_printf("CONNECT %s:%d HTTP/1.0\n\n",
+            server->connrec->proxy != NULL ? server->connrec->proxy : server->connrec->address,
+            server->connrec->proxy != NULL ? server->connrec->proxy_port : server->connrec->port);
+	if (!connect_str || net_sendbuffer_send(server->handle, connect_str, strlen(connect_str))) {
+		server->connection_lost = TRUE;
+		server_connect_failed(server, "HTTP Proxy connect failed");
+		return;
+	}
+	g_free(connect_str);
+
+	server->connect_tag = g_input_add(net_sendbuffer_handle(server->handle),
+                                          G_INPUT_WRITE | G_INPUT_READ,
+					  (GInputFunction)
+					  proxy_connect_http_init,
+					  server);
+}
+
+static void sig_server_proxy_connect(SERVER_REC *server)
+{
+	if (!server->connrec->network_proxy)
+		proxy_server_connected(server);
+
+	if (server->connrec->network_proxy_type && !strcmp(server->connrec->network_proxy_type, "HTTP"))
+		proxy_connect_http(server);
+	else
+		proxy_server_connected(server);
+}
+
+void proxy_init(void)
+{
+	signal_add_last("server proxy connect", sig_server_proxy_connect);
+}
+
+void proxy_deinit(void)
+{
+	signal_remove("server proxy connect", sig_server_proxy_connect);
+}
diff --git a/src/core/proxy.h b/src/core/proxy.h
new file mode 100644
index 0000000..da08a77
--- /dev/null
+++ b/src/core/proxy.h
@@ -0,0 +1,7 @@
+#ifndef __PROXY_H
+#define __PROXY_H
+
+void proxy_init(void);
+void proxy_deinit(void);
+
+#endif
diff --git a/src/core/server-connect-rec.h b/src/core/server-connect-rec.h
index cfbe3eb..8443cb2 100644
--- a/src/core/server-connect-rec.h
+++ b/src/core/server-connect-rec.h
@@ -10,6 +10,11 @@ char *proxy;
 int proxy_port;
 char *proxy_string, *proxy_string_after, *proxy_password;
 
+/* if we're using a network proxy to connect, or just NULLs */
+char *network_proxy;
+int network_proxy_port;
+char *network_proxy_type;
+
 unsigned short family; /* 0 = don't care, AF_INET or AF_INET6 */
 char *tag; /* try to keep this tag when connected to server */
 char *address;
diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c
index c8a7262..d16afd2 100644
--- a/src/core/servers-reconnect.c
+++ b/src/core/servers-reconnect.c
@@ -162,6 +162,9 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
 	dest->proxy_string = g_strdup(src->proxy_string);
 	dest->proxy_string_after = g_strdup(src->proxy_string_after);
 	dest->proxy_password = g_strdup(src->proxy_password);
+	dest->network_proxy = g_strdup(src->network_proxy);
+	dest->network_proxy_port = src->network_proxy_port;
+	dest->network_proxy_type = g_strdup(src->network_proxy_type);
 
 	dest->tag = g_strdup(src->tag);
 
diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c
index 83b90db..28c58ff 100644
--- a/src/core/servers-setup.c
+++ b/src/core/servers-setup.c
@@ -135,6 +135,12 @@ static void server_setup_fill(SERVER_CONNECT_REC *conn,
 		conn->proxy_password = g_strdup(settings_get_str("proxy_password"));
 	}
 
+	if (settings_get_bool("use_network_proxy")) {
+		conn->network_proxy = g_strdup(settings_get_str("network_proxy_address"));
+		conn->network_proxy_port = settings_get_int("network_proxy_port");
+		conn->network_proxy_type = g_strdup(settings_get_str("network_proxy_type"));
+	}
+
 	/* source IP */
 	if (source_host_ip4 != NULL) {
 		conn->own_ip4 = g_new(IPADDR, 1);
@@ -542,6 +548,11 @@ void servers_setup_init(void)
 	settings_add_str("proxy", "proxy_string_after", "");
 	settings_add_str("proxy", "proxy_password", "");
 
+	settings_add_bool("network_proxy", "use_network_proxy", FALSE);
+	settings_add_str("network_proxy", "network_proxy_address", "");
+	settings_add_int("network_proxy", "network_proxy_port", 8080);
+	settings_add_str("network_proxy", "network_proxy_type", "HTTP");
+
         setupservers = NULL;
 	source_host_ip4 = source_host_ip6 = NULL;
         old_source_host = NULL;
diff --git a/src/core/servers.c b/src/core/servers.c
index d4827b6..78a2faf 100644
--- a/src/core/servers.c
+++ b/src/core/servers.c
@@ -141,10 +141,7 @@ static char *server_create_tag(SERVER_CONNECT_REC *conn)
 /* Connection to server finished, fill the rest of the fields */
 void server_connect_finished(SERVER_REC *server)
 {
-	server->connect_time = time(NULL);
-
-	servers = g_slist_append(servers, server);
-	signal_emit("server connected", 1, server);
+	signal_emit("server proxy connect", 1, server);
 }
 
 static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle)
@@ -221,8 +218,12 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
 		own_ip = ip == NULL ? NULL :
 			(IPADDR_IS_V6(ip) ? server->connrec->own_ip6 :
 			 server->connrec->own_ip4);
-		port = server->connrec->proxy != NULL ?
-			server->connrec->proxy_port : server->connrec->port;
+                if (server->connrec->network_proxy != NULL)
+			port = server->connrec->network_proxy_port;
+		else if (server->connrec->proxy != NULL)
+			port = server->connrec->proxy_port;
+		else
+			port = server->connrec->port;
 		handle = server->connrec->use_ssl ?
 			net_connect_ip_ssl(ip, port, server->connrec->address, own_ip, server->connrec->ssl_cert, server->connrec->ssl_pkey,
 server->connrec->ssl_cafile, server->connrec->ssl_capath, server->connrec->ssl_verify) :
@@ -422,8 +423,12 @@ int server_start_connect(SERVER_REC *server)
 		server->connect_pipe[0] = g_io_channel_new(fd[0]);
 		server->connect_pipe[1] = g_io_channel_new(fd[1]);
 
-		connect_address = server->connrec->proxy != NULL ?
-			server->connrec->proxy : server->connrec->address;
+                if (server->connrec->network_proxy != NULL)
+			connect_address = server->connrec->network_proxy;
+		else if (server->connrec->proxy != NULL)
+			connect_address = server->connrec->proxy;
+		else
+			connect_address = server->connrec->address;
 		server->connect_pid =
 			net_gethostbyname_nonblock(connect_address,
 						   server->connect_pipe[1],
@@ -623,6 +628,9 @@ void server_connect_unref(SERVER_CONNECT_REC *conn)
 	g_free_not_null(conn->proxy_string_after);
 	g_free_not_null(conn->proxy_password);
 
+	g_free_not_null(conn->network_proxy);
+	g_free_not_null(conn->network_proxy_type);
+
 	g_free_not_null(conn->tag);
 	g_free_not_null(conn->address);
 	g_free_not_null(conn->chatnet);

