Mercurial > hg
annotate mercurial/statichttprepo.py @ 8723:b4a1b9012d96
Merge with crew-stable
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Sat, 06 Jun 2009 13:37:41 -0700 |
parents | e10e984bea46 |
children | 5614a628d173 |
rev | line source |
---|---|
1101 | 1 # statichttprepo.py - simple http repository class for mercurial |
2 # | |
3 # This provides read-only repo access to repositories exported via static http | |
4 # | |
4635
63b9d2deed48
Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4258
diff
changeset
|
5 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
1101 | 6 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7873
diff
changeset
|
7 # This software may be used and distributed according to the terms of the |
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7873
diff
changeset
|
8 # GNU General Public License version 2, incorporated herein by reference. |
1101 | 9 |
3891 | 10 from i18n import _ |
7637 | 11 import changelog, byterange, url, error |
7873
4a4c7f6a5912
cleanup: drop unused imports
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
7637
diff
changeset
|
12 import localrepo, manifest, util, store |
6028
6605a03cbf87
make static-http work with empty repos (issue965)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5321
diff
changeset
|
13 import urllib, urllib2, errno |
1325
57220daf40e9
Move urllib error handling from revlog into statichttprepo, where it belongs.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1101
diff
changeset
|
14 |
7274
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
15 class httprangereader(object): |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
16 def __init__(self, url, opener): |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
17 # we assume opener has HTTPRangeHandler |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
18 self.url = url |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
19 self.pos = 0 |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
20 self.opener = opener |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
21 def seek(self, pos): |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
22 self.pos = pos |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
23 def read(self, bytes=None): |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
24 req = urllib2.Request(self.url) |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
25 end = '' |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
26 if bytes: |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
27 end = self.pos + bytes - 1 |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
28 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end)) |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
29 |
1325
57220daf40e9
Move urllib error handling from revlog into statichttprepo, where it belongs.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1101
diff
changeset
|
30 try: |
7274
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
31 f = self.opener.open(req) |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
32 data = f.read() |
8612
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
33 if hasattr(f, 'getcode'): |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
34 # python 2.6+ |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
35 code = f.getcode() |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
36 elif hasattr(f, 'code'): |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
37 # undocumented attribute, seems to be set in 2.4 and 2.5 |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
38 code = f.code |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
39 else: |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
40 # Don't know how to check, hope for the best. |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
41 code = 206 |
1821
0b3f4be5c5bf
Catch urllib errors for old-http in a nicer way.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1598
diff
changeset
|
42 except urllib2.HTTPError, inst: |
6028
6605a03cbf87
make static-http work with empty repos (issue965)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5321
diff
changeset
|
43 num = inst.code == 404 and errno.ENOENT or None |
6605a03cbf87
make static-http work with empty repos (issue965)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5321
diff
changeset
|
44 raise IOError(num, inst) |
1325
57220daf40e9
Move urllib error handling from revlog into statichttprepo, where it belongs.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1101
diff
changeset
|
45 except urllib2.URLError, inst: |
1821
0b3f4be5c5bf
Catch urllib errors for old-http in a nicer way.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1598
diff
changeset
|
46 raise IOError(None, inst.reason[1]) |
1101 | 47 |
8612
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
48 if code == 200: |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
49 # HTTPRangeHandler does nothing if remote does not support |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
50 # Range headers and returns the full entity. Let's slice it. |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
51 if bytes: |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
52 data = data[self.pos:self.pos + bytes] |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
53 else: |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
54 data = data[self.pos:] |
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
55 elif bytes: |
7274
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
56 data = data[:bytes] |
8612
e10e984bea46
statichttprepo: handle remote not supporting Range headers
Patrick Mezard <pmezard@gmail.com>
parents:
8225
diff
changeset
|
57 self.pos += len(data) |
7274
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
58 return data |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
59 |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
60 def build_opener(ui, authinfo): |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
61 # urllib cannot handle URLs with embedded user or passwd |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
62 urlopener = url.opener(ui, authinfo) |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
63 urlopener.add_handler(byterange.HTTPRangeHandler()) |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
64 |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
65 def opener(base): |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
66 """return a function that opens files over http""" |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
67 p = base |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
68 def o(path, mode="r"): |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
69 f = "/".join((p, urllib.quote(path))) |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
70 return httprangereader(f, urlopener) |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
71 return o |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
72 |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
73 return opener |
1101 | 74 |
75 class statichttprepository(localrepo.localrepository): | |
76 def __init__(self, ui, path): | |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2072
diff
changeset
|
77 self._url = path |
1101 | 78 self.ui = ui |
3853
c0b449154a90
switch to the .hg/store layout, fix the tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3851
diff
changeset
|
79 |
7274
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
80 self.path, authinfo = url.getauthinfo(path.rstrip('/') + "/.hg") |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
81 |
95f3694cc5a4
statichttprepo: cleanups, use url.py (proxy, password support)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7211
diff
changeset
|
82 opener = build_opener(ui, authinfo) |
1101 | 83 self.opener = opener(self.path) |
6028
6605a03cbf87
make static-http work with empty repos (issue965)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5321
diff
changeset
|
84 |
3851
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
85 # find requirements |
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
86 try: |
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
87 requirements = self.opener("requires").read().splitlines() |
6028
6605a03cbf87
make static-http work with empty repos (issue965)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5321
diff
changeset
|
88 except IOError, inst: |
7178
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
89 if inst.errno != errno.ENOENT: |
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
90 raise |
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
91 # check if it is a non-empty old-style repository |
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
92 try: |
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
93 self.opener("00changelog.i").read(1) |
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
94 except IOError, inst: |
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
95 if inst.errno != errno.ENOENT: |
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
96 raise |
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
97 # we do not care about empty old-style repositories here |
6028
6605a03cbf87
make static-http work with empty repos (issue965)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5321
diff
changeset
|
98 msg = _("'%s' does not appear to be an hg repository") % path |
7637 | 99 raise error.RepoError(msg) |
7178
98b6c3dde237
Fix Debian bug #494889 (fetching from static-http://... broken)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6312
diff
changeset
|
100 requirements = [] |
6028
6605a03cbf87
make static-http work with empty repos (issue965)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5321
diff
changeset
|
101 |
3851
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
102 # check them |
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
103 for r in requirements: |
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
104 if r not in self.supported: |
7637 | 105 raise error.RepoError(_("requirement '%s' not supported") % r) |
3851
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
106 |
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
107 # setup store |
6988 | 108 def pjoin(a, b): |
109 return a + '/' + b | |
110 self.store = store.store(requirements, self.path, opener, pjoin) | |
6897
faea0d27e38f
statichttp: use store class
Matt Mackall <mpm@selenic.com>
parents:
6840
diff
changeset
|
111 self.spath = self.store.path |
faea0d27e38f
statichttp: use store class
Matt Mackall <mpm@selenic.com>
parents:
6840
diff
changeset
|
112 self.sopener = self.store.opener |
faea0d27e38f
statichttp: use store class
Matt Mackall <mpm@selenic.com>
parents:
6840
diff
changeset
|
113 self.sjoin = self.store.join |
3851
8f18e31c4441
add "requires" file to the repo, specifying the requirements
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3794
diff
changeset
|
114 |
3791
8643b9f90b51
introduce localrepo.spath for the store path, sopener fixes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3457
diff
changeset
|
115 self.manifest = manifest.manifest(self.sopener) |
8643b9f90b51
introduce localrepo.spath for the store path, sopener fixes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3457
diff
changeset
|
116 self.changelog = changelog.changelog(self.sopener) |
1101 | 117 self.tagscache = None |
118 self.nodetagscache = None | |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1325
diff
changeset
|
119 self.encodepats = None |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1325
diff
changeset
|
120 self.decodepats = None |
1101 | 121 |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2072
diff
changeset
|
122 def url(self): |
7211 | 123 return self._url |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2072
diff
changeset
|
124 |
1101 | 125 def local(self): |
126 return False | |
2740
386f04d6ecb3
clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2673
diff
changeset
|
127 |
7005
7739b61897df
do not pretend to lock static-http repositories (issue994)
Martin Geisler <mg@daimi.au.dk>
parents:
6988
diff
changeset
|
128 def lock(self, wait=True): |
7739b61897df
do not pretend to lock static-http repositories (issue994)
Martin Geisler <mg@daimi.au.dk>
parents:
6988
diff
changeset
|
129 raise util.Abort(_('cannot lock static-http repository')) |
7739b61897df
do not pretend to lock static-http repositories (issue994)
Martin Geisler <mg@daimi.au.dk>
parents:
6988
diff
changeset
|
130 |
2740
386f04d6ecb3
clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2673
diff
changeset
|
131 def instance(ui, path, create): |
386f04d6ecb3
clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2673
diff
changeset
|
132 if create: |
386f04d6ecb3
clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2673
diff
changeset
|
133 raise util.Abort(_('cannot create new static-http repository')) |
4853
bf10a03a6b24
Removed deprecated hg:// and old-http:// protocols (issue406)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4635
diff
changeset
|
134 return statichttprepository(ui, path[7:]) |