https and proxies

Mads Kiilerich mads at kiilerich.com
Sun Dec 26 19:43:43 CST 2010


We have this outstanding issue with https certificate verification 
through proxies, especially with python 2.5 and backported ssl.

Henrik mentioned however that Python proxy support changed a lot early 
in the 2.6 series, and I have done some testing.

The following test works fine with python 2.7 (and I have tested with 
late 2.6.x before):

--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -187,3 +187,22 @@
    $ hg -R copy-pull pull --config web.cacerts=pub-expired.pem 
https://localhost:$HGPORT2/
    abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify 
failed (glob)
    [255]
+
+Prepare for connecting through proxy
+
+  $ kill `cat hg1.pid`
+  $ sleep 1
+
+  $ ("$TESTDIR/tinyproxy.py" $HGPORT1 localhost \
+ > >proxy.log 2>&1 </dev/null &
+ >  echo $! > proxy.pid)
+  $ cat proxy.pid >> $DAEMON_PIDS
+  $ sleep 2
+
+Test https through proxy
+
+  $ http_proxy=http://localhost:$HGPORT1/ \
+ >     hg --config http_proxy.always=True -R copy-pull pull --traceback
+  pulling from https://localhost:$HGPORT/
+  searching for changes
+  no changes found

BUT with plain 2.6 the pull fails with "abort: error: " - without any 
message:

   Traceback (most recent call last):
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/dispatch.py", line 58, 
in _runcatch
       return _dispatch(ui, args)
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/dispatch.py", line 
590, in _dispatch
       cmdpats, cmdoptions)
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/dispatch.py", line 
401, in runcommand
       ret = _runcommand(ui, options, cmd, d)
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/dispatch.py", line 
641, in _runcommand
       return checkargs()
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/dispatch.py", line 
595, in checkargs
       return cmdfunc()
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/dispatch.py", line 
588, in <lambda>
       d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
     File "/tmp/hgtests.f8FpOn/install/lib/python/mercurial/util.py", 
line 426, in check
       return func(*args, **kwargs)
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/commands.py", line 
2795, in pull
       other = hg.repository(hg.remoteui(repo, opts), source)
     File "/tmp/hgtests.f8FpOn/install/lib/python/mercurial/hg.py", line 
94, in repository
       repo = _lookup(path).instance(ui, path, create)
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/httprepo.py", line 
199, in instance
       inst.between([(nullid, nullid)])
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/wireproto.py", line 
68, in between
       d = self._call("between", pairs=n)
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/httprepo.py", line 
137, in _call
       fp = self._callstream(cmd, **args)
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/httprepo.py", line 88, 
in _callstream
       resp = self.urlopener.open(req)
     File "/usr/lib/python2.6/urllib2.py", line 383, in open
       response = self._open(req, data)
     File "/usr/lib/python2.6/urllib2.py", line 401, in _open
       '_open', req)
     File "/usr/lib/python2.6/urllib2.py", line 361, in _call_chain
       result = func(*args)
     File "/usr/lib/python2.6/urllib2.py", line 690, in <lambda>
       meth(r, proxy, type))
     File "/tmp/hgtests.f8FpOn/install/lib/python/mercurial/url.py", 
line 252, in proxy_open
       return urllib2.ProxyHandler.proxy_open(self, req, proxy, type_)
     File "/usr/lib/python2.6/urllib2.py", line 713, in proxy_open
       return self.parent.open(req)
     File "/usr/lib/python2.6/urllib2.py", line 383, in open
       response = self._open(req, data)
     File "/usr/lib/python2.6/urllib2.py", line 401, in _open
       '_open', req)
     File "/usr/lib/python2.6/urllib2.py", line 361, in _call_chain
       result = func(*args)
     File "/tmp/hgtests.f8FpOn/install/lib/python/mercurial/url.py", 
line 501, in http_open
       return self.do_open(httpconnection, req)
     File 
"/tmp/hgtests.f8FpOn/install/lib/python/mercurial/keepalive.py", line 
259, in do_open
       raise urllib2.URLError(err)
   URLError: <urlopen error >
   abort: error:
   [255]

Conclusion: https and proxy in python are very fishy, but especially the 
combination is horrible. This breaks Mercurial, even before we try to 
validate certificates, and even when only 2.6 or later is considered.

I really don't know what Python versions we can say we support for these 
"advanced" features. Anything but latest 2.6.x and 2.7.x doesn't seem 
feasible.

/Mads



More information about the Mercurial-devel mailing list