Example #1
0
    def _check_url(cls, url):
        """
        Function will check given url and try to verify if it's a valid
        link. Sometimes it may happened that git will issue basic
        auth request that can cause whole API to hang when used from python
        or other external calls.

        On failures it'll raise urllib2.HTTPError, exception is also thrown
        when the return code is non 200
        """
        # check first if it's not an local url
        if os.path.isdir(url) or url.startswith('file:'):
            return True

        if url.startswith('git://'):
            return True

        if '+' in url[:url.find('://')]:
            url = url[url.find('+') + 1:]

        handlers = []
        url_obj = mercurial.util.url(safe_bytes(url))
        test_uri, authinfo = url_obj.authinfo()
        if not test_uri.endswith(b'info/refs'):
            test_uri = test_uri.rstrip(b'/') + b'/info/refs'

        url_obj.passwd = b'*****'
        cleaned_uri = str(url_obj)

        if authinfo:
            # create a password manager
            passmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
            passmgr.add_password(*authinfo)

            handlers.extend((mercurial.url.httpbasicauthhandler(passmgr),
                             mercurial.url.httpdigestauthhandler(passmgr)))

        o = urllib.request.build_opener(*handlers)
        o.addheaders = [('User-Agent', 'git/1.7.8.0')]  # fake some git

        req = urllib.request.Request(
            "%s?%s" % (safe_str(test_uri),
                       urllib.parse.urlencode({"service": 'git-upload-pack'})))

        try:
            resp = o.open(req)
            if resp.code != 200:
                raise Exception('Return Code is not 200')
        except Exception as e:
            # means it cannot be cloned
            raise urllib.error.URLError("[%s] org_exc: %s" % (cleaned_uri, e))

        # now detect if it's proper git repo
        gitdata = resp.read()
        if b'service=git-upload-pack' not in gitdata:
            raise urllib.error.URLError("url [%s] does not look like an git" %
                                        cleaned_uri)

        return True
Example #2
0
 def __init__(self, remote, url):
     if remote.startswith(('hg::', 'hg://')):
         self.name = None
     else:
         self.name = remote
     self.parsed_url = munge_url(url)
     self.url = urlunparse(self.parsed_url)
     self.git_url = url if url.startswith('hg://') else 'hg::%s' % url
Example #3
0
 def __init__(self, remote, url):
     if remote.startswith(('hg::', 'hg://')):
         self.name = None
     else:
         self.name = remote
     self.parsed_url = munge_url(url)
     self.url = urlunparse(self.parsed_url)
     self.git_url = url if url.startswith('hg://') else 'hg::%s' % url
Example #4
0
    def _check_url(cls, url, repoui=None):
        """
        Function will check given url and try to verify if it's a valid
        link. Sometimes it may happened that mercurial will issue basic
        auth request that can cause whole API to hang when used from python
        or other external calls.

        On failures it'll raise urllib2.HTTPError, exception is also thrown
        when the return code is non 200
        """
        # check first if it's not an local url
        url = safe_bytes(url)
        if os.path.isdir(url) or url.startswith(b'file:'):
            return True

        if url.startswith(b'ssh:'):
            # in case of invalid uri or authentication issues, sshpeer will
            # throw an exception.
            mercurial.sshpeer.instance(repoui or mercurial.ui.ui(), url,
                                       False).lookup(b'tip')
            return True

        url_prefix = None
        if b'+' in url[:url.find(b'://')]:
            url_prefix, url = url.split(b'+', 1)

        handlers = []
        url_obj = mercurial.util.url(url)
        test_uri, authinfo = url_obj.authinfo()
        url_obj.passwd = b'*****'
        cleaned_uri = str(url_obj)

        if authinfo:
            # create a password manager
            passmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
            passmgr.add_password(*authinfo)

            handlers.extend((mercurial.url.httpbasicauthhandler(passmgr),
                             mercurial.url.httpdigestauthhandler(passmgr)))

        o = urllib.request.build_opener(*handlers)
        o.addheaders = [('Content-Type', 'application/mercurial-0.1'),
                        ('Accept', 'application/mercurial-0.1')]

        req = urllib.request.Request(
            "%s?%s" %
            (test_uri,
             urllib.parse.urlencode({
                 'cmd': 'between',
                 'pairs': "%s-%s" % ('0' * 40, '0' * 40),
             })))

        try:
            resp = o.open(req)
            if resp.code != 200:
                raise Exception('Return Code is not 200')
        except Exception as e:
            # means it cannot be cloned
            raise urllib.error.URLError("[%s] org_exc: %s" % (cleaned_uri, e))

        if not url_prefix:  # skip svn+http://... (and git+... too)
            # now check if it's a proper hg repo
            try:
                mercurial.httppeer.instance(repoui or mercurial.ui.ui(), url,
                                            False).lookup(b'tip')
            except Exception as e:
                raise urllib.error.URLError(
                    "url [%s] does not look like an hg repo org_exc: %s" %
                    (cleaned_uri, e))

        return True