~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/sftp.py

  • Committer: Robey Pointer
  • Date: 2005-11-07 07:56:31 UTC
  • mto: (1185.49.5 sftp-fix)
  • mto: This revision was merged to the branch mainline in revision 1518.
  • Revision ID: robey@lag.net-20051107075631-95a57ed02ee8cca0
fix sftp urls to support the ietf draft url spec wrt relative vs absolute sftp urls (this will break existing branch urls); fix username/password parsing in sftp urls; add unit tests to make sure sftp url parsing is working

Show diffs side-by-side

added added

removed removed

Lines of Context:
87
87
    Transport implementation for SFTP access.
88
88
    """
89
89
 
90
 
    _url_matcher = re.compile(r'^sftp://([^:@]*(:[^@]*)?@)?(.*?)(:\d+)?(/.*)?$')
 
90
    _url_matcher = re.compile(r'^sftp://([^:@]*(:[^@]*)?@)?(.*?)(:[^/]+)?(/.*)?$')
91
91
    
92
92
    def __init__(self, base, clone_from=None):
93
93
        assert base.startswith('sftp://')
148
148
                basepath.append(p)
149
149
 
150
150
        path = '/'.join(basepath)
151
 
        if len(path) and path[0] != '/':
152
 
            path = '/' + path
 
151
        # could still be a "relative" path here, but relative on the sftp server
153
152
        return path
154
153
 
155
154
    def relpath(self, abspath):
366
365
    def _unparse_url(self, path=None):
367
366
        if path is None:
368
367
            path = self._path
369
 
        if self._port == 22:
370
 
            return 'sftp://%s@%s%s' % (self._username, self._host, path)
371
 
        return 'sftp://%s@%s:%d%s' % (self._username, self._host, self._port, path)
 
368
        host = self._host
 
369
        username = urllib.quote(self._username)
 
370
        if self._password:
 
371
            username += ':' + urllib.quote(self._password)
 
372
        if self._port != 22:
 
373
            host += ':%d' % self._port
 
374
        return 'sftp://%s@%s/%s' % (username, host, urllib.quote(path))
372
375
 
373
376
    def _parse_url(self, url):
374
377
        assert url[:7] == 'sftp://'
379
382
        if self._username is None:
380
383
            self._username = getpass.getuser()
381
384
        else:
382
 
            self._username = self._username[:-1]
383
 
        if self._password:
384
 
            self._password = self._password[1:]
385
 
            self._username = self._username[len(self._password)+1:]
 
385
            if self._password:
 
386
                # username field is 'user:pass@' in this case, and password is ':pass'
 
387
                username_len = len(self._username) - len(self._password) - 1
 
388
                self._username = urllib.unquote(self._username[:username_len])
 
389
                self._password = urllib.unquote(self._password[1:])
 
390
            else:
 
391
                self._username = urllib.unquote(self._username[:-1])
386
392
        if self._port is None:
387
393
            self._port = 22
388
394
        else:
389
395
            self._port = int(self._port[1:])
390
396
        if (self._path is None) or (self._path == ''):
391
 
            self._path = '/'
 
397
            self._path = ''
 
398
        else:
 
399
            # remove leading '/'
 
400
            self._path = urllib.unquote(self._path[1:])
392
401
 
393
402
    def _sftp_connect(self):
394
403
        global SYSTEM_HOSTKEYS, BZR_HOSTKEYS