mercurial/httprepo.py
changeset 5123 79373ec3f27d
parent 4853 bf10a03a6b24
parent 5066 167c422c745f
child 5176 664a1c312972
equal deleted inserted replaced
5122:487659a90497 5123:79373ec3f27d
   142             yield zd.decompress(chunk)
   142             yield zd.decompress(chunk)
   143     except httplib.HTTPException, inst:
   143     except httplib.HTTPException, inst:
   144         raise IOError(None, _('connection ended unexpectedly'))
   144         raise IOError(None, _('connection ended unexpectedly'))
   145     yield zd.flush()
   145     yield zd.flush()
   146 
   146 
       
   147 _safe = ('abcdefghijklmnopqrstuvwxyz'
       
   148          'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
       
   149          '0123456789' '_.-/')
       
   150 _safeset = None
       
   151 _hex = None
       
   152 def quotepath(path):
       
   153     '''quote the path part of a URL
       
   154 
       
   155     This is similar to urllib.quote, but it also tries to avoid
       
   156     quoting things twice (inspired by wget):
       
   157 
       
   158     >>> quotepath('abc def')
       
   159     'abc%20def'
       
   160     >>> quotepath('abc%20def')
       
   161     'abc%20def'
       
   162     >>> quotepath('abc%20 def')
       
   163     'abc%20%20def'
       
   164     >>> quotepath('abc def%20')
       
   165     'abc%20def%20'
       
   166     >>> quotepath('abc def%2')
       
   167     'abc%20def%252'
       
   168     >>> quotepath('abc def%')
       
   169     'abc%20def%25'
       
   170     '''
       
   171     global _safeset, _hex
       
   172     if _safeset is None:
       
   173         _safeset = util.set(_safe)
       
   174         _hex = util.set('abcdefABCDEF0123456789')
       
   175     l = list(path)
       
   176     for i in xrange(len(l)):
       
   177         c = l[i]
       
   178         if c == '%' and i + 2 < len(l) and (l[i+1] in _hex and l[i+2] in _hex):
       
   179             pass
       
   180         elif c not in _safeset:
       
   181             l[i] = '%%%02X' % ord(c)
       
   182     return ''.join(l)
       
   183 
   147 class httprepository(remoterepository):
   184 class httprepository(remoterepository):
   148     def __init__(self, ui, path):
   185     def __init__(self, ui, path):
   149         self.path = path
   186         self.path = path
   150         self.caps = None
   187         self.caps = None
   151         self.handler = None
   188         self.handler = None
   152         scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
   189         scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
   153         if query or frag:
   190         if query or frag:
   154             raise util.Abort(_('unsupported URL component: "%s"') %
   191             raise util.Abort(_('unsupported URL component: "%s"') %
   155                              (query or frag))
   192                              (query or frag))
   156         if not urlpath: urlpath = '/'
   193         if not urlpath:
       
   194             urlpath = '/'
       
   195         urlpath = quotepath(urlpath)
   157         host, port, user, passwd = netlocsplit(netloc)
   196         host, port, user, passwd = netlocsplit(netloc)
   158 
   197 
   159         # urllib cannot handle URLs with embedded user or passwd
   198         # urllib cannot handle URLs with embedded user or passwd
   160         self._url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
   199         self._url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
   161                                          urlpath, '', ''))
   200                                          urlpath, '', ''))
   162         self.ui = ui
   201         self.ui = ui
       
   202         self.ui.debug(_('using %s\n') % self._url)
   163 
   203 
   164         proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
   204         proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
   165         # XXX proxyauthinfo = None
   205         # XXX proxyauthinfo = None
   166         self.handler = httphandler()
   206         self.handler = httphandler()
   167         handlers = [self.handler]
   207         handlers = [self.handler]