U
    nËjrH  ã                
   @  s  d Z ddlm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d
 dd„ eddƒD ƒ¡Zd
 dd„ eddƒD ƒ¡Zd
 dd„ eddƒD ƒ¡Zd
 dd„ eddƒD ƒ¡Zd
 dd„ eddƒD ƒ¡Zd
 dd„ eddƒ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dBd%d&d$d'œd(d)„Zd%d%d*œd+d,„Zd-d%d.d/œd0d1„Z d%d2d2d3d4œd5d6„Z!d%d%d7œd8d9„Z"d%d%d:œd;d<„Z#d%d%d%d=œd>d?„Z$d%d%d%d=œd@dA„Z%dS )Caï  
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.
é    )ÚannotationsNé   )Ú
InvalidURLi   zBABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~z!$&'()*+,;=z%[A-Fa-f0-9]{2}Ú c                 C  s   g | ]}|d krt |ƒ‘qS ))é    é"   é<   é>   é`   ©Úchr©Ú.0Úi© r   ú3/tmp/pip-unpacked-wheel-7ig9zwdf/httpx/_urlparse.pyÚ
<listcomp>,   s      r   r   é   c                 C  s   g | ]}|d krt |ƒ‘qS ))r   r   é#   r   r	   r   r   r   r   r   r   2   s      c                 C  s   g | ]}|d krt |ƒ‘qS ))	r   r   r   r   r	   é?   r
   é{   é}   r   r   r   r   r   r   8   s   þc                 C  s   g | ]}|d krt |ƒ‘qS ©)r   r   r   r   r	   r   r
   r   r   é/   é:   é;   é=   é@   é[   é\   é]   é^   é|   r   r   r   r   r   r   C   s
   ÿþc                 C  s   g | ]}|d krt |ƒ‘qS r   r   r   r   r   r   r   M   s
   ÿþc                 C  s   g | ]}|d krt |ƒ‘qS ))r   r   r   r   r	   r   r
   r   r   r   r   r   r   r   r   r    r!   r"   r   r   r   r   r   r   Z   s
   ÿþ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(\[.*\]|[^:@]*))ÚuserinfoÚhostÚportz[^@]*z(\[.*\]|[^:]*))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 ded< ded< ded< ded< ded< ded	< ded
< eddœdd„ƒZeddœdd„ƒZdd dœdd„Zddœdd„ZdS )ÚParseResultÚstrr$   r)   r*   ú
int | Noner+   r&   ú
str | Noner'   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 )Nr   ú@ú:ú[ú])Újoinr)   r*   r+   ©Úselfr   r   r   r%   §   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   r2   r3   r4   )r5   r*   r+   r6   r   r   r   Únetloc±   s
    þÿzParseResult.netloc)Úkwargsr0   c                 K  s6   |s| S | j | j| j| j| jdœ}| |¡ td|ŽS )Nr#   r   )r   )r$   r%   r&   r'   r(   ÚupdateÚurlparse)r7   r9   Údefaultsr   r   r   Ú	copy_withº   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   r2   ú//ú?ú#)r%   r5   r$   r&   r'   r(   )r7   r%   r   r   r   Ú__str__È   s    ûÿzParseResult.__str__N)	Ú__name__Ú
__module__Ú__qualname__Ú__annotations__Úpropertyr%   r8   r=   rA   r   r   r   r   r,   ž   s   
	r,   r-   r/   )Úurlr9   r0   c           "      K  sè  t | ƒtkrtdƒ‚tdd„ | D ƒƒr\tdd„ | D ƒƒ}|  |¡}d|›d|› d�}t|ƒ‚d|kr†|d }t|tƒr~t|ƒn||d< d	|kr´| 	d	¡pšd
}| 
d¡\|d< }|d< d|ksÆd|k�rt| 	dd
¡pÖd
td�}t| 	dd
¡pîd
td�}	|	�r
|› d|	› �n||d< d|k�rR| 	d¡�p*d
}
|
 
