Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/httprepo.py @ 2435:ff2bac730b99
http client: support persistent connections.
uses keepalive module from urlgrabber package. tested against "hg serve",
cgi server, and through http proxy. used ethereal to verify that only
one tcp connection used during entire "hg pull" sequence.
if server supports keepalive, this makes latency of "hg pull" much lower.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Thu, 15 Jun 2006 12:57:59 -0700 |
parents | 3f24bc5dee81 |
children | e8c4f3d3df8c |
comparison
equal
deleted
inserted
replaced
2434:a2df85adface | 2435:ff2bac730b99 |
---|---|
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 | 14 |
14 class passwordmgr(urllib2.HTTPPasswordMgr): | 15 class passwordmgr(urllib2.HTTPPasswordMgr): |
15 def __init__(self, ui): | 16 def __init__(self, ui): |
16 urllib2.HTTPPasswordMgr.__init__(self) | 17 urllib2.HTTPPasswordMgr.__init__(self) |
17 self.ui = ui | 18 self.ui = ui |
82 urlpath, '', '')) | 83 urlpath, '', '')) |
83 self.ui = ui | 84 self.ui = ui |
84 | 85 |
85 proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy') | 86 proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy') |
86 proxyauthinfo = None | 87 proxyauthinfo = None |
87 handler = urllib2.BaseHandler() | 88 handler = keepalive.HTTPHandler() |
88 | 89 |
89 if proxyurl: | 90 if proxyurl: |
90 # proxy can be proper url or host[:port] | 91 # proxy can be proper url or host[:port] |
91 if not (proxyurl.startswith('http:') or | 92 if not (proxyurl.startswith('http:') or |
92 proxyurl.startswith('https:')): | 93 proxyurl.startswith('https:')): |
159 resp = urllib2.urlopen(cu) | 160 resp = urllib2.urlopen(cu) |
160 except httplib.HTTPException, inst: | 161 except httplib.HTTPException, inst: |
161 self.ui.debug(_('http error while sending %s command\n') % cmd) | 162 self.ui.debug(_('http error while sending %s command\n') % cmd) |
162 self.ui.print_exc() | 163 self.ui.print_exc() |
163 raise IOError(None, inst) | 164 raise IOError(None, inst) |
164 proto = resp.headers['content-type'] | 165 try: |
166 proto = resp.getheader('content-type') | |
167 except AttributeError: | |
168 proto = resp.headers['content-type'] | |
165 | 169 |
166 # accept old "text/plain" and "application/hg-changegroup" for now | 170 # accept old "text/plain" and "application/hg-changegroup" for now |
167 if not proto.startswith('application/mercurial') and \ | 171 if not proto.startswith('application/mercurial') and \ |
168 not proto.startswith('text/plain') and \ | 172 not proto.startswith('text/plain') and \ |
169 not proto.startswith('application/hg-changegroup'): | 173 not proto.startswith('application/hg-changegroup'): |
176 raise hg.RepoError(_("'%s' uses newer protocol %s") % | 180 raise hg.RepoError(_("'%s' uses newer protocol %s") % |
177 (self.url, version)) | 181 (self.url, version)) |
178 | 182 |
179 return resp | 183 return resp |
180 | 184 |
185 def do_read(self, cmd, **args): | |
186 fp = self.do_cmd(cmd, **args) | |
187 try: | |
188 return fp.read() | |
189 finally: | |
190 # if using keepalive, allow connection to be reused | |
191 fp.close() | |
192 | |
181 def heads(self): | 193 def heads(self): |
182 d = self.do_cmd("heads").read() | 194 d = self.do_read("heads") |
183 try: | 195 try: |
184 return map(bin, d[:-1].split(" ")) | 196 return map(bin, d[:-1].split(" ")) |
185 except: | 197 except: |
186 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n") | 198 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n") |
187 raise | 199 raise |
188 | 200 |
189 def branches(self, nodes): | 201 def branches(self, nodes): |
190 n = " ".join(map(hex, nodes)) | 202 n = " ".join(map(hex, nodes)) |
191 d = self.do_cmd("branches", nodes=n).read() | 203 d = self.do_read("branches", nodes=n) |
192 try: | 204 try: |
193 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] | 205 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] |
194 return br | 206 return br |
195 except: | 207 except: |
196 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n") | 208 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n") |
197 raise | 209 raise |
198 | 210 |
199 def between(self, pairs): | 211 def between(self, pairs): |
200 n = "\n".join(["-".join(map(hex, p)) for p in pairs]) | 212 n = "\n".join(["-".join(map(hex, p)) for p in pairs]) |
201 d = self.do_cmd("between", pairs=n).read() | 213 d = self.do_read("between", pairs=n) |
202 try: | 214 try: |
203 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] | 215 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] |
204 return p | 216 return p |
205 except: | 217 except: |
206 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n") | 218 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n") |