##// END OF EJS Templates
push over http: client support....
Vadim Gelfer -
r2465:c91118f4 default
parent child Browse files
Show More
@@ -10,7 +10,7 b' 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(), "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):
@@ -69,6 +69,22 b' def netlocunsplit(host, port, user=None,'
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
@@ -86,7 +102,7 b' class httprepository(remoterepository):'
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]
@@ -154,6 +170,8 b' class httprepository(remoterepository):'
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)
@@ -165,13 +183,15 b' class httprepository(remoterepository):'
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))
175 except httplib.HTTPException, inst:
195 except httplib.HTTPException, inst:
176 self.ui.debug(_('http error while sending %s command\n') % cmd)
196 self.ui.debug(_('http error while sending %s command\n') % cmd)
177 self.ui.print_exc()
197 self.ui.print_exc()
@@ -249,7 +269,29 b' class httprepository(remoterepository):'
249 return util.chunkbuffer(zgenerator(util.filechunkiter(f)))
269 return util.chunkbuffer(zgenerator(util.filechunkiter(f)))
250
270
251 def unbundle(self, cg, heads, source):
271 def unbundle(self, cg, heads, source):
252 raise util.Abort(_('operation not supported over http'))
272 # have to stream bundle to a temp file because we do not have
273 # http 1.1 chunked transfer.
274
275 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
276 fp = os.fdopen(fd, 'wb+')
277 try:
278 for chunk in util.filechunkiter(cg):
279 fp.write(chunk)
280 length = fp.tell()
281 rfp = self.do_cmd(
282 'unbundle', data=fp,
283 headers={'content-length': length,
284 'content-type': 'application/octet-stream'},
285 heads=' '.join(map(hex, heads)))
286 try:
287 ret = int(rfp.readline())
288 self.ui.write(rfp.read())
289 return ret
290 finally:
291 rfp.close()
292 finally:
293 fp.close()
294 os.unlink(tempname)
253
295
254 class httpsrepository(httprepository):
296 class httpsrepository(httprepository):
255 pass
297 pass
General Comments 0
You need to be logged in to leave comments. Login now