28 |
27 |
29 httplib = util.httplib |
28 httplib = util.httplib |
30 urlerr = util.urlerr |
29 urlerr = util.urlerr |
31 urlreq = util.urlreq |
30 urlreq = util.urlreq |
32 |
31 |
33 def zgenerator(f): |
32 # FUTURE: consider refactoring this API to use generators. This will |
34 zd = zlib.decompressobj() |
33 # require a compression engine API to emit generators. |
|
34 def decompressresponse(response, engine): |
35 try: |
35 try: |
36 for chunk in util.filechunkiter(f): |
36 reader = engine.decompressorreader(response) |
37 while chunk: |
|
38 yield zd.decompress(chunk, 2**18) |
|
39 chunk = zd.unconsumed_tail |
|
40 except httplib.HTTPException: |
37 except httplib.HTTPException: |
41 raise IOError(None, _('connection ended unexpectedly')) |
38 raise IOError(None, _('connection ended unexpectedly')) |
42 yield zd.flush() |
39 |
|
40 # We need to wrap reader.read() so HTTPException on subsequent |
|
41 # reads is also converted. |
|
42 origread = reader.read |
|
43 class readerproxy(reader.__class__): |
|
44 def read(self, *args, **kwargs): |
|
45 try: |
|
46 return origread(*args, **kwargs) |
|
47 except httplib.HTTPException: |
|
48 raise IOError(None, _('connection ended unexpectedly')) |
|
49 |
|
50 reader.__class__ = readerproxy |
|
51 return reader |
43 |
52 |
44 class httppeer(wireproto.wirepeer): |
53 class httppeer(wireproto.wirepeer): |
45 def __init__(self, ui, path): |
54 def __init__(self, ui, path): |
46 self.path = path |
55 self.path = path |
47 self.caps = None |
56 self.caps = None |
200 if version_info > (0, 1): |
209 if version_info > (0, 1): |
201 raise error.RepoError(_("'%s' uses newer protocol %s") % |
210 raise error.RepoError(_("'%s' uses newer protocol %s") % |
202 (safeurl, version)) |
211 (safeurl, version)) |
203 |
212 |
204 if _compressible: |
213 if _compressible: |
205 return util.chunkbuffer(zgenerator(resp)) |
214 return decompressresponse(resp, util.compengines['zlib']) |
206 |
215 |
207 return resp |
216 return resp |
208 |
217 |
209 def _call(self, cmd, **args): |
218 def _call(self, cmd, **args): |
210 fp = self._callstream(cmd, **args) |
219 fp = self._callstream(cmd, **args) |