Example #1
0
def parse_dbase_from_uri(uri):
    """A simplified version of pymongo.uri_parser.parse_uri to get the dbase.

    Returns a string representing the database provided in the URI or None if
    no database is provided in the URI.

    An invalid MongoDB connection URI may raise an InvalidURI exception,
    however, the URI is not fully parsed and some invalid URIs may not result
    in an exception.

    "mongodb://host1/database" becomes "database"

    and

    "mongodb://host1" becomes None
    """
    SCHEME = "mongodb://"

    if not uri.startswith(SCHEME):
        raise InvalidURI("Invalid URI scheme: URI "
                         "must begin with '%s'" % (SCHEME, ))

    scheme_free = uri[len(SCHEME):]

    if not scheme_free:
        raise InvalidURI("Must provide at least one hostname or IP.")

    dbase = None

    # Check for unix domain sockets in the uri
    if '.sock' in scheme_free:
        host_part, _, path_part = scheme_free.rpartition('/')
        if not host_part:
            host_part = path_part
            path_part = ""
        if '/' in host_part:
            raise InvalidURI("Any '/' in a unix domain socket must be"
                             " URL encoded: %s" % host_part)
        path_part = unquote_plus(path_part)
    else:
        host_part, _, path_part = scheme_free.partition('/')

    if not path_part and '?' in host_part:
        raise InvalidURI("A '/' is required between "
                         "the host list and any options.")

    if path_part:
        if path_part[0] == '?':
            opts = path_part[1:]
        else:
            dbase, _, opts = path_part.partition('?')
            if '.' in dbase:
                dbase, _ = dbase.split('.', 1)

    if dbase is not None:
        dbase = unquote_plus(dbase)

    return dbase
Example #2
0
def _parse_host_and_port(uri, default_port=27017):
    """A simplified version of pymongo.uri_parser.parse_uri to get the dbase.

    Returns a tuple of the main host and the port provided in the URI.

    An invalid MongoDB connection URI may raise an InvalidURI exception,
    however, the URI is not fully parsed and some invalid URIs may not result
    in an exception.
    """
    if '://' not in uri:
        return uri, default_port

    uri = uri.split('://', 1)[1]

    if '/' in uri:
        uri = uri.split('/', 1)[0]

    # TODO(pascal): Handle replica sets better. Accessing the secondary hosts
    # should reach the same dataas the primary.
    if ',' in uri:
        uri = uri.split(',', 1)[0]

    if ']:' in uri:
        host, uri = uri.split(']:', 1)
        host = host + ']'
    elif ':' in uri and not uri.endswith(']'):
        host, uri = uri.split(':', 1)
    else:
        return uri, default_port

    if not uri:
        return uri, default_port

    try:
        return host, int(uri)
    except ValueError:
        raise InvalidURI('Invalid URI scheme: could not parse port "%s"' % uri)
Example #3
0
def parse_uri(uri, default_port=27017, warn=False):
    """A simplified version of pymongo.uri_parser.parse_uri.

    Returns a dict with:
     - nodelist, a tuple of (host, port)
     - database the name of the database or None if no database is provided in the URI.

    An invalid MongoDB connection URI may raise an InvalidURI exception,
    however, the URI is not fully parsed and some invalid URIs may not result
    in an exception.

    'mongodb://host1/database' becomes 'host1', 27017, 'database'

    and

    'mongodb://host1' becomes 'host1', 27017, None
    """
    SCHEME = 'mongodb://'

    if not uri.startswith(SCHEME):
        raise InvalidURI('Invalid URI scheme: URI '
                         "must begin with '%s'" % (SCHEME, ))

    scheme_free = uri[len(SCHEME):]

    if not scheme_free:
        raise InvalidURI('Must provide at least one hostname or IP.')

    dbase = None

    # Check for unix domain sockets in the uri
    if '.sock' in scheme_free:
        host_part, _, path_part = scheme_free.rpartition('/')
        if not host_part:
            host_part = path_part
            path_part = ''
        if '/' in host_part:
            raise InvalidURI("Any '/' in a unix domain socket must be"
                             ' URL encoded: %s' % host_part)
        path_part = unquote_plus(path_part)
    else:
        host_part, _, path_part = scheme_free.partition('/')

    if not path_part and '?' in host_part:
        raise InvalidURI("A '/' is required between "
                         'the host list and any options.')

    nodelist = []
    if ',' in host_part:
        hosts = host_part.split(',')
    else:
        hosts = [host_part]
    for host in hosts:
        match = _HOST_MATCH.match(host)
        if not match:
            raise ValueError(
                "Reserved characters such as ':' must be escaped according RFC "
                "2396. An IPv6 address literal must be enclosed in '[' and ']' "
                'according to RFC 2732.')
        host = match.group(2)
        if host.startswith('[') and host.endswith(']'):
            host = host[1:-1]

        port = match.group(4)
        if port:
            try:
                port = int(port)
                if port < 0 or port > 65535:
                    raise ValueError()
            except ValueError:
                raise ValueError(
                    'Port must be an integer between 0 and 65535:', port)
        else:
            port = default_port

        nodelist.append((host, port))

    if path_part and path_part[0] != '?':
        dbase, _, _ = path_part.partition('?')
        if '.' in dbase:
            dbase, _ = dbase.split('.', 1)

    if dbase is not None:
        dbase = unquote_plus(dbase)

    return {'nodelist': tuple(nodelist), 'database': dbase}