~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/urlutils.py

  • Committer: John Ferlito
  • Date: 2009-09-02 04:31:45 UTC
  • mto: (4665.7.1 serve-init)
  • mto: This revision was merged to the branch mainline in revision 4913.
  • Revision ID: johnf@inodes.org-20090902043145-gxdsfw03ilcwbyn5
Add a debian init script for bzr --serve

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Bazaar -- distributed version control
2
 
#
3
 
# Copyright (C) 2006 Canonical Ltd
 
1
# Copyright (C) 2006, 2008 Canonical Ltd
4
2
#
5
3
# This program is free software; you can redistribute it and/or modify
6
4
# it under the terms of the GNU General Public License as published by
14
12
#
15
13
# You should have received a copy of the GNU General Public License
16
14
# along with this program; if not, write to the Free Software
17
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
16
 
19
17
"""A collection of function for handling URL operations."""
20
18
 
68
66
        relpath = relpath.encode('utf-8')
69
67
    # After quoting and encoding, the path should be perfectly
70
68
    # safe as a plain ASCII string, str() just enforces this
71
 
    return str(urllib.quote(relpath))
 
69
    return str(urllib.quote(relpath, safe='/~'))
72
70
 
73
71
 
74
72
def file_relpath(base, path):
75
73
    """Compute just the relative sub-portion of a url
76
 
    
 
74
 
77
75
    This assumes that both paths are already fully specified file:// URLs.
78
76
    """
79
77
    if len(base) < MIN_ABS_FILEURL_LENGTH:
80
 
        raise ValueError('Length of base must be equal or'
 
78
        raise ValueError('Length of base (%r) must equal or'
81
79
            ' exceed the platform minimum url length (which is %d)' %
82
 
            MIN_ABS_FILEURL_LENGTH)
 
80
            (base, MIN_ABS_FILEURL_LENGTH))
83
81
    base = local_path_from_url(base)
84
82
    path = local_path_from_url(path)
85
83
    return escape(osutils.relpath(base, path))
185
183
 
186
184
def joinpath(base, *args):
187
185
    """Join URL path segments to a URL path segment.
188
 
    
 
186
 
189
187
    This is somewhat like osutils.joinpath, but intended for URLs.
190
188
 
191
189
    XXX: this duplicates some normalisation logic, and also duplicates a lot of
230
228
 
231
229
    This also handles transforming escaping unicode characters, etc.
232
230
    """
233
 
    # importing directly from posixpath allows us to test this 
 
231
    # importing directly from posixpath allows us to test this
234
232
    # on non-posix platforms
235
233
    return 'file://' + escape(_posix_normpath(
236
234
        osutils._posix_abspath(path)))
254
252
    # allow empty paths so we can serve all roots
255
253
    if win32_url == '///':
256
254
        return '/'
257
 
    
 
255
 
258
256
    # usual local path with drive letter
