serve: fix https mode and add test
The https mode failed in super because BaseRequestHandler is an old-style
class.
This introduces the first test of https client/server functionality - and
"hghave ssl". The test is currently only run on Python 2.6.
--- a/mercurial/hgweb/server.py Sat Oct 16 17:29:04 2010 -0500
+++ b/mercurial/hgweb/server.py Sun Oct 17 04:13:35 2010 +0200
@@ -180,7 +180,7 @@
def do_write(self):
from OpenSSL.SSL import SysCallError
try:
- super(_shgwebhandler, self).do_write()
+ _hgwebhandler.do_write(self)
except SysCallError, inst:
if inst.args[0] != errno.EPIPE:
raise
@@ -188,7 +188,7 @@
def handle_one_request(self):
from OpenSSL.SSL import SysCallError, ZeroReturnError
try:
- super(_shgwebhandler, self).handle_one_request()
+ _hgwebhandler.handle_one_request(self)
except (SysCallError, ZeroReturnError):
self.close_connection = True
pass
--- a/tests/hghave Sat Oct 16 17:29:04 2010 -0500
+++ b/tests/hghave Sun Oct 17 04:13:35 2010 +0200
@@ -179,12 +179,21 @@
def has_outer_repo():
return matchoutput('hg root 2>&1', r'')
+def has_ssl():
+ try:
+ from OpenSSL.SSL import SysCallError, ZeroReturnError
+ import ssl
+ return True
+ except ImportError:
+ return False
+
checks = {
"baz": (has_baz, "GNU Arch baz client"),
"bzr": (has_bzr, "Canonical's Bazaar client"),
"bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
"cvs": (has_cvs, "cvs client/server"),
"darcs": (has_darcs, "darcs client"),
+ "docutils": (has_docutils, "Docutils text processing library"),
"eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
"execbit": (has_executablebit, "executable bit"),
"fifo": (has_fifo, "named pipes"),
@@ -198,7 +207,7 @@
"outer-repo": (has_outer_repo, "outer repo"),
"p4": (has_p4, "Perforce server and client"),
"pygments": (has_pygments, "Pygments source highlighting library"),
- "docutils": (has_docutils, "Docutils text processing library"),
+ "ssl": (has_ssl, "python ssl and openssl modules"),
"svn": (has_svn, "subversion client and admin tools"),
"svn-bindings": (has_svn_bindings, "subversion python bindings"),
"symlink": (has_symlink, "symbolic links"),
@@ -272,5 +281,3 @@
if failures != 0:
sys.exit(1)
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-https.t Sun Oct 17 04:13:35 2010 +0200
@@ -0,0 +1,103 @@
+Proper https client requires the built-in ssl from Python 2.6,
+and https serve requires the full OpenSSL module.
+
+ $ "$TESTDIR/hghave" ssl || exit 80
+
+HTTPS serve seems to be broken on Python 2.7:
+
+ $ [ "`python -c 'import sys; print sys.version_info[:2]'`" = '(2, 6)' ] || exit 80
+
+Certificates created with:
+ printf '.\n.\n.\n.\n.\nlocalhost\nhg@localhost\n' | \
+ openssl req -newkey rsa:512 -keyout priv.pem -nodes -x509 -days 9000 -out pub.pem
+Can be dumped with:
+ openssl x509 -in pub.pem -text
+
+ $ cat << EOT > priv.pem
+ > -----BEGIN PRIVATE KEY-----
+ > MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApjCWeYGrIa/Vo7LH
+ > aRF8ou0tbgHKE33Use/whCnKEUm34rDaXQd4lxxX6aDWg06n9tiVStAKTgQAHJY8
+ > j/xgSwIDAQABAkBxHC6+Qlf0VJXGlb6NL16yEVVTQxqDS6hA9zqu6TZjrr0YMfzc
+ > EGNIiZGt7HCBL0zO+cPDg/LeCZc6HQhf0KrhAiEAzlJq4hWWzvguWFIJWSoBeBUG
+ > MF1ACazQO7PYE8M0qfECIQDONHHP0SKZzz/ZwBZcAveC5K61f/v9hONFwbeYulzR
+ > +wIgc9SvbtgB/5Yzpp//4ZAEnR7oh5SClCvyB+KSx52K3nECICbhQphhoXmI10wy
+ > aMTellaq0bpNMHFDziqH9RsqAHhjAiEAgYGxfzkftt5IUUn/iFK89aaIpyrpuaAh
+ > HY8gUVkVRVs=
+ > -----END PRIVATE KEY-----
+ > EOT
+
+ $ cat << EOT > pub.pem
+ > -----BEGIN CERTIFICATE-----
+ > MIIBqzCCAVWgAwIBAgIJANAXFFyWjGnRMA0GCSqGSIb3DQEBBQUAMDExEjAQBgNV
+ > BAMMCWxvY2FsaG9zdDEbMBkGCSqGSIb3DQEJARYMaGdAbG9jYWxob3N0MB4XDTEw
+ > MTAxNDIwMzAxNFoXDTM1MDYwNTIwMzAxNFowMTESMBAGA1UEAwwJbG9jYWxob3N0
+ > MRswGQYJKoZIhvcNAQkBFgxoZ0Bsb2NhbGhvc3QwXDANBgkqhkiG9w0BAQEFAANL
+ > ADBIAkEApjCWeYGrIa/Vo7LHaRF8ou0tbgHKE33Use/whCnKEUm34rDaXQd4lxxX
+ > 6aDWg06n9tiVStAKTgQAHJY8j/xgSwIDAQABo1AwTjAdBgNVHQ4EFgQUE6sA+amm
+ > r24dGX0kpjxOgO45hzQwHwYDVR0jBBgwFoAUE6sA+ammr24dGX0kpjxOgO45hzQw
+ > DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAANBAFArvQFiAZJgQczRsbYlG1xl
+ > t+truk37w5B3m3Ick1ntRcQrqs+hf0CO1q6Squ144geYaQ8CDirSR92fICELI1c=
+ > -----END CERTIFICATE-----
+ > EOT
+ $ cat priv.pem pub.pem >> server.pem
+ $ PRIV=`pwd`/server.pem
+
+ $ hg init test
+ $ cd test
+ $ echo foo>foo
+ $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
+ $ echo foo>foo.d/foo
+ $ echo bar>foo.d/bAr.hg.d/BaR
+ $ echo bar>foo.d/baR.d.hg/bAR
+ $ hg commit -A -m 1
+ adding foo
+ adding foo.d/bAr.hg.d/BaR
+ adding foo.d/baR.d.hg/bAR
+ adding foo.d/foo
+ $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV
+ $ cat ../hg0.pid >> $DAEMON_PIDS
+
+Test server address cannot be reused
+
+ $ hg serve -p $HGPORT --certificate=$PRIV 2>&1
+ abort: cannot start server at ':$HGPORT': Address already in use
+ [255]
+ $ cd ..
+
+clone via pull
+
+ $ hg clone https://localhost:$HGPORT/ copy-pull
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 4 changes to 4 files
+ updating to branch default
+ 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg verify -R copy-pull
+ checking changesets
+ checking manifests
+ crosschecking files in changesets and manifests
+ checking files
+ 4 files, 1 changesets, 4 total revisions
+ $ cd test
+ $ echo bar > bar
+ $ hg commit -A -d '1 0' -m 2
+ adding bar
+ $ cd ..
+
+pull
+
+ $ cd copy-pull
+ $ echo '[hooks]' >> .hg/hgrc
+ $ echo "changegroup = python '$TESTDIR'/printenv.py changegroup" >> .hg/hgrc
+ $ hg pull
+ changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_URL=https://localhost:$HGPORT/
+ pulling from https://localhost:$HGPORT/
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+ (run 'hg update' to get a working copy)
+ $ cd ..