mercurial/httppeer.py
changeset 30465 40a1871eea5e
parent 30464 e16e234b9ca3
child 30475 ef9f197188ec
equal deleted inserted replaced
30464:e16e234b9ca3 30465:40a1871eea5e
    10 
    10 
    11 import errno
    11 import errno
    12 import os
    12 import os
    13 import socket
    13 import socket
    14 import tempfile
    14 import tempfile
    15 import zlib
       
    16 
    15 
    17 from .i18n import _
    16 from .i18n import _
    18 from .node import nullid
    17 from .node import nullid
    19 from . import (
    18 from . import (
    20     bundle2,
    19     bundle2,
    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)