[PATCH] SOCKS5 proxy support

heisenbug heisenbug at zoho.com
Sun Apr 6 09:47:44 CDT 2014


# HG changeset patch
# User Bug Heisen <heisenbug at zoho.com>
# Date 1396793762 -7200
#      Sun Apr 06 16:16:02 2014 +0200
# Node ID 3f58227755ed42a2c891fa5bc75c286c3d35791c
# Parent  12f161f08d744f0e4b6eef9c905670afb5c24dd4
socks proxy: socks5 proxy support for http(s) protocol

This patch adds support for a SOCKS5 proxy, using the 'socks'
module from the SocksiPy projects (needs to be installed separately).
Because it is the 'proxyhandler' function that is modified, it will
only work for HTTP/HTTPS protocols. For the SSH protocol, using a SOCKS
proxy can easily be done outside of Mercurial, by specifying the
'ProxyCommand' option.

The patch has the SOCKS5 version hardcoded in it, but the 'socks'
module should support other versions as well. So other SOCKS versions
are possible in the same way, but the code would require modification
to support them.

For testing purposes, it's good to know that SSH can create a SOCKS5
proxy using the `-D` command line flag. Using Tor also generates such
a proxy, typically either on port 9050 or 9150.

diff -r 12f161f08d74 -r 3f58227755ed mercurial/url.py
--- a/mercurial/url.py	Tue Apr 01 23:41:32 2014 -0700
+++ b/mercurial/url.py	Sun Apr 06 16:16:02 2014 +0200
@@ -63,6 +63,44 @@
 
 class proxyhandler(urllib2.ProxyHandler):
     def __init__(self, ui):
+
+        # First, check if a SOCKS5 proxy is set, using a line 'host = ...' in 
+        # the [socks_proxy] section of the config file.
+
+        proxyurl = ui.config("socks_proxy", "host")
+
+        if proxyurl:
+            idx = proxyurl.find(":")
+            if idx < 0:
+                raise util.Abort(_("host in socks_proxy should be "
+                                   "hostname:port"))
+
+            host = proxyurl[:idx]
+            portstr = proxyurl[idx+1:]
+            try:
+                port = int(portstr)
+            except ValueError:
+                raise util.Abort(_("Cannot interpret '%s' in the socks_proxy "
+                                   "host line as an integer port number") 
+                                   % portstr)
+
+            if port <= 0 or port > 65535:
+                raise util.Abort(_("Port number in socks_proxy host line "
+                                   "must lie between 1 and 65535, but is "
+                                   "%d") % port)
+
+            ui.note("Setting SOCKS5 proxy to %s:%d\n" % (host, port))
+                    
+            try:
+                import socks
+                socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, host, port)
+                socket.socket = socks.socksocket
+            except ImportError:
+                raise util.Abort(_("The SocksiPy socks module is needed for "
+                                   "SOCKS support"))
+
+        # Then check for a http/https proxy
+        
         proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
         # XXX proxyauthinfo = None
 



More information about the Mercurial-devel mailing list