3
O6bqQ                 @   s  d Z ddlZddlZddlZddlmZmZ er>ddlmZ nddl	mZ ddl
mZmZmZmZ ddlmZmZ ddlmZmZ dZeeZd	ZeeZd
Zdd Zdd ZefddZdddhZdd eD dd eD B Zdd Z dd Z!dd Z"dd Z#d6d d!Z$d7d#d$Z%efd%d&Z&ej'd'ej(d( d) Z)e*d*d+d,d-d.d/gZ+d0d1 Z,ed"dd"dfd2d3Z-e.d4krddl/Z/ddlZye/j/e-ej0d5  W n, ek
r Z1 ze2e1 W Y ddZ1[1X nX ej3d dS )8z*Tools to parse and validate a MongoDB URI.    N)string_typePY3)unquote_plus)get_validated_optionsINTERNAL_URI_OPTION_NAME_MAPURI_OPTIONS_DEPRECATION_MAP_CaseInsensitiveDictionary)ConfigurationError
InvalidURI)_HAVE_DNSPYTHON_SrvResolverz
mongodb://zmongodb+srv://ii  c             C   s\   d| ks| j ddkr0tr d}nd}td| | jd\}}}|sLtdt|t|fS )a  Validates the format of user information in a MongoDB URI.
    Reserved characters like ':', '/', '+' and '@' must be escaped
    following RFC 3986.

    Returns a 2-tuple containing the unescaped username followed
    by the unescaped password.

    :Paramaters:
        - `userinfo`: A string of the form <username>:<password>

    .. versionchanged:: 2.2
       Now uses `urllib.unquote_plus` so `+` characters must be escaped.
    @:   zurllib.parse.quote_pluszurllib.quote_pluszFUsername and password must be escaped according to RFC 3986, use %s().z'The empty string is not valid username.)countr   r
   	partitionr   )userinfoZquote_fnuser_passwd r   Q/var/www/html/sandeepIITI/myenv/lib/python3.6/site-packages/pymongo/uri_parser.pyparse_userinfo*   s    r   c             C   sT   | j ddkrtd| j d}|dkr8| dd	 |fS | d| | |d d fS )
a  Validates an IPv6 literal host:port string.

    Returns a 2-tuple of IPv6 literal followed by port where
    port is default_port if it wasn't specified in entity.

    :Parameters:
        - `entity`: A string that represents an IPv6 literal enclosed
                    in braces (e.g. '[::1]' or '[::1]:27017').
        - `default_port`: The port number to use when one wasn't
                          specified in entity.
    ]r   zNan IPv6 address literal must be enclosed in '[' and ']' according to RFC 2732.z]:   Nr   r   )find
ValueError)entitydefault_portir   r   r   parse_ipv6_literal_hostF   s    
r!   c             C   s   | }|}| d dkr$t | |\}}nF| jdr6| |fS | jdd	krj| jddkrZtd|jdd\}}t|tr|j  st	|dkst	|dkrtd|f t	|}|j
 |fS )
a  Validates a host string

    Returns a 2-tuple of host followed by port where port is default_port
    if it wasn't specified in the string.

    :Parameters:
        - `entity`: A host or host:port string where host could be a
                    hostname or IP address.
        - `default_port`: The port number to use when one wasn't
                          specified in entity.
    r   [z.sockr   r   zReserved characters such as ':' must be escaped according RFC 2396. An IPv6 address literal must be enclosed in '[' and ']' according to RFC 2732.i  z/Port must be an integer between 0 and 65535: %sr   )r!   endswithr   r   r   split
isinstancer   isdigitintlower)r   r   hostportr   r   r   
parse_host\   s     

"
r+   tlsallowinvalidcertificatesZtlsallowinvalidhostnamestlsdisableocspendpointcheckc             C   s   h | ]}|qS r   r   ).0kr   r   r   	<setcomp>   s    r0   c             C   s   h | ]}t | qS r   )r   )r.   r/   r   r   r   r0      s    c             C   s   t  }xz| j|D ]l}|jd\}}|j dkrD|j|g j| q||kr\tjd|f  |j dkrn|}nt|}|||< qW |S )zHelper method for split_options which creates the options dict.
    Also handles the creation of a list for the URI tag_sets/
    readpreferencetags portion, and the use of a unicode options string.=ZreadpreferencetagszDuplicate URI option '%s'.Zauthmechanismproperties)r   r$   r(   
setdefaultappendwarningswarnr   )optsdelimoptionsZurioptkeyvaluevalr   r   r   _parse_options   s    r<   c                s0   j d}|dk	rHx4tD ],}| krd}t| jd j|f qW  fdd}|d}|dk	rd krd}t|d jdf |dkrd d< |d	}|dk	rx,dD ]$} j |dkrd
}t||f qW d kod kr,dd }| j d| j dkr,d}t| jd jdf  S )zRaise appropriate errors when conflicting TLS options are present in
    the options dictionary.

    :Parameters:
        - `options`: Instance of _CaseInsensitiveDictionary containing
          MongoDB URI options.
    tlsinsecureNz9URI options %s and %s cannot be specified simultaneously.c                s    j | p j t|  S )N)getr   )opt)r8   r   r   _getopt   s    
