o
    Åîï]ªF  ã                
   @   s´  d 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hZedd„ eD ƒB Zdd„ Zdd„ Z dd„ Z!dd„ Z"d-dd„Z#d.d!d"„Z$efd#d$„Z%e &d%e 'd&¡ d' ¡Z(e)g d(¢ƒZ*ed dd dfd)d*„Z+e,d+krØddl-Z-ddl.Z.ze- -e+e.j/d, ƒ¡ W n eyÐ Z0 z
e1e0ƒ W Y dZ0[0ndZ0[0ww e. 2d¡ dS dS )/z*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://i‰i  c                 C   s\   d| v s|   d¡dkrtrd}nd}td| ƒ‚|  d¡\}}}|s&t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   )ÚuserinfoÚquote_fnÚuserÚ_Úpasswd© r   úD/var/www/html/env/lib/python3.10/site-packages/pymongo/uri_parser.pyÚparse_userinfo)   s   ÿr   c                 C   sT   |   d¡dkrtdƒ‚|   d¡}|dkr| 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.
    ú]éÿÿÿÿzNan IPv6 address literal must be enclosed in '[' and ']' according to RFC 2732.z]:r   é   N)ÚfindÚ
ValueError)ÚentityÚdefault_portÚir   r   r   Úparse_ipv6_literal_hostE   s   
r"   c                 C   s¶   | }|}| d dkrt | |ƒ\}}n#|  d¡r| |fS |  d¡dkr5|  d¡dkr-tdƒ‚| dd¡\}}t|tƒrU| ¡ rJt	|ƒdksJt	|ƒdkrQtd	|f ƒ‚t	|ƒ}| 
¡ |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   ú[ú.sockr   r   r   z’Reserved 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: %s)r"   Úendswithr   r   r   ÚsplitÚ
isinstancer   ÚisdigitÚintÚlower)r   r    ÚhostÚportr   r   r   Ú
parse_host[   s"   

 ÿr-   ÚtlsallowinvalidcertificatesÚtlsallowinvalidhostnamesc                 C   s   h | ]}t | ’qS r   )r   )Ú.0Úkr   r   r   Ú	<setcomp>…   s    r2   c                 C   sl   t ƒ }|  |¡D ]+}| d¡\}}| ¡ dkr!| |g ¡ |¡ q||v r-t d|f ¡ t|ƒ||< q|S )zÆHelper 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.ú=ÚreadpreferencetagszDuplicate URI option '%s'.)r   r&   r*   Ú
setdefaultÚappendÚwarningsÚwarnr   )ÚoptsÚdelimÚoptionsÚurioptÚkeyÚvaluer   r   r   Ú_parse_options‰   s   r?   c                 C   sœ   |   d¡}|dur"tD ]}|| v r!d}t||  d¡|  |¡f ƒ‚qd| v rLd| v rLdd„ }||   d¡ƒ||   d¡ƒkrLd}t||  d¡|  d¡f ƒ‚| S )	zÝRaise 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.ÚsslÚtlsc                 S   s"   | dv r| dkS t | tƒr| S | S )N)ÚtrueÚfalserC   )r'   Úbool)Úvalr   r   r   Útruth_value¬   s
   
z-_handle_security_options.<locals>.truth_valuez=Can not specify conflicting values for URI options %s and %s.)ÚgetÚ_TLSINSECURE_EXCLUDE_OPTSr
   Ú	cased_key)r;   r@   ÚoptÚerr_msgrG   r   r   r   Ú_handle_security_optionsš   s"   
ÿýÿrM   c                 C   s¼   t | ƒD ]W}|tv r[t| \}}|dkrF|}|| v r4d}tj||  |¡|  |¡f tdd� |  |¡ qd}tj||  |¡|f tdd� q|dkr[d}tj||  |¡|f tdd� q| 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.
    Úrenamedz0Deprecated option '%s' ignored in favor of '%s'.r   )Ú
