mercurial/httppeer.py
changeset 28883 032c4c2f802a
parent 28666 ae53ecc47414
child 29241 269f7ea08983
equal deleted inserted replaced
28882:800ec7c048b0 28883:032c4c2f802a
    11 import errno
    11 import errno
    12 import httplib
    12 import httplib
    13 import os
    13 import os
    14 import socket
    14 import socket
    15 import tempfile
    15 import tempfile
    16 import urllib
       
    17 import urllib2
       
    18 import zlib
    16 import zlib
    19 
    17 
    20 from .i18n import _
    18 from .i18n import _
    21 from .node import nullid
    19 from .node import nullid
    22 from . import (
    20 from . import (
    27     url,
    25     url,
    28     util,
    26     util,
    29     wireproto,
    27     wireproto,
    30 )
    28 )
    31 
    29 
       
    30 urlerr = util.urlerr
       
    31 urlreq = util.urlreq
       
    32 
    32 def zgenerator(f):
    33 def zgenerator(f):
    33     zd = zlib.decompressobj()
    34     zd = zlib.decompressobj()
    34     try:
    35     try:
    35         for chunk in util.filechunkiter(f):
    36         for chunk in util.filechunkiter(f):
    36             while chunk:
    37             while chunk:
    57 
    58 
    58         self.ui = ui
    59         self.ui = ui
    59         self.ui.debug('using %s\n' % self._url)
    60         self.ui.debug('using %s\n' % self._url)
    60 
    61 
    61         self.urlopener = url.opener(ui, authinfo)
    62         self.urlopener = url.opener(ui, authinfo)
    62         self.requestbuilder = urllib2.Request
    63         self.requestbuilder = urlreq.request
    63 
    64 
    64     def __del__(self):
    65     def __del__(self):
    65         if self.urlopener:
    66         if self.urlopener:
    66             for h in self.urlopener.handlers:
    67             for h in self.urlopener.handlers:
    67                 h.close()
    68                 h.close()
   103         postargsok = self.caps is not None and 'httppostargs' in self.caps
   104         postargsok = self.caps is not None and 'httppostargs' in self.caps
   104         # TODO: support for httppostargs when data is a file-like
   105         # TODO: support for httppostargs when data is a file-like
   105         # object rather than a basestring
   106         # object rather than a basestring
   106         canmungedata = not data or isinstance(data, basestring)
   107         canmungedata = not data or isinstance(data, basestring)
   107         if postargsok and canmungedata:
   108         if postargsok and canmungedata:
   108             strargs = urllib.urlencode(sorted(args.items()))
   109             strargs = urlreq.urlencode(sorted(args.items()))
   109             if strargs:
   110             if strargs:
   110                 if not data:
   111                 if not data:
   111                     data = strargs
   112                     data = strargs
   112                 elif isinstance(data, basestring):
   113                 elif isinstance(data, basestring):
   113                     data = strargs + data
   114                     data = strargs + data
   117                 httpheader = self.capable('httpheader')
   118                 httpheader = self.capable('httpheader')
   118                 if httpheader:
   119                 if httpheader:
   119                     headersize = int(httpheader.split(',', 1)[0])
   120                     headersize = int(httpheader.split(',', 1)[0])
   120             if headersize > 0:
   121             if headersize > 0:
   121                 # The headers can typically carry more data than the URL.
   122                 # The headers can typically carry more data than the URL.
   122                 encargs = urllib.urlencode(sorted(args.items()))
   123                 encargs = urlreq.urlencode(sorted(args.items()))
   123                 headerfmt = 'X-HgArg-%s'
   124                 headerfmt = 'X-HgArg-%s'
   124                 contentlen = headersize - len(headerfmt % '000' + ': \r\n')
   125                 contentlen = headersize - len(headerfmt % '000' + ': \r\n')
   125                 headernum = 0
   126                 headernum = 0
   126                 varyheaders = []
   127                 varyheaders = []
   127                 for i in xrange(0, len(encargs), contentlen):
   128                 for i in xrange(0, len(encargs), contentlen):
   130                     headers[header] = encargs[i:i + contentlen]
   131                     headers[header] = encargs[i:i + contentlen]
   131                     varyheaders.append(header)
   132                     varyheaders.append(header)
   132                 headers['Vary'] = ','.join(varyheaders)
   133                 headers['Vary'] = ','.join(varyheaders)
   133             else:
   134             else:
   134                 q += sorted(args.items())
   135                 q += sorted(args.items())
   135         qs = '?%s' % urllib.urlencode(q)
   136         qs = '?%s' % urlreq.urlencode(q)
   136         cu = "%s%s" % (self._url, qs)
   137         cu = "%s%s" % (self._url, qs)
   137         size = 0
   138         size = 0
   138         if util.safehasattr(data, 'length'):
   139         if util.safehasattr(data, 'length'):
   139             size = data.length
   140             size = data.length
   140         elif data is not None:
   141         elif data is not None:
   148         if data is not None:
   149         if data is not None:
   149             self.ui.debug("sending %s bytes\n" % size)
   150             self.ui.debug("sending %s bytes\n" % size)
   150             req.add_unredirected_header('Content-Length', '%d' % size)
   151             req.add_unredirected_header('Content-Length', '%d' % size)
   151         try:
   152         try:
   152             resp = self.urlopener.open(req)
   153             resp = self.urlopener.open(req)
   153         except urllib2.HTTPError as inst:
   154         except urlerr.httperror as inst:
   154             if inst.code == 401:
   155             if inst.code == 401:
   155                 raise error.Abort(_('authorization failed'))
   156                 raise error.Abort(_('authorization failed'))
   156             raise
   157             raise
   157         except httplib.HTTPException as inst:
   158         except httplib.HTTPException as inst:
   158             self.ui.debug('http error while sending %s command\n' % cmd)
   159             self.ui.debug('http error while sending %s command\n' % cmd)