z)_handle_security_options.<locals>._getoptr,   r-   T
tlscrlfilezDURI option %s=True cannot be specified when CRL checking is enabled.sslZtlsc             S   s"   | dkr| dkS t | tr| S | S )Ntruefalse)rC   rD   )r%   bool)r;   r   r   r   truth_value   s
    
z-_handle_security_options.<locals>.truth_valuez=Can not specify conflicting values for URI options %s and %s.)r=   r,   r-   )r>   _TLSINSECURE_EXCLUDE_OPTSr
   	cased_key)r8   r=   r?   err_msgr@   ZtlsallowinvalidcertsrA   rF   r   )r8   r   _handle_security_options   s>    

rJ   c             C   s   xt | D ]}|tkr
t| \}}|dkr|}|| krjd}tj|| j|| j|f tdd | j| q
d}tj|| j||f tdd q
|dkr
d}tj|| j||f tdd q
W | S )aM  Issue appropriate warnings when deprecated options are present in the
    options dictionary. Removes deprecated option key, value pairs if the
    options dictionary is found to also have the renamed option.

    :Parameters:
        - `options`: Instance of _CaseInsensitiveDictionary containing
          MongoDB URI options.
    Zrenamedz0Deprecated option '%s' ignored in favor of '%s'.r   )
stacklevelz,Option '%s' is deprecated, use '%s' instead.removedzOption '%s' is deprecated. %s.)listr   r4   r5   rH   DeprecationWarningpop)r8   optnamemodemessageZ
newoptnameZwarn_msgr   r   r   _handle_option_deprecations   s.    	


rS   c             C   sj   | j d}|dk	r2xtD ]}t| }| | |< qW x2t| D ]&}tj |d}|dk	r<| j|| |< q<W | S )a  Normalizes option names in the options dictionary by converting them to
    their internally-used names. Also handles use of the tlsInsecure option.

    :Parameters:
        - `options`: Instance of _CaseInsensitiveDictionary containing
          MongoDB URI options.
    r=   N)r>   _IMPLICIT_TLSINSECURE_OPTSr   rM   rO   )r8   r=   r?   ZintnamerP   r   r   r   _normalize_options  s    

rU   Fc             C   s
   t | |S )a  Validates and normalizes options passed in a MongoDB URI.

    Returns a new dictionary of validated and normalized options. If warn is
    False then errors will be thrown for invalid options, otherwise they will
    be ignored and a warning will be issued.

    :Parameters:
        - `opts`: A dict of MongoDB URI options.
        - `warn` (optional): If ``True`` then warnings will be logged and
          invalid options will be ignored. Otherwise invalid options will
          cause errors.
    )r   )r6   r5   r   r   r   validate_options  s    rV   Tc             C   s   | j d}| j d}yd|dkr0|dkr0tdnF|dkrDt| d}n2|dkrXt| d}n| j ddkrrt| d}ntW n tk
r   tdY nX t|}t|}|rt||}|jd	d
krtd|rt|}|S )a  Takes the options portion of a MongoDB URI, validates each option
    and returns the options in a dictionary.

    :Parameters:
        - `opt`: A string representing MongoDB URI options.
        - `validate`: If ``True`` (the default), validate and normalize all
          options.
        - `warn`: If ``False`` (the default), suppress all warnings raised
          during validation of options.
        - `normalize`: If ``True`` (the default), renames all options to their
          internally-used names.
    &;r   z.Can not mix '&' and ';' for option separators.r1   r   Nz(MongoDB URI options are key=value pairs.
authsource z1the authSource database cannot be an empty stringr   )	r   r
   r<   r   rJ   rS   rV   r>   rU   )r6   validater5   	normalizeZand_idxZsemi_idxr8   r   r   r   split_options*  s0    



r]   c             C   sJ   g }x@| j dD ]2}|s td|}|jdr2d}|jt|| qW |S )a  Takes a string of the form host1[:port],host2[:port]... and
    splits it into (host, port) tuples. If [:port] isn't present the
    default_port is used.

    Returns a set of 2-tuples containing the host name (or IP) followed by
    port number.

    :Parameters:
        - `hosts`: A string of the form host1[:port],host2[:port],...
        - `default_port`: The port number to use when one wasn't specified
          for a host.
    ,z)Empty host (or extra comma in host list).z.sockN)r$   r	   r#   r3   r+   )hostsr   nodesr   r*   r   r   r   split_hostsW  s    
