##// END OF EJS Templates
statichttprepo: kill off sopener
Siddharth Agarwal -
r25670:6368c51c default
parent child Browse files
Show More
@@ -1,164 +1,163 b''
1 1 # statichttprepo.py - simple http repository class for mercurial
2 2 #
3 3 # This provides read-only repo access to repositories exported via static http
4 4 #
5 5 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
6 6 #
7 7 # This software may be used and distributed according to the terms of the
8 8 # GNU General Public License version 2 or any later version.
9 9
10 10 from i18n import _
11 11 import changelog, byterange, url, error, namespaces
12 12 import localrepo, manifest, util, scmutil, store
13 13 import urllib, urllib2, errno, os
14 14
15 15 class httprangereader(object):
16 16 def __init__(self, url, opener):
17 17 # we assume opener has HTTPRangeHandler
18 18 self.url = url
19 19 self.pos = 0
20 20 self.opener = opener
21 21 self.name = url
22 22 def seek(self, pos):
23 23 self.pos = pos
24 24 def read(self, bytes=None):
25 25 req = urllib2.Request(self.url)
26 26 end = ''
27 27 if bytes:
28 28 end = self.pos + bytes - 1
29 29 if self.pos or end:
30 30 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
31 31
32 32 try:
33 33 f = self.opener.open(req)
34 34 data = f.read()
35 35 code = f.code
36 36 except urllib2.HTTPError as inst:
37 37 num = inst.code == 404 and errno.ENOENT or None
38 38 raise IOError(num, inst)
39 39 except urllib2.URLError as inst:
40 40 raise IOError(None, inst.reason[1])
41 41
42 42 if code == 200:
43 43 # HTTPRangeHandler does nothing if remote does not support
44 44 # Range headers and returns the full entity. Let's slice it.
45 45 if bytes:
46 46 data = data[self.pos:self.pos + bytes]
47 47 else:
48 48 data = data[self.pos:]
49 49 elif bytes:
50 50 data = data[:bytes]
51 51 self.pos += len(data)
52 52 return data
53 53 def readlines(self):
54 54 return self.read().splitlines(True)
55 55 def __iter__(self):
56 56 return iter(self.readlines())
57 57 def close(self):
58 58 pass
59 59
60 60 def build_opener(ui, authinfo):
61 61 # urllib cannot handle URLs with embedded user or passwd
62 62 urlopener = url.opener(ui, authinfo)
63 63 urlopener.add_handler(byterange.HTTPRangeHandler())
64 64
65 65 class statichttpvfs(scmutil.abstractvfs):
66 66 def __init__(self, base):
67 67 self.base = base
68 68
69 69 def __call__(self, path, mode='r', *args, **kw):
70 70 if mode not in ('r', 'rb'):
71 71 raise IOError('Permission denied')
72 72 f = "/".join((self.base, urllib.quote(path)))
73 73 return httprangereader(f, urlopener)
74 74
75 75 def join(self, path):
76 76 if path:
77 77 return os.path.join(self.base, path)
78 78 else:
79 79 return self.base
80 80
81 81 return statichttpvfs
82 82
83 83 class statichttppeer(localrepo.localpeer):
84 84 def local(self):
85 85 return None
86 86 def canpush(self):
87 87 return False
88 88
89 89 class statichttprepository(localrepo.localrepository):
90 90 supported = localrepo.localrepository._basesupported
91 91
92 92 def __init__(self, ui, path):
93 93 self._url = path
94 94 self.ui = ui
95 95
96 96 self.root = path
97 97 u = util.url(path.rstrip('/') + "/.hg")
98 98 self.path, authinfo = u.authinfo()
99 99
100 100 opener = build_opener(ui, authinfo)
101 101 self.opener = opener(self.path)
102 102 self.vfs = self.opener
103 103 self._phasedefaults = []
104 104
105 105 self.names = namespaces.namespaces()
106 106
107 107 try:
108 108 requirements = scmutil.readrequires(self.vfs, self.supported)
109 109 except IOError as inst:
110 110 if inst.errno != errno.ENOENT:
111 111 raise
112 112 requirements = set()
113 113
114 114 # check if it is a non-empty old-style repository
115 115 try:
116 116 fp = self.vfs("00changelog.i")
117 117 fp.read(1)
118 118 fp.close()
119 119 except IOError as inst:
120 120 if inst.errno != errno.ENOENT:
121 121 raise
122 122 # we do not care about empty old-style repositories here
123 123 msg = _("'%s' does not appear to be an hg repository") % path
124 124 raise error.RepoError(msg)
125 125
126 126 # setup store
127 127 self.store = store.store(requirements, self.path, opener)
128 128 self.spath = self.store.path
129 129 self.svfs = self.store.opener
130 self.sopener = self.svfs
131 130 self.sjoin = self.store.join
132 131 self._filecache = {}
133 132 self.requirements = requirements
134 133
135 134 self.manifest = manifest.manifest(self.svfs)
136 135 self.changelog = changelog.changelog(self.svfs)
137 136 self._tags = None
138 137 self.nodetagscache = None
139 138 self._branchcaches = {}
140 139 self._revbranchcache = None
141 140 self.encodepats = None
142 141 self.decodepats = None
143 142 self._transref = None
144 143
145 144 def _restrictcapabilities(self, caps):
146 145 caps = super(statichttprepository, self)._restrictcapabilities(caps)
147 146 return caps.difference(["pushkey"])
148 147
149 148 def url(self):
150 149 return self._url
151 150
152 151 def local(self):
153 152 return False
154 153
155 154 def peer(self):
156 155 return statichttppeer(self)
157 156
158 157 def lock(self, wait=True):
159 158 raise util.Abort(_('cannot lock static-http repository'))
160 159
161 160 def instance(ui, path, create):
162 161 if create:
163 162 raise util.Abort(_('cannot create new static-http repository'))
164 163 return statichttprepository(ui, path[7:])
General Comments 0
You need to be logged in to leave comments. Login now