d¡\|d< }|d< |�sRd |d< d|k�rž| d¡�pjd
}d|k�rž| d¡�rŽ| d¡�sžd|› d�|d< | ¡ D ]¢\}}|d k	�r¦t |ƒtk�rÖtd|› d�ƒ‚tdd„ |D ƒƒ�r&tdd„ |D ƒƒ}| |¡}d|› d|›d|› d�}t|ƒ‚t|  |¡�s¦td|› d�ƒ‚�q¦t | ¡}|d k	�sbt‚| ¡ }| d|d ¡�p~d
}| d |d  ¡�p”d
}| d|d ¡�pªd
}| d|d ¡}| d!|d! ¡}t |¡}|d k	�sät‚| ¡ }| d|d ¡�p d
}| d|d ¡�pd
}| d|d ¡}| ¡ }t|td�}t|ƒ}t||ƒ}|d
k}|d
k�pp|d
k�pp|d k	}t|||d"� |�sŒ|�r”t|ƒ}t|td�}|d k�r®d n
t|t d�} |d k�rÈd n
t|t!d�}!t"|||||| |!ƒS )#NzURL too longc                 s  s    | ]}|  ¡ o| ¡  V  qd S ©N©ÚisasciiÚisprintable©r   Úcharr   r   r   Ú	<genexpr>ß   s     zurlparse.<locals>.<genexpr>c                 s  s"   | ]}|  ¡ r| ¡ s|V  qd S rH   rI   rL   r   r   r   rN   à   s       z.Invalid non-printable ASCII character in URL, z at position Ú.r+   r8   r   r2   r*   ÚusernameÚpassword©Úsafer)   Úraw_pathr?   r&   r'   r3   r4   zURL component 'z
' too longc                 s  s    | ]}|  ¡ o| ¡  V  qd S rH   rI   rL   r   r   r   rN     s     c                 s  s"   | ]}|  ¡ r| ¡ s|V  qd S rH   rI   rL   r   r   r   rN     s      z-Invalid non-printable ASCII character in URL z component, zInvalid URL component 'ú'r$   r%   r(   )Ú
has_schemeÚhas_authority)#ÚlenÚMAX_URL_LENGTHr   ÚanyÚnextÚfindÚ
isinstanceÚintr-   ÚpopÚ	partitionÚquoteÚUSERNAME_SAFEÚPASSWORD_SAFEÚgetÚ
startswithÚendswithÚitemsÚCOMPONENT_REGEXÚ	fullmatchÚ	URL_REGEXÚmatchÚAssertionErrorÚ	groupdictÚAUTHORITY_REGEXÚlowerÚUSERINFO_SAFEÚencode_hostÚnormalize_portÚvalidate_pathÚnormalize_pathÚ	PATH_SAFEÚ
QUERY_SAFEÚ	FRAG_SAFEr,   )"rG   r9   rM   ÚidxÚerrorr+   r8   Ú_rP   rQ   rT   Z	seperatorr*   ÚkeyÚvalueZ	url_matchZurl_dictr$   r%   r&   r'   ÚfragZauthority_matchZauthority_dictr)   Zparsed_schemeZparsed_userinfoZparsed_hostZparsed_portrV   rW   Zparsed_pathZparsed_queryZparsed_fragr   r   r   r;   Õ   sš    
ÿ

"
ÿ
ÿ


ÿùr;   )r*   r0   c                 C  sþ   | sdS t  | ¡rJzt | ¡ W n$ tjk
rD   td| ›�ƒ‚Y nX | S t | ¡rœzt | dd… ¡ W n$ tjk
rŽ   td| ›�ƒ‚Y nX | dd… S |  ¡ r¼d}t	|  
¡ t| d�S zt |  
¡ ¡ d¡W S  tjk
� rø   td	| ›�ƒ‚Y nX d S )
Nr   zInvalid IPv4 address: r   éÿÿÿÿzInvalid IPv6 address: z"`{}%|\rR   ÚasciizInvalid IDNA hostname: )ÚIPv4_STYLE_HOSTNAMErk   Ú	ipaddressÚIPv4AddressÚAddressValueErrorr   ÚIPv6_STYLE_HOSTNAMEÚIPv6AddressrJ   ra   ro   Ú
SUB_DELIMSÚidnaÚencodeÚdecodeÚ	IDNAError)r*   ZWHATWG_SAFEr   r   r   rq   \  s*    

	rq   zstr | int | Noner.   )r+   r$   r0   c                 C  sj   | d ks| dkrd S zt | ƒ}W n" tk
