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