U
    dd>                  
   @   s  d Z ddlZddlZddlZddlZddlmZ dZdZdZ	e
dZe
d	jd
dddddZe
djddddZe
d
e
de
de
de
de
de
de
ddZe
dZe
dZG dd dejZd3eeje edddZeedddZejejeef  eeje d d!d"Zeeedd#d$d%Zeed&d'd(Zeed)d*d+Zd4eeed-d.d/Zej ej!eef  ed0d1d2Z"dS )5a  
An implementation of `urlparse` that provides URL validation and normalization
as described by RFC3986.

We rely on this implementation rather than the one in Python's stdlib, because:

* It provides more complete URL validation.
* It properly differentiates between an empty querystring and an absent querystring,
  to distinguish URLs with a trailing '?'.
* It handles scheme, hostname, port, and path normalization.
* It supports IDNA hostnames, normalizing them to their encoded form.
* The API supports passing individual components, as well as the complete URL string.

Previously we relied on the excellent `rfc3986` package to handle URL parsing and
validation, but this module provides a simpler alternative, with less indirection
required.
    N   )
InvalidURLi   zBABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~z!$&'()*+,;=z%[A-Fa-f0-9]{2}z(?:(?P<scheme>{scheme}):)?(?://(?P<authority>{authority}))?(?P<path>{path})(?:\?(?P<query>{query}))?(?:#(?P<fragment>{fragment}))?z([a-zA-Z][a-zA-Z0-9+.-]*)?z[^/?#]*z[^?#]*z[^#]*z.*scheme	authoritypathqueryfragmentzA(?:(?P<userinfo>{userinfo})@)?(?P<host>{host}):?(?P<port>{port})?z[^@]*z(\[.*\]|[^:]*))userinfohostport)r   r   r   r   r	   r
   r   r   z^[0-9]+.[0-9]+.[0-9]+.[0-9]+$z^\[.*\]$c                   @   s   e Zd ZU eed< eed< eed< eje ed< eed< eje ed< eje ed< eedd	d
Z	eedddZ
eje d dddZedddZdS )ParseResultr   r
   r   r   r   r   r	   )returnc                 C   sR   d | jr| j dndd| jkr0d| j dn| j| jd k	rJd| j ndgS )N @:[])joinr
   r   r   self r   3/tmp/pip-unpacked-wheel-fkuvgui5/httpx/_urlparse.pyr   g   s    zParseResult.authorityc                 C   s>   d d| jkrd| j dn| j| jd k	r6d| j ndgS )Nr   r   r   r   )r   r   r   r   r   r   r   netlocq   s
    zParseResult.netloc)kwargsr   c                 K   s6   |s| S | j | j| j| j| jd}|| td|S )Nr   r   )r   )r   r   r   r   r	   updateurlparse)r   r   defaultsr   r   r   	copy_withz   s    