stacklevelz,Option '%s' is deprecated, use '%s' instead.ÚremovedzOption '%s' is deprecated. %s.)Úlistr   r7   r8   rJ   ÚDeprecationWarningÚpop)r;   ÚoptnameÚmodeÚmessageÚ
newoptnameÚwarn_msgr   r   r   Ú_handle_option_deprecations»   s8   	
ÿý
þþ€rY   c                 C   sf   |   d¡}|durtD ]}t  |d¡}| | |< qt| ƒD ]}t  |d¡}|dur0|  |¡| |< q| 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)rH   Ú_IMPLICIT_TLSINSECURE_OPTSr   rQ   rS   )r;   r@   rK   ÚintnamerT   r   r   r   Ú_normalize_optionsß   s   
€r\   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   )r9   r8   r   r   r   Úvalidate_optionsö   s   
r]   Tc                 C   s¼   |   d¡}|   d¡}z1|dkr|dkrtdƒ‚|dkr!t| dƒ}n|dkr+t| dƒ}n|   d¡dkr8t| dƒ}nt‚W n tyF   tdƒ‚w t|ƒ}t|ƒ}|rVt||ƒ}|r\t|ƒ}|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.r3   r   Nz(MongoDB URI options are key=value pairs.)r   r
   r?   r   rM   rY   r]   r\   )r9   Úvalidater8   Ú	normalizeÚand_idxÚsemi_idxr;   r   r   r   Úsplit_options  s.   

€ÿ
rd   c                 C   sF   g }|   d¡D ]}|stdƒ‚|}| d¡rd}| t||ƒ¡ q|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).r$   N)r&   r	   r%   r6   r-   )Úhostsr    Únodesr   r,   r   r   r   Úsplit_hosts0  s   
rh   r#   z/ "$r   )Ú
authsourceÚ
authSourceÚ
replicasetÚ
replicaSetc                 C   s”  |   t¡rd}| td… }n|   t¡r"tstdƒ‚d}| td… }ntdttf ƒ‚|s0tdƒ‚d}d}	d}
d}tƒ }| 	d¡\}}}|sI|}d}|sSd	|v rStd
ƒ‚|r’|d d	krdt
|dd… ƒ}n"tt
| 	d	¡ƒ\}
}}d|
v r{|
 dd¡\}
}t |
¡r†td|
 ƒ‚|r’| t||||ƒ¡ |
duršt
|
ƒ}
|dur¢t
|ƒ}d|v rµ| d¡\}}}t|ƒ\}}	n|}d|v rÁtd| ƒ‚t
|ƒ}d}|�r:t|dd�}t|ƒdkrÝtdtf ƒ‚|d \}}|durîtdtf ƒ‚|pô| d¡}t||d�}| ¡ }| ¡ }|�r+t||||ƒ}t|ƒt �rtdƒ‚| ¡ D ]\}}||v�r)|||< �qd|v�r9|�r5dnd|d< nt||d�}|||	|
|||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.
    FNzCThe "dnspython" module must be installed to use mongodb+srv:// URIsTz4Invalid URI scheme: URI must begin with '%s' or '%s'z)Must provide at least one hostname or IP.ú/Ú ú?z8A '/' is required between the host list and any options.r   r   Ú.zBad database name "%s"r   z;Any '/' in a unix domain socket must be percent-encoded: %s)r    z0%s URIs must include one, and only one, hostnamez&%s URIs must not include a port numberÚconnectTimeoutMS)Úconnect_timeoutz5Only authSource and replicaSet are supported from DNSrA   rC   )ÚnodelistÚusernameÚpasswordÚdatabaseÚ
collectionr;   Úfqdn)Ú
startswithÚSCHEMEÚ
SCHEME_LENÚ
SRV_SCHEMEr   r	   ÚSRV_SCHEME_LENr
   r   r   r   Úmapr&   Ú_BAD_DB_CHARSÚsearchÚupdaterd   Ú
rpartitionr   rh   ÚlenrH   r   Ú	get_hostsÚget_optionsÚsetÚ_ALLOWED_TXT_OPTSÚitems)Úurir    r`   r8   ra   rr   Úis_srvÚscheme_freer   r   Údbaserw   r;   Ú	host_partr   Ú	path_partr9   r   rf   rx   rg   r,   Údns_resolverÚdns_optionsÚparsed_dns_optionsrK   rF   r   r   r   Ú	parse_uriR  s²   
/
ÿ
ÿÿÿÿÿÿ
€
€ùr’   Ú__main__r   )F)TFT)3Ú__doc__Úrer7   Úbson.py3compatr   r   Úurllib.parser   ÚurllibÚpymongo.commonr   r   r   r   Úpymongo.errorsr	   r
   Úpymongo.srv_resolverr   r   rz   rƒ   r{   r|   r}   ÚDEFAULT_PORTr   r"   r-   rZ   rI   r?   rM   rY   r\   r]   rd   rh   ÚcompileÚescaper   Ú	frozensetr‡   r’   Ú__name__ÚpprintÚsysÚargvÚexcÚprintÚexitr   r   r   r   Ú<module>   sh   &ÿÿÿ!$

*ÿ
ÿ €ÿù