rB   td| ›�ƒ‚Y nX ddddddœ |¡}||krfd 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   ‹  s    
ÿrr   ÚboolÚNone)r&   rV   rW   r0   c                 C  sJ   |r| r|   d¡stdƒ‚|sF|sF|   d¡r4tdƒ‚|   d¡rFt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>   z3Relative URLs cannot have a path starting with '//'r2   z2Relative URLs cannot have a path starting with ':'N)re   r   )r&   rV   rW   r   r   r   rs   ¦  s    

rs   )r&   r0   c                 C  sv   d| kr| S |   d¡}d|kr*d|kr*| S g }|D ]8}|dkr@q2|dkr`|rj|dgkrj| ¡  q2| |¡ q2d |¡S )zˆ
    Drop "." and ".." segments from a URL path.

    For example:

        normalize_path("/path/./to/somewhere/..") == "/path/to"
    rO   r–   z..r   )Úsplitr_   Úappendr5   )r&   Ú
componentsÚoutputÚ	componentr   r   r   rt   ¿  s    	

rt   )Ústringr0   c                 C  s   d  dd„ |  d¡D ƒ¡S )Nr   c                 S  s   g | ]}d |d›�‘qS )ú%Z02Xr   )r   Úbyter   r   r   r   ß  s     zPERCENT.<locals>.<listcomp>zutf-8)r5   rˆ   )rœ   r   r   r   ÚPERCENTÞ  s    rŸ   )rœ   rS   r0   c                   s.   t | ‰ |  ˆ ¡s| S d ‡ fdd„| D ƒ¡S )z1
    Use percent-encoding to quote a string.
    r   c                   s    g | ]}|ˆ kr|nt |ƒ‘qS r   )rŸ   rL   ©ZNON_ESCAPED_CHARSr   r   r   í  s     z#percent_encoded.<locals>.<listcomp>)ÚUNRESERVED_CHARACTERSÚrstripr5   )rœ   rS   r   r    r   Úpercent_encodedâ  s    
ÿr£   c           
      C  sž   g }d}t  t| ¡D ]T}| ¡ | ¡  }}| d¡}||krZ| ||… }| t||d�¡ | |¡ |}q|t| ƒkr”| |d… }	| t|	|d�¡ d 	|¡S )a®  
    Use percent-encoding to quote a string, omitting existing '%xx' escape sequences.

    See: https://www.rfc-editor.org/rfc/rfc3986#section-2.1

    * `string`: The string to be percent-escaped.
    * `safe`: A string containing characters that may be treated as safe, and do not
        need to be escaped. Unreserved characters are always treated as safe.
        See: https://www.rfc-editor.org/rfc/rfc3986#section-2.3
    r   rR   Nr   )
ÚreÚfinditerÚPERCENT_ENCODED_REGEXÚstartÚendÚgroupr˜   r£   rX   r5   )
rœ   rS   ÚpartsÚcurrent_positionrk   Zstart_positionZend_positionZmatched_textZleading_textZtrailing_textr   r   r   ra   ñ  s    

ra   )r   )&Ú__doc__Ú
__future__r   r�   r¤   Útypingr‡   Ú_exceptionsr   rY   r¡   r†   Úcompiler¦   r5   Úrangerw   rv   ru   rb   rc   rp   Úformatrj   rn   rh   r€   r„   Ú
NamedTupler,   r;   rq   rr   rs   rt   rŸ   r£   ra   r   r   r   r   Ú<module>   s˜   ÿ
ÿÿþÿþÿ
þÿþÿÿõÿÿúÿø

7 /