zParseResult.copy_withc                 C   sh   | j }d| jr| j dnd|r,d| nd| j| jd k	rHd| j nd| jd k	r`d| j ndgS )Nr   r   //?#)r   r   r   r   r   r	   )r   r   r   r   r   __str__   s    zParseResult.__str__N)__name__
__module____qualname__str__annotations__typingOptionalintpropertyr   r   r   r"   r   r   r   r   r   ^   s   
	r   r   )urlr   r   c                 K   s  t | tkrtdtdd | D r.tdd|krX|d }t|trPt|n||d< d|kr|dpld}|d\|d	< }|d< d
|ksd|krt	|d
dpd}t	|ddpd}|r| d| n||d< d|kr|dpd}|d\|d< }|d< |sd |d< d	|krb|
d	p.d}	d|	krb|	drR|	dsbd|	 d|d	< | D ]v\}
}|d k	rjt |tkrtd|
 dtdd |D rtd|
 dt|
 |sjtd|
 dqjt| }|d k	st| }|
d|d pd}|
d|d p,d}|
d|d pBd}|
d|d }|
d|d }t|}|d k	s|t| }|
d|d pd}|
d	|d	 pd}	|
d|d }| }t	|td d}t|	}t||}|dk}|dkp|dkp|d k	}t|||d |r*t|}t	|td d}|d krHd nt	|td d}|d krfd nt	|td d}t|||||||S ) NzURL too longc                 s   s    | ]}|  o|  V  qd S Nisasciiisprintable.0charr   r   r   	<genexpr>   s     zurlparse.<locals>.<genexpr>z,Invalid non-printable ASCII character in URLr   r   r   r   r   usernamepasswordr
   raw_pathr    r   r   r   r   zURL component 'z
' too longc                 s   s    | ]}|  o|  V  qd S r-   r.   r1   r   r   r   r4      s     z8Invalid non-printable ASCII character in URL component ''zInvalid URL component 'r   r   r	   safe)
has_schemehas_authorityz:@/z/?)lenMAX_URL_LENGTHr   any
isinstancer*   r&   pop	partitionquoteget
startswithendswithitemsCOMPONENT_REGEX	fullmatch	URL_REGEXmatchAssertionError	groupdictAUTHORITY_REGEXlower
SUB_DELIMSencode_hostnormalize_portvalidate_pathnormalize_pathr   )r,   r   r   r   _r5   r6   r7   Z	seperatorr   keyvalueZ	url_matchZurl_dictr   r   r   r   r	   Zauthority_matchZauthority_dictr
   Zparsed_schemeZparsed_userinfoZparsed_hostZparsed_portr;   r<   Zparsed_pathZparsed_queryZparsed_fragmentr   r   r   r      s    

"




r   )r   r   c                 C   s   | sdS t | rDzt|  W n tjk
r>   tdY nX | S t| rzt| dd  W n tjk
r   tdY nX | dd S |  rt	| 
 tdS zt| 
 dW S  tjk
r   tdY nX d S )	Nr   zInvalid IPv4 addressr   zInvalid IPv6 addressr9   asciizInvalid IDNA hostname)IPv4_STYLE_HOSTNAMErK   	ipaddressIPv4AddressAddressValueErrorr   IPv6_STYLE_HOSTNAMEIPv6Addressr/   rC   rO   rP   idnaencodedecode	IDNAError)r   r   r   r   rQ     s(    

	rQ   )r   r   r   c                 C   sd   | d ks| dkrd S zt | }W n tk
r<   tdY nX dddddd|}||kr`d S |S )Nr   zInvalid port   P   i  )ftphttphttpswswss)r*   
ValueErrorr   rD   )r   r   Zport_as_intdefault_portr   r   r   rR   C  s    rR   )r   r;   r<   r   c                 C   sH   |r| rD|  dsDtdn(|  dr.td|  drD|sDtddS )z
    Path validation rules that depend on if the URL contains a scheme or authority component.

    See https://datatracker.ietf.org/doc/html/rfc3986.html#section-3.3
    /z7For absolute URLs, path must be empty or begin with '/'r   zFURLs with no authority component cannot have a path starting with '//'r   zBURLs with no scheme component cannot have a path starting with ':'N)rE   r   )r   r;   r<   r   r   r   rS   `  s    

rS   )r   r   c                 C   sV   |  d}g }|D ]8}|dkr q|dkr@|rJ|dgkrJ|  q|| qd|S )z
    Drop "." and ".." segments from a URL path.

    For example:

        normalize_path("/path/./to/somewhere/..") == "/path/to"
    rm   .z..r   )splitrA   appendr   )r   
componentsoutput	componentr   r   r   rT   z  s    	

rT   )r3   r   c                 C   s   d dd | dD  S )a  
    Replace every character in a string with the percent-encoded representation.

    Characters outside the ASCII range are represented with their a percent-encoded
    representation of their UTF-8 byte sequence.

    For example:

        percent_encode(" ") == "%20"
    r   c                 S   s   g | ]}d |dqS )%Z02xr   )r2   byter   r   r   
<listcomp>  s     z"percent_encode.<locals>.<listcomp>zutf-8)r   ra   upper)r3   r   r   r   percent_encode  s    rx   rm   )stringr:   r   c                    s@   t |  | dtt| kr( d7  d fdd| D S )Nrt   r   c                    s    g | ]}| kr|nt |qS r   )rx   r1   ZNON_ESCAPED_CHARSr   r   rv     s     zquote.<locals>.<listcomp>)UNRESERVED_CHARACTERScountr=   PERCENT_ENCODED_REGEXfindallr   )ry   r:   r   rz   r   rC     s    rC   )rG   r   c                 C   s   d dd | D S )N&c                 S   s$   g | ]\}}t |d  t | qS )=)rC   )r2   kvr   r   r   rv     s     zurlencode.<locals>.<listcomp>)r   )rG   r   r   r   	urlencode  s    r   )r   )rm   )#__doc__r[   rer(   r`   _exceptionsr   r>   r{   rP   compiler}   formatrJ   rN   rH   rZ   r^   
NamedTupler   r&   r)   r   rQ   Unionr*   rR   boolrS   rT   rx   rC   ListTupler   r   r   r   r   <module>   sh   


7 / 