changeset 2704:959d0daa44da beta

Added url validator for git
author Marcin Kuzminski <marcin@python-works.com>
date Wed, 08 Aug 2012 21:32:05 +0200
parents 02ec22d017c2
children bf177b4981c3
files rhodecode/lib/vcs/backends/git/repository.py rhodecode/lib/vcs/backends/hg/repository.py
diffstat 2 files changed, 47 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/lib/vcs/backends/git/repository.py	Wed Aug 08 20:03:53 2012 +0200
+++ b/rhodecode/lib/vcs/backends/git/repository.py	Wed Aug 08 21:32:05 2012 +0200
@@ -15,6 +15,8 @@
 import posixpath
 import logging
 import traceback
+import urllib
+import urllib2
 from dulwich.repo import Repo, NotGitRepository
 #from dulwich.config import ConfigFile
 from string import Template
@@ -126,7 +128,8 @@
         se = None
         return so, se
 
-    def _check_url(self, url):
+    @classmethod
+    def _check_url(cls, url):
         """
         Functon will check given url and try to verify if it's a valid
         link. Sometimes it may happened that mercurial will issue basic
@@ -135,9 +138,45 @@
 
         On failures it'll raise urllib2.HTTPError
         """
+        from mercurial.util import url as Url
 
-        #TODO: implement this
-        pass
+        # those authnadlers are patched for python 2.6.5 bug an
+        # infinit looping when given invalid resources
+        from mercurial.url import httpbasicauthhandler, httpdigestauthhandler
+
+        # check first if it's not an local url
+        if os.path.isdir(url) or url.startswith('file:'):
+            return True
+
+        if('+' in url[:url.find('://')]):
+            url = url[url.find('+') + 1:]
+
+        handlers = []
+        test_uri, authinfo = Url(url).authinfo()
+        if not test_uri.endswith('info/refs'):
+            test_uri = test_uri.rstrip('/') + '/info/refs'
+        if authinfo:
+            #create a password manager
+            passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
+            passmgr.add_password(*authinfo)
+
+            handlers.extend((httpbasicauthhandler(passmgr),
+                             httpdigestauthhandler(passmgr)))
+
+        o = urllib2.build_opener(*handlers)
+        o.addheaders = [('User-Agent', 'git/1.7.8.0')]  # fake some git
+
+        q = {"service": 'git-upload-pack'}
+        qs = '?%s' % urllib.urlencode(q)
+        cu = "%s%s" % (test_uri, qs)
+        req = urllib2.Request(cu, None, {})
+
+        try:
+            resp = o.open(req)
+            return resp.code == 200
+        except Exception, e:
+            # means it cannot be cloned
+            raise urllib2.URLError(e)
 
     def _get_repo(self, create, src_url=None, update_after_clone=False,
             bare=False):
@@ -148,7 +187,7 @@
                                   "given (clone operation creates repository)")
         try:
             if create and src_url:
-                self._check_url(src_url)
+                GitRepository._check_url(src_url)
                 self.clone(src_url, update_after_clone, bare)
                 return Repo(self.path)
             elif create:
--- a/rhodecode/lib/vcs/backends/hg/repository.py	Wed Aug 08 20:03:53 2012 +0200
+++ b/rhodecode/lib/vcs/backends/hg/repository.py	Wed Aug 08 21:32:05 2012 +0200
@@ -249,7 +249,8 @@
                                         ignorews=ignore_whitespace,
                                         context=context)))
 
-    def _check_url(self, url):
+    @classmethod
+    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 mercurial will issue basic
@@ -271,7 +272,7 @@
             return True
 
         if('+' in url[:url.find('://')]):
-            url = url[url.find('+')+1:]
+            url = url[url.find('+') + 1:]
 
         handlers = []
         test_uri, authinfo = Url(url).authinfo()
@@ -318,7 +319,7 @@
                 if not update_after_clone:
                     opts.update({'noupdate': True})
                 try:
-                    self._check_url(url)
+                    MercurialRepository._check_url(url)
                     clone(self.baseui, url, self.path, **opts)
 #                except urllib2.URLError:
 #                    raise Abort("Got HTTP 404 error")