mercurial/httppeer.py
changeset 32003 84569d2b3fb7
parent 32002 bf855efe5664
child 32022 e5d7f99a3063
equal deleted inserted replaced
32002:bf855efe5664 32003:84569d2b3fb7
    28 )
    28 )
    29 
    29 
    30 httplib = util.httplib
    30 httplib = util.httplib
    31 urlerr = util.urlerr
    31 urlerr = util.urlerr
    32 urlreq = util.urlreq
    32 urlreq = util.urlreq
    33 
       
    34 # FUTURE: consider refactoring this API to use generators. This will
       
    35 # require a compression engine API to emit generators.
       
    36 def decompressresponse(response, engine):
       
    37     try:
       
    38         reader = engine.decompressorreader(response)
       
    39     except httplib.HTTPException:
       
    40         raise IOError(None, _('connection ended unexpectedly'))
       
    41 
       
    42     # We need to wrap reader.read() so HTTPException on subsequent
       
    43     # reads is also converted.
       
    44     # Ideally we'd use super() here. However, if ``reader`` isn't a new-style
       
    45     # class, this can raise:
       
    46     # TypeError: super() argument 1 must be type, not classobj
       
    47     origread = reader.read
       
    48     class readerproxy(reader.__class__):
       
    49         def read(self, *args, **kwargs):
       
    50             try:
       
    51                 return origread(*args, **kwargs)
       
    52             except httplib.HTTPException:
       
    53                 raise IOError(None, _('connection ended unexpectedly'))
       
    54 
       
    55     reader.__class__ = readerproxy
       
    56     return reader
       
    57 
    33 
    58 def encodevalueinheaders(value, header, limit):
    34 def encodevalueinheaders(value, header, limit):
    59     """Encode a string value into multiple HTTP headers.
    35     """Encode a string value into multiple HTTP headers.
    60 
    36 
    61     ``value`` will be encoded into 1 or more HTTP headers with the names
    37     ``value`` will be encoded into 1 or more HTTP headers with the names
   295                 version_info = tuple([int(n) for n in version.split('.')])
   271                 version_info = tuple([int(n) for n in version.split('.')])
   296             except ValueError:
   272             except ValueError:
   297                 raise error.RepoError(_("'%s' sent a broken Content-Type "
   273                 raise error.RepoError(_("'%s' sent a broken Content-Type "
   298                                         "header (%s)") % (safeurl, proto))
   274                                         "header (%s)") % (safeurl, proto))
   299 
   275 
       
   276             # TODO consider switching to a decompression reader that uses
       
   277             # generators.
   300             if version_info == (0, 1):
   278             if version_info == (0, 1):
   301                 if _compressible:
   279                 if _compressible:
   302                     return decompressresponse(resp, util.compengines['zlib'])
   280                     return util.compengines['zlib'].decompressorreader(resp)
   303                 return resp
   281                 return resp
   304             elif version_info == (0, 2):
   282             elif version_info == (0, 2):
   305                 # application/mercurial-0.2 always identifies the compression
   283                 # application/mercurial-0.2 always identifies the compression
   306                 # engine in the payload header.
   284                 # engine in the payload header.
   307                 elen = struct.unpack('B', resp.read(1))[0]
   285                 elen = struct.unpack('B', resp.read(1))[0]
   308                 ename = resp.read(elen)
   286                 ename = resp.read(elen)
   309                 engine = util.compengines.forwiretype(ename)
   287                 engine = util.compengines.forwiretype(ename)
   310                 return decompressresponse(resp, engine)
   288                 return engine.decompressorreader(resp)
   311             else:
   289             else:
   312                 raise error.RepoError(_("'%s' uses newer protocol %s") %
   290                 raise error.RepoError(_("'%s' uses newer protocol %s") %
   313                                       (safeurl, version))
   291                                       (safeurl, version))
   314 
   292 
   315         if _compressible:
   293         if _compressible:
   316             return decompressresponse(resp, util.compengines['zlib'])
   294             return util.compengines['zlib'].decompressorreader(resp)
   317 
   295 
   318         return resp
   296         return resp
   319 
   297 
   320     def _call(self, cmd, **args):
   298     def _call(self, cmd, **args):
   321         fp = self._callstream(cmd, **args)
   299         fp = self._callstream(cmd, **args)