ra   r"   z/ "$r   rY   Z
authSource
replicasetZ
replicaSetloadbalancedZloadBalancedc             C   sd   t | dkr|jdrtd|jdr`t | dkr<td|jdrNtd|jdr`tdd S )	Nr   Zdirectconnectionz8Cannot specify multiple hosts with directConnection=truerc   z4Cannot specify multiple hosts with loadBalanced=truez;Cannot specify directConnection=true with loadBalanced=truerb   z0Cannot specify replicaSet with loadBalanced=true)lenr>   r	   )r`   r8   r   r   r   _check_optionsz  s    


re   c             C   s  | j trd}| td }nF| j trRts@tjp2d}td| d}| td }nt	dttf |snt	dd}	d}
d}d}t
 }|jd\}}}|s|}d	}| rd
|krt	d|r*|jd
\}}}|rt|}d|kr|jdd\}}tj|rt	d| nd}|r*|jt|||| d|krR|jd\}}}t|\}	}
n|}d|krlt	d| t|}d}|r|jdrtdtf t|dd}t|dkrt	dtf |d \}}|dk	rt	dtf |p|jd}t||d}|j }|j }|rdt||||}t|t r:tdx(|j D ]\}}||krD|||< qDW d|kr|rxdnd|d< nt||d}t|| ||	|
||||dS )a  Parse and validate a MongoDB URI.

    Returns a dict of the form::

        {
            'nodelist': <list of (host, port) tuples>,
            'username': <username> or None,
            'password': <password> or None,
            'database': <database name> or None,
            'collection': <collection name> or None,
            'options': <dict of MongoDB URI options>,
            'fqdn': <fqdn of the MongoDB+SRV URI> or None
        }

    If the URI scheme is "mongodb+srv://" DNS SRV and TXT lookups will be done
    to build nodelist and options.

    :Parameters:
        - `uri`: The MongoDB URI to parse.
        - `default_port`: The port number to use when one wasn't specified
          for a host in the URI.
        - `validate` (optional): If ``True`` (the default), validate and
          normalize all options. Default: ``True``.
        - `warn` (optional): When validating, if ``True`` then will warn
          the user then ignore any invalid options or values. If ``False``,
          validation will error when options are unsupported or values are
          invalid. Default: ``False``.
        - `normalize` (optional): If ``True``, convert names of URI options
          to their internally-used names. Default: ``True``.
        - `connect_timeout` (optional): The maximum time in milliseconds to
          wait for a response from the DNS server.

    .. versionchanged:: 3.9
        Added the ``normalize`` parameter.

    .. versionchanged:: 3.6
        Added support for mongodb+srv:// URIs.

    .. versionchanged:: 3.5
        Return the original value of the ``readPreference`` MongoDB URI option
        instead of the validated read preference mode.

    .. versionchanged:: 3.1
        ``warn`` added so invalid options can be ignored.
    FNpythonzThe "dnspython" module must be installed to use mongodb+srv:// URIs. To fix this error install pymongo with the srv extra:
 %s -m pip install "pymongo[srv]"Tz4Invalid URI scheme: URI must begin with '%s' or '%s'z)Must provide at least one hostname or IP./rZ   ?z8A '/' is required between the host list and any options..r   zBad database name "%s"r   z;Any '/' in a unix domain socket must be percent-encoded: %sZdirectConnectionz1Cannot specify directConnection=true with %s URIs)r   z0%s URIs must include one, and only one, hostnamer   z&%s URIs must not include a port numberZconnectTimeoutMS)connect_timeoutzDOnly authSource, replicaSet, and loadBalanced are supported from DNSrB   rC   )ZnodelistusernamepasswordZdatabase
collectionr8   fqdn)
startswithSCHEME
SCHEME_LEN
SRV_SCHEMEr   sys
executabler	   SRV_SCHEME_LENr
   r   r   r   r$   _BAD_DB_CHARSsearchupdater]   
rpartitionr   r>   ra   rd   r   Z	get_hostsZget_optionsset_ALLOWED_TXT_OPTSitemsre   )urir   r[   r5   r\   rj   Zis_srvZscheme_freeZpython_pathr   r   Zdbaserm   r8   Z	host_partr   Z	path_partr6   r   r_   rn   r`   r*   Zdns_resolverZdns_optionsZparsed_dns_optionsr?   r;   r   r   r   	parse_uri  s    /










r~   __main__r   )F)TFT)4__doc__rer4   rs   Zbson.py3compatr   r   urllib.parser   urllibZpymongo.commonr   r   r   r   Zpymongo.errorsr	   r
   Zpymongo.srv_resolverr   r   rp   rd   rq   rr   ru   ZDEFAULT_PORTr   r!   r+   rT   rG   r<   rJ   rS   rU   rV   r]   ra   compileescaperv   	frozensetr{   re   r~   __name__pprintargvexcprintexitr   r   r   r   <module>   s\   (<$

-
 