259
257
    if (win32_url[3] not in ('abcdefghijklmnopqrstuvwxyz'
260
258
                             'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
270
268
 
271
269
    This also handles transforming escaping unicode characters, etc.
272
270
    """
273
 
    # importing directly from ntpath allows us to test this 
 
271
    # importing directly from ntpath allows us to test this
274
272
    # on non-win32 platform
275
273
    # FIXME: It turns out that on nt, ntpath.abspath uses nt._getfullpathname
276
274
    #       which actually strips trailing space characters.
305
303
 
306
304
def _unescape_safe_chars(matchobj):
307
305
    """re.sub callback to convert hex-escapes to plain characters (if safe).
308
 
    
 
306
 
309
307
    e.g. '%7E' will be converted to '~'.
310
308
    """
311
309
    hex_digits = matchobj.group(0)[1:]
318
316
 
319
317
def normalize_url(url):
320
318
    """Make sure that a path string is in fully normalized URL form.
321
 
    
 
319
 
322
320
    This handles URLs which have unicode characters, spaces,
323
321
    special characters, etc.
324
322
 
370
368
    dummy, base_first_slash = _find_scheme_and_separator(base)
371
369
    if base_first_slash is None:
372
370
        return other
373
 
    
 
371
 
374
372
    dummy, other_first_slash = _find_scheme_and_separator(other)
375
373
    if other_first_slash is None:
376
374
        return other
418
416
    # Strip off the drive letter
419
417
    # path is currently /C:/foo
420
418
    if len(path) < 3 or path[2] not in ':|' or path[3] != '/':
421
 
        raise errors.InvalidURL(url_base + path, 
 
419
        raise errors.InvalidURL(url_base + path,
422
420
            'win32 file:/// paths need a drive letter')
423
421
    url_base += path[0:3] # file:// + /C:
424
422
    path = path[3:] # /foo
432
430
    :param exclude_trailing_slash: Strip off a final '/' if it is part
433
431
        of the path (but not if it is part of the protocol specification)
434
432
 
435
 
    :return: (parent_url, child_dir).  child_dir may be the empty string if we're at 
 
433
    :return: (parent_url, child_dir).  child_dir may be the empty string if we're at
436
434
        the root.
437
435
    """
438
436
    scheme_loc, first_path_slash = _find_scheme_and_separator(url)
542
540
# These are characters that if escaped, should stay that way
543
541
_no_decode_chars = ';/?:@&=+$,#'
544
542
_no_decode_ords = [ord(c) for c in _no_decode_chars]
545
 
_no_decode_hex = (['%02x' % o for o in _no_decode_ords] 
 
543
_no_decode_hex = (['%02x' % o for o in _no_decode_ords]
546
544
                + ['%02X' % o for o in _no_decode_ords])
547
545
_hex_display_map = dict(([('%02x' % o, chr(o)) for o in range(256)]
548
546
                    + [('%02X' % o, chr(o)) for o in range(256)]))
574
572
    This will turn file:// urls into local paths, and try to decode
575
573
    any portions of a http:// style url that it can.
576
574
 
577
 
    Any sections of the URL which can't be represented in the encoding or 
 
575
    Any sections of the URL which can't be represented in the encoding or
578
576
    need to stay as escapes are left alone.
579
577
 
580
578
    :param url: A 7-bit ASCII URL
581
579
    :param encoding: The final output encoding
582
580
 
583
 
    :return: A unicode string which can be safely encoded into the 
 
581
    :return: A unicode string which can be safely encoded into the
584
582
         specified encoding.
585
583
    """
586
584
    if encoding is None:
687
685
    if len(segments) == 0:
688
686
        return '.'
689
687
    return osutils.pathjoin(*segments)
 
688
 
 
689
 
 
690
 
 
691
def parse_url(url):
 
692
    """Extract the server address, the credentials and the path from the url.
 
693
 
 
694
    user, password, host and path should be quoted if they contain reserved
 
695
    chars.
 
696
 
 
697
    :param url: an quoted url
 
698
 
 
699
    :return: (scheme, user, password, host, port, path) tuple, all fields
 
700
        are unquoted.
 
701
    """
 
702
    if isinstance(url, unicode):
 
703
        raise errors.InvalidURL('should be ascii:\n%r' % url)
 
704
    url = url.encode('utf-8')
 
705
    (scheme, netloc, path, params,
 
706
     query, fragment) = urlparse.urlparse(url, allow_fragments=False)
 
707
    user = password = host = port = None
 
708
    if '@' in netloc:
 
709
        user, host = netloc.rsplit('@', 1)
 
710
        if ':' in user:
 
711
            user, password = user.split(':', 1)
 
712
            password = urllib.unquote(password)
 
713
        user = urllib.unquote(user)
 
714
    else:
 
715
        host = netloc
 
716
 
 
717
    if ':' in host and not (host[0] == '[' and host[-1] == ']'): #there *is* port
 
718
        host, port = host.rsplit(':',1)
 
719
        try:
 
720
            port = int(port)
 
721
        except ValueError:
 
722
            raise errors.InvalidURL('invalid port number %s in url:\n%s' %
 
723
                                    (port, url))
 
724
    if host != "" and host[0] == '[' and host[-1] == ']': #IPv6
 
725
        host = host[1:-1]
 
726
 
 
727
    host = urllib.unquote(host)
 
728
    path = urllib.unquote(path)
 
729
 
 
730
    return (scheme, user, password, host, port, path)