Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/httprepo.py @ 2471:6904e1ef8ad1
merge with crew.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Tue, 20 Jun 2006 23:58:45 -0700 |
parents | 4e78dc71d946 |
children | eabcda3ed0dd |
comparison
equal
deleted
inserted
replaced
2470:fe1689273f84 | 2471:6904e1ef8ad1 |
---|---|
8 from node import * | 8 from node import * |
9 from remoterepo import * | 9 from remoterepo import * |
10 from i18n import gettext as _ | 10 from i18n import gettext as _ |
11 from demandload import * | 11 from demandload import * |
12 demandload(globals(), "hg os urllib urllib2 urlparse zlib util httplib") | 12 demandload(globals(), "hg os urllib urllib2 urlparse zlib util httplib") |
13 demandload(globals(), "keepalive") | 13 demandload(globals(), "errno keepalive tempfile socket") |
14 | 14 |
15 class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm): | 15 class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm): |
16 def __init__(self, ui): | 16 def __init__(self, ui): |
17 urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self) | 17 urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self) |
18 self.ui = ui | 18 self.ui = ui |
67 else: | 67 else: |
68 userpass = urllib.quote(user) | 68 userpass = urllib.quote(user) |
69 return userpass + '@' + hostport | 69 return userpass + '@' + hostport |
70 return hostport | 70 return hostport |
71 | 71 |
72 class httpconnection(keepalive.HTTPConnection): | |
73 # must be able to send big bundle as stream. | |
74 | |
75 def send(self, data): | |
76 if isinstance(data, str): | |
77 keepalive.HTTPConnection.send(self, data) | |
78 else: | |
79 # if auth required, some data sent twice, so rewind here | |
80 data.seek(0) | |
81 for chunk in util.filechunkiter(data): | |
82 keepalive.HTTPConnection.send(self, chunk) | |
83 | |
84 class httphandler(keepalive.HTTPHandler): | |
85 def http_open(self, req): | |
86 return self.do_open(httpconnection, req) | |
87 | |
72 class httprepository(remoterepository): | 88 class httprepository(remoterepository): |
73 def __init__(self, ui, path): | 89 def __init__(self, ui, path): |
74 self.caps = None | 90 self.caps = None |
75 scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path) | 91 scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path) |
76 if query or frag: | 92 if query or frag: |
84 urlpath, '', '')) | 100 urlpath, '', '')) |
85 self.ui = ui | 101 self.ui = ui |
86 | 102 |
87 proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy') | 103 proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy') |
88 proxyauthinfo = None | 104 proxyauthinfo = None |
89 handler = keepalive.HTTPHandler() | 105 handler = httphandler() |
90 | 106 |
91 if proxyurl: | 107 if proxyurl: |
92 # proxy can be proper url or host[:port] | 108 # proxy can be proper url or host[:port] |
93 if not (proxyurl.startswith('http:') or | 109 if not (proxyurl.startswith('http:') or |
94 proxyurl.startswith('https:')): | 110 proxyurl.startswith('https:')): |
152 if self.caps is None: | 168 if self.caps is None: |
153 try: | 169 try: |
154 self.caps = self.do_read('capabilities').split() | 170 self.caps = self.do_read('capabilities').split() |
155 except hg.RepoError: | 171 except hg.RepoError: |
156 self.caps = () | 172 self.caps = () |
173 self.ui.debug(_('capabilities: %s\n') % | |
174 (' '.join(self.caps or ['none']))) | |
157 return self.caps | 175 return self.caps |
158 | 176 |
159 capabilities = property(get_caps) | 177 capabilities = property(get_caps) |
160 | 178 |
161 def dev(self): | 179 def dev(self): |
163 | 181 |
164 def lock(self): | 182 def lock(self): |
165 raise util.Abort(_('operation not supported over http')) | 183 raise util.Abort(_('operation not supported over http')) |
166 | 184 |
167 def do_cmd(self, cmd, **args): | 185 def do_cmd(self, cmd, **args): |
186 data = args.pop('data', None) | |
187 headers = args.pop('headers', {}) | |
168 self.ui.debug(_("sending %s command\n") % cmd) | 188 self.ui.debug(_("sending %s command\n") % cmd) |
169 q = {"cmd": cmd} | 189 q = {"cmd": cmd} |
170 q.update(args) | 190 q.update(args) |
171 qs = urllib.urlencode(q) | 191 qs = urllib.urlencode(q) |
172 cu = "%s?%s" % (self.url, qs) | 192 cu = "%s?%s" % (self.url, qs) |
173 try: | 193 try: |
174 resp = urllib2.urlopen(cu) | 194 resp = urllib2.urlopen(urllib2.Request(cu, data, headers)) |
195 except urllib2.HTTPError, inst: | |
196 if inst.code == 401: | |
197 raise util.Abort(_('authorization failed')) | |
198 raise | |
175 except httplib.HTTPException, inst: | 199 except httplib.HTTPException, inst: |
176 self.ui.debug(_('http error while sending %s command\n') % cmd) | 200 self.ui.debug(_('http error while sending %s command\n') % cmd) |
177 self.ui.print_exc() | 201 self.ui.print_exc() |
178 raise IOError(None, inst) | 202 raise IOError(None, inst) |
179 try: | 203 try: |
247 yield zd.flush() | 271 yield zd.flush() |
248 | 272 |
249 return util.chunkbuffer(zgenerator(util.filechunkiter(f))) | 273 return util.chunkbuffer(zgenerator(util.filechunkiter(f))) |
250 | 274 |
251 def unbundle(self, cg, heads, source): | 275 def unbundle(self, cg, heads, source): |
252 raise util.Abort(_('operation not supported over http')) | 276 # have to stream bundle to a temp file because we do not have |
277 # http 1.1 chunked transfer. | |
278 | |
279 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') | |
280 fp = os.fdopen(fd, 'wb+') | |
281 try: | |
282 for chunk in util.filechunkiter(cg): | |
283 fp.write(chunk) | |
284 length = fp.tell() | |
285 try: | |
286 rfp = self.do_cmd( | |
287 'unbundle', data=fp, | |
288 headers={'content-length': length, | |
289 'content-type': 'application/octet-stream'}, | |
290 heads=' '.join(map(hex, heads))) | |
291 try: | |
292 ret = int(rfp.readline()) | |
293 self.ui.write(rfp.read()) | |
294 return ret | |
295 finally: | |
296 rfp.close() | |
297 except socket.error, err: | |
298 if err[0] in (errno.ECONNRESET, errno.EPIPE): | |
299 raise util.Abort(_('push failed: %s'), err[1]) | |
300 raise util.Abort(err[1]) | |
301 finally: | |
302 fp.close() | |
303 os.unlink(tempname) | |
253 | 304 |
254 class httpsrepository(httprepository): | 305 class httpsrepository(httprepository): |
255 pass | 306 pass |