a
    äze e  ã                   @   sr  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZ d dlmZ zd dlZW n ey‚   dZY n0 ej e¡Zej ed¡Zej ed¡ZG dd„ dejjƒZG dd	„ d	ejƒZG d
d„ dƒZG dd„ dejjƒZG dd„ dejjƒZ G dd„ de	j!ƒZ"ej#dddG dd„ de	j!ƒƒZ$dd„ Z%G dd„ de	j!ƒZ&dd„ Z'e(dkrne	 )¡  dS )é    N)Úsupport)Úhashlib_helperzkeycert.pemzkeycert2.pemc                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚLoopbackHttpServerz^HTTP server w/ a few modifications that make it useful for
    loopback testing purposes.
    c                 C   s"   t jj | ||¡ | j d¡ d S )Ngš™™™™™¹?)ÚhttpÚserverÚ
HTTPServerÚ__init__ÚsocketÚ
settimeout)ÚselfZserver_addressZRequestHandlerClass© r   ú0/usr/lib/python3.9/test/test_urllib2_localnet.pyr   !   s
    
þzLoopbackHttpServer.__init__c                 C   s    | j  ¡ \}}| d¡ ||fS )zHTTPServer method, overridden.g      $@)r	   Úacceptr
   )r   ÚrequestZclient_addressr   r   r   Úget_request*   s    
zLoopbackHttpServer.get_requestN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r      s   	r   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚLoopbackHttpServerThreadz2Stoppable thread that runs a loopback http server.c                 C   s<   t j | ¡ d| _t  ¡ | _d|_td|ƒ| _| jj	| _
d S )NFzHTTP/1.0)z	127.0.0.1r   )Ú	threadingÚThreadr   Ú_stop_serverÚEventÚreadyZprotocol_versionr   ÚhttpdZserver_portÚport©r   Úrequest_handlerr   r   r   r   9   s    
ÿz!LoopbackHttpServerThread.__init__c                 C   s   d| _ |  ¡  | j ¡  dS )z.Stops the webserver if it's currently running.TN)r   Újoinr   Zserver_close©r   r   r   r   ÚstopB   s    zLoopbackHttpServerThread.stopc                 C   s    | j  ¡  | js| j ¡  q
d S ©N)r   Úsetr   r   Úhandle_requestr    r   r   r   ÚrunJ   s    
zLoopbackHttpServerThread.runN)r   r   r   r   r   r!   r%   r   r   r   r   r   6   s   	r   c                   @   sX   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )ÚDigestAuthHandlerz-Handler for performing digest authentication.c                 C   s"   d| _ g | _i | _d| _d| _d S )Nr   z
Test RealmÚauth)Ú_request_numÚ_noncesÚ_usersÚ_realm_nameÚ_qopr    r   r   r   r   T   s
    zDigestAuthHandler.__init__c                 C   s
   || _ d S r"   )r,   )r   Zqopr   r   r   Úset_qop[   s    zDigestAuthHandler.set_qopc                 C   s   t |tƒsJ ‚|| _d S r"   )Ú
isinstanceÚdictr*   )r   Zusersr   r   r   Ú	set_users^   s    zDigestAuthHandler.set_usersc                 C   s
   || _ d S r"   )r+   )r   Zrealmr   r   r   Ú	set_realmb   s    zDigestAuthHandler.set_realmc                 C   s8   |  j d7  _ t t| j ƒ d¡¡ ¡ }| j |¡ |S )Né   Úascii)r(   ÚhashlibÚmd5ÚstrÚencodeÚ	hexdigestr)   Úappend)r   Únoncer   r   r   Ú_generate_noncee   s    z!DigestAuthHandler._generate_noncec                 C   s‚   |  d¡}||d d … }| d¡}i }|D ]P}| d¡\}}| ¡ }|d dkrl|d dkrl|dd… }n| ¡ }|||< q,|S )Nú r2   ú,ú=r   ú"éÿÿÿÿ)ÚfindÚsplitÚstrip)r   Zauth_strZfirst_space_indexÚpartsÚ	auth_dictÚpartÚnameÚvaluer   r   r   Ú_create_auth_dictk   s    


z#DigestAuthHandler._create_auth_dictc                 C   s–   i }|  |¡ ||d< ||d< ||d< d| }t | d¡¡ ¡ }d| }t | d¡¡ ¡ }	||d< |	|d< d	| }
t |
 d¡¡ ¡ }||d
 kS )NÚpasswordÚmethodÚuriz#%(username)s:%(realm)s:%(password)sr3   z%(method)s:%(uri)sÚHA1ÚHA2z3%(HA1)s:%(nonce)s:%(nc)s:%(cnonce)s:%(qop)s:%(HA2)sÚresponse)Úupdater4   r5   r7   r8   )r   rE   rJ   rK   rL   Z
final_dictZHA1_strrM   ZHA2_strrN   Zresponse_strrO   r   r   r   Ú_validate_auth|   s     
ÿz DigestAuthHandler._validate_authc                 C   sN   |  dd¡ | dd¡ | dd| j| j|  ¡ f ¡ | ¡  |j d¡ dS )	Ni—  zProxy Authentication RequiredúContent-Typeú	text/htmlzProxy-Authenticatez(Digest realm="%s", qop="%s",nonce="%s", s   Proxy Authentication Required.F)Úsend_responseÚsend_headerr+   r,   r;   Úend_headersÚwfileÚwriter   r   r   r   Ú_return_auth_challengeŽ   s    ýÿz(DigestAuthHandler._return_auth_challengec                 C   sÊ   t | jƒdkrdS d|jvr&|  |¡S |  |jd ¡}|d | jv rT| j|d  }n
|  |¡S | d¡| jvrx|  |¡S | j |d ¡ d}|j|j	fD ]}|  
|||j|¡r˜d}q˜|sÂ|  |¡S dS dS )a  Performs digest authentication on the given HTTP request
        handler.  Returns True if authentication was successful, False
        otherwise.

        If no users have been set, then digest auth is effectively
        disabled and this method will always return True.
        r   TzProxy-AuthorizationÚusernamer:   FN)Úlenr*   ÚheadersrY   rI   Úgetr)   ÚremoveÚpathÚ
short_pathrQ   Zcommand)r   r   rE   rJ   Zauth_validatedr_   r   r   r   r$      s0    	

ÿ

ý
z DigestAuthHandler.handle_requestN)r   r   r   r   r   r-   r0   r1   r;   rI   rQ   rY   r$   r   r   r   r   r&   Q   s   r&   c                   @   sf   e Zd ZdZdZdZdZdeef Ze 	e 
d¡¡ d¡Zdd„ Zd	d
„ Zdd„ Zdd„ Zdd„ ZdS )ÚBasicAuthHandlerz,Handler for performing basic authentication.ÚtestUserÚtestPassÚTestz%s:%sr3   c                 O   s    t jjj| g|¢R i |¤Ž d S r"   )r   r   ÚBaseHTTPRequestHandlerr   )r   ÚargsÚkwargsr   r   r   r   Ó   s    zBasicAuthHandler.__init__c                 G   s   d S r"   r   ©r   Úformatrf   r   r   r   Úlog_messageÖ   s    zBasicAuthHandler.log_messagec                 C   s"   |   d¡ |  dd¡ |  ¡  d S )NéÈ   úContent-typerS   )rT   rU   rV   r    r   r   r   Údo_HEADÚ   s    
zBasicAuthHandler.do_HEADc                 C   s4   |   d¡ |  dd| j ¡ |  dd¡ |  ¡  d S )Ni‘  zWWW-AuthenticatezBasic realm="%s"rl   rS   )rT   rU   ÚREALMrV   r    r   r   r   Údo_AUTHHEADß   s    
zBasicAuthHandler.do_AUTHHEADc                 C   sh   | j  dd¡s$|  ¡  | j d¡ n@| j  dd¡d| j kr\|  d¡ |  ¡  | j d¡ n|  ¡  d S )NZAuthorizationÚ s   No Auth header receivedzBasic rk   s   It works)r\   r]   ro   rW   rX   ÚENCODED_AUTHrT   rV   r    r   r   r   Údo_GETå   s    ÿÿ
zBasicAuthHandler.do_GETN)r   r   r   r   ÚUSERÚPASSWDrn   ZUSER_PASSWDÚbase64Z	b64encoder7   Údecoderq   r   rj   rm   ro   rr   r   r   r   r   ra   Ê   s   ra   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚFakeProxyHandlerzÏThis is a 'fake proxy' that makes it look like the entire
    internet has gone down due to a sudden zombie invasion.  It main
    utility is in providing us with authentication support for
    testing.
    c                 O   s&   || _ tjjj| g|¢R i |¤Ž d S r"   )Údigest_auth_handlerr   r   re   r   )r   rx   rf   rg   r   r   r   r   ý   s    zFakeProxyHandler.__init__c                 G   s   d S r"   r   rh   r   r   r   rj     s    zFakeProxyHandler.log_messagec                 C   sv   t j | jd¡\}}}}}}|| _| j | ¡rr|  dd¡ |  dd¡ |  	¡  | j
 td| j dƒ¡ | j
 d¡ d S )	Nr   rk   ZOKrR   rS   zYou've reached %s!<BR>r3   sF   Our apologies, but our server is down due to a sudden zombie invasion.)ÚurllibÚparseÚurlparser_   r`   rx   r$   rT   rU   rV   rW   rX   Úbytes)r   ZscmÚnetlocr_   ÚparamsÚqueryÚfragmentr   r   r   rr     s    ÿÿzFakeProxyHandler.do_GETN)r   r   r   r   r   rj   rr   r   r   r   r   rw   ö   s   rw   c                       sP   e Zd ZdZdZdZdZ‡ fdd„Zdd„ Z‡ fd	d
„Z	dd„ Z
dd„ Z‡  ZS )ÚBasicAuthTestsrb   rc   Z	Incorrectrd   c                    sT   t t| ƒ ¡  dd„ }t|ƒ| _|  | j¡ d| jj | _| j 	¡  | jj
 ¡  d S )Nc                  _   s   t | i |¤ŽS r"   )ra   ©rf   rg   r   r   r   Ú#http_server_with_basic_auth_handler   s    zABasicAuthTests.setUp.<locals>.http_server_with_basic_auth_handlerzhttp://127.0.0.1:%s)Úsuperr   ÚsetUpr   r   Ú
addCleanupÚstop_serverr   Ú
server_urlÚstartr   Úwait)r   rƒ   ©Ú	__class__r   r   r…     s    

zBasicAuthTests.setUpc                 C   s   | j  ¡  d | _ d S r"   ©r   r!   r    r   r   r   r‡   (  s    
zBasicAuthTests.stop_serverc                    s   t t| ƒ ¡  d S r"   )r„   r   ÚtearDownr    r‹   r   r   rŽ   ,  s    zBasicAuthTests.tearDownc                 C   sz   t j ¡ }| | j| j| j| j¡ t j t j 	|¡¡ z|  
t j | j¡¡ W n& t jjyt   |  d| j ¡ Y n0 d S )Nz!Basic auth failed for the url: %s)ry   r   ÚHTTPBasicAuthHandlerÚadd_passwordrn   rˆ   rs   rt   Úinstall_openerÚbuild_openerÚ
assertTrueÚurlopenÚerrorÚ	HTTPErrorÚfail©r   Zahr   r   r   Útest_basic_auth_success/  s    
z&BasicAuthTests.test_basic_auth_successc                 C   sR   t j ¡ }| | j| j| j| j¡ t j t j 	|¡¡ |  
t jjt jj| j¡ d S r"   )ry   r   r   r   rn   rˆ   rs   ÚINCORRECT_PASSWDr‘   r’   ÚassertRaisesr•   r–   r”   r˜   r   r   r   Útest_basic_auth_httperror8  s    
z(BasicAuthTests.test_basic_auth_httperror)r   r   r   rs   rt   rš   rn   r…   r‡   rŽ   r™   rœ   Ú__classcell__r   r   r‹   r   r     s   	r   r5   T)Zopensslc                       sT   e Zd ZdZdZdZdZ‡ fdd„Zdd„ Zd	d
„ Z	dd„ Z
dd„ Zdd„ Z‡  ZS )ÚProxyAuthTestszhttp://localhostZtesterZtest123Z	TestRealmc                    sÜ   t tˆ ƒ ¡  dd„ }ˆ  |tj ¡ ¡ dtjd< dtjd< tƒ ˆ _ˆ j 	ˆ j
ˆ ji¡ ˆ j ˆ j¡ ‡ fdd„}t|ƒˆ _ˆ  ˆ j¡ ˆ j ¡  ˆ jj ¡  dˆ jj }tj d	|i¡}tj ¡ ˆ _tj |ˆ j¡ˆ _d S )
Nc                 S   s   t j ¡  t j | ¡ d S r"   ©ÚosÚenvironÚclearrP   ©Zold_environr   r   r   Úrestore_environJ  s    
z-ProxyAuthTests.setUp.<locals>.restore_environrp   ÚNO_PROXYÚno_proxyc                     s   t ˆ jg| ¢R i |¤ŽS r"   )rw   rx   r‚   r    r   r   Úcreate_fake_proxy_handlerU  s    z7ProxyAuthTests.setUp.<locals>.create_fake_proxy_handlerzhttp://127.0.0.1:%dr   )r„   rž   r…   r†   r    r¡   Úcopyr&   rx   r0   rs   rt   r1   rn   r   r   r‡   r‰   r   rŠ   r   ry   r   ZProxyHandlerZProxyDigestAuthHandlerÚproxy_digest_handlerr’   Úopener)r   r¤   r§   Z	proxy_urlÚhandlerr‹   r    r   r…   G  s&    



ÿzProxyAuthTests.setUpc                 C   s   | j  ¡  d | _ d S r"   r   r    r   r   r   r‡   b  s    
zProxyAuthTests.stop_serverc                 C   sF   | j  | j| j| j| jd ¡ | j d¡ |  t	j
j| jj| j¡ d S )NZbadr'   )r©   r   rn   ÚURLrs   rt   rx   r-   r›   ry   r•   r–   rª   Úopenr    r   r   r   Ú-test_proxy_with_bad_password_raises_httperrorf  s    ÿ
þz<ProxyAuthTests.test_proxy_with_bad_password_raises_httperrorc                 C   s(   | j  d¡ |  tjj| jj| j¡ d S ©Nr'   )	rx   r-   r›   ry   r•   r–   rª   r­   r¬   r    r   r   r   Ú,test_proxy_with_no_password_raises_httperrorn  s
    
þz;ProxyAuthTests.test_proxy_with_no_password_raises_httperrorc                 C   sb   | j  | j| j| j| j¡ | j d¡ | j 	| j¡}| 
¡ r@q6W d   ƒ n1 sT0    Y  d S r¯   )r©   r   rn   r¬   rs   rt   rx   r-   rª   r­   Úread©r   Úresultr   r   r   Útest_proxy_qop_auth_workst  s    ÿz(ProxyAuthTests.test_proxy_qop_auth_worksc                 C   s‚   | j  | j| j| j| j¡ | j d¡ z| j 	| j¡}W n t
jjyN   Y n00 | | ¡ r`qVW d   ƒ n1 st0    Y  d S )Nzauth-int)r©   r   rn   r¬   rs   rt   rx   r-   rª   r­   ry   r•   ÚURLErrorr±   r²   r   r   r   Ú0test_proxy_qop_auth_int_works_or_throws_urlerror|  s    ÿz?ProxyAuthTests.test_proxy_qop_auth_int_works_or_throws_urlerror)r   r   r   r¬   rs   rt   rn   r…   r‡   r®   r°   r´   r¶   r   r   r   r‹   r   rž   ?  s   rž   c                    s   G ‡ ‡fdd„dt jjƒ‰ ˆ S )Nc                       sB   e Zd ZdZg Zg ZdZdd„ Zdd„ Z‡ ‡fdd„Z	d	d
„ Z
dS )z1GetRequestHandler.<locals>.FakeHTTPRequestHandlerz	TestHTTP/éP   c                 S   s*   |   ¡ }|r&| j |¡}||d … }qd S r"   )Ú	send_headrW   rX   )r   ÚbodyÚdoner   r   r   rr   –  s    z8GetRequestHandler.<locals>.FakeHTTPRequestHandler.do_GETc                 S   s2   | j d }| j t|ƒ¡}|  ¡  | j |¡ d S )NzContent-Length)r\   Zrfiler±   Úintrr   Úrequestsr9   )r   Zcontent_lengthZ	post_datar   r   r   Údo_POSTœ  s    
z9GetRequestHandler.<locals>.FakeHTTPRequestHandler.do_POSTc                    s|   | j ˆ _| j | j¡ ˆ d¡\}}}|  |¡ |D ]\}}|  ||d| ji ¡ q4|rp|  dd¡ |  	¡  |S |  	¡  d S )Nr   r   rl   z
text/plain)
r\   Úheaders_receivedr¼   r9   r_   ÚpoprT   rU   r   rV   )r   Zresponse_coder\   r¹   ÚheaderrH   ©ÚFakeHTTPRequestHandlerÚ	responsesr   r   r¸   ¢  s    
z;GetRequestHandler.<locals>.FakeHTTPRequestHandler.send_headc                 W   s   d S r"   r   )r   rf   r   r   r   rj   ±  s    z=GetRequestHandler.<locals>.FakeHTTPRequestHandler.log_messageN)r   r   r   Zserver_versionr¼   r¾   r   rr   r½   r¸   rj   r   rÁ   r   r   rÂ     s   rÂ   )r   r   re   )rÃ   r   rÁ   r   ÚGetRequestHandler  s    &rÄ   c                       sÎ   e Zd ZdZ‡ fdd„Zd/dd„Zdd„ Zd0d	d
„Zd1dd„Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Z‡  ZS )2ÚTestUrlopenaN  Tests urllib.request.urlopen using the network.

    These tests are not exhaustive.  Assuming that testing using files does a
    good job overall of some of the basic interface features.  There are no
    tests exercising the optional 'data' and 'proxies' arguments.  No tests
    for transparent redirection have been written.
    c                    sN   t t| ƒ ¡  |  tjj¡ dd„ }|  |tj 	¡ ¡ dtjd< dtjd< d S )Nc                 S   s   t j ¡  t j | ¡ d S r"   rŸ   r£   r   r   r   r¤   È  s    
z*TestUrlopen.setUp.<locals>.restore_environÚ*r¥   r¦   )
r„   rÅ   r…   r†   ry   r   Ú
urlcleanupr    r¡   r¨   )r   r¤   r‹   r   r   r…   Á  s    
zTestUrlopen.setUpNc                 K   sx   g }t jj||fi |¤Ž}zH| | d¡¡ | | ¡ ¡ | | d¡¡ | | ¡ ¡ W | ¡  n
| ¡  0 d 	|¡S )Nrk   i   ó    )
ry   r   r”   ÚextendÚ	readlinesr9   Úreadliner±   Úcloser   )r   ÚurlÚdatarg   ÚlÚfr   r   r   r”   Ï  s    zTestUrlopen.urlopenc                 C   s   | j  ¡  d | _ d S r"   r   r    r   r   r   r‡   Ü  s    
zTestUrlopen.stop_serverc                 C   sZ   |d u rdg dfg}t |ƒ}t|ƒ| _|  | j¡ | j ¡  | jj ¡  | jj}||_|S )Nrk   s   we don't care)	rÄ   r   r   r†   r‡   r‰   r   rŠ   r   )r   rÃ   r«   r   r   r   r   Ústart_serverà  s    

zTestUrlopen.start_serverc                 K   s^   t tjdƒs|  d¡ ddlm} |d u r6dg dfg}t|ƒ}|| fd|i|¤Ž}|j|_|S )NZHTTPSHandlerzssl support requiredr   )Úmake_https_serverrk   ó   we care a bitZhandler_class)Úhasattrry   r   ÚskipTestZtest.ssl_serversrÒ   rÄ   r   )r   rÃ   rg   rÒ   r«   r   r   r   r   Ústart_https_serverí  s    
zTestUrlopen.start_https_serverc                 C   sV   d}ddgdfdg |fg}|   |¡}|  d|j ¡}|  ||¡ |  |jddg¡ d S )	Ns   We got here...i.  )ZLocationz(http://localhost:%(port)s/somewhere_elserp   rk   úhttp://localhost:%s/ú/z/somewhere_else©rÑ   r”   r   ÚassertEqualr¼   )r   Úexpected_responserÃ   r«   rÎ   r   r   r   Útest_redirectionø  s    ÿý
zTestUrlopen.test_redirectionc                 C   s@   d}d}ddg|fg}|   |¡}|  d|j ¡}|  ||¡ d S )Ns   hello worlds   a
hello worl
1
d
0
rk   )zTransfer-EncodingZchunkedr×   )rÑ   r”   r   rÚ   )r   rÛ   Zchunked_startrO   r«   rÎ   r   r   r   Útest_chunked  s    ÿ
zTestUrlopen.test_chunkedc              
   C   sŽ   d}|   dg |fg¡}z|  d|j ¡ W n8 tjjyb } z| ¡ }| ¡  W Y d }~nd }~0 0 |  d¡ |  	||¡ |  	|j
dg¡ d S )Ns   Bad bad bad...i”  zhttp://localhost:%s/weeblez404 should raise URLErrorz/weeble)rÑ   r”   r   ry   r•   rµ   r±   rÌ   r—   rÚ   r¼   )r   rÛ   r«   rÐ   rÎ   r   r   r   Útest_404  s    
zTestUrlopen.test_404c                 C   sF   d}|   dg |fg¡}|  d|j ¡}|  ||¡ |  |jdg¡ d S )Nó   pycon 2008...rk   úhttp://localhost:%s/bizarreú/bizarrerÙ   ©r   rÛ   r«   rÎ   r   r   r   Útest_200"  s
    zTestUrlopen.test_200c                 C   sJ   d}|   dg |fg¡}|  d|j d¡}|  ||¡ |  |jddg¡ d S )Nrß   rk   rà   s   get=with_feelingrá   rÙ   râ   r   r   r   Útest_200_with_parameters)  s    ÿz$TestUrlopen.test_200_with_parametersc                 C   s8   |   ¡ }tjtd}| jd|j |d}|  |d¡ d S )N©Zcafileúhttps://localhost:%s/bizarre©ÚcontextrÓ   )rÖ   ÚsslÚcreate_default_contextÚCERT_localhostr”   r   rÚ   )r   r«   rè   rÎ   r   r   r   Ú
test_https1  s    zTestUrlopen.test_httpsc              	   C   sî   | j td}t dtf¡À | jd|j td}|  |d¡ |  t	j
j¡$}| jd|j td W d   ƒ n1 st0    Y  | j td}|  t	j
j¡$}| jd|j td W d   ƒ n1 sÂ0    Y  W d   ƒ n1 sà0    Y  d S )N©Úcertfilerp   ræ   rå   rÓ   )rÖ   rë   r   Úcheck_warningsÚDeprecationWarningr”   r   rÚ   r›   ry   r•   rµ   ÚCERT_fakehostname)r   r«   rÎ   Úcmr   r   r   Útest_https_with_cafile7  s    ÿÿ$ÿz"TestUrlopen.test_https_with_cafilec              	   C   s€   | j td}t dtf¡R |  tjj¡$}| j	d|j
 dd W d   ƒ n1 sT0    Y  W d   ƒ n1 sr0    Y  d S )Nrí   rp   ræ   T)Z	cadefault)rÖ   rë   r   rï   rð   r›   ry   r•   rµ   r”   r   )r   r«   rò   r   r   r   Útest_https_with_cadefaultH  s    ÿz%TestUrlopen.test_https_with_cadefaultc                    s†   t d u r|  d¡ t js"|  d¡ d ‰ ‡ fdd„}t  t j¡}| |¡ | j|td}t jtd}| j	d|j
 |d |  ˆ d	¡ d S )
Nzssl module requiredzSNI support required in OpenSSLc                    s   |‰ d S r"   r   )Zssl_sockZserver_nameZinitial_context©Zsni_namer   r   Úcb_sniV  s    z*TestUrlopen.test_https_sni.<locals>.cb_sni)rè   rî   rå   zhttps://localhost:%srç   Ú	localhost)ré   rÕ   ZHAS_SNIZ
SSLContextZPROTOCOL_TLS_SERVERZset_servername_callbackrÖ   rë   rê   r”   r   rÚ   )r   rö   rè   r«   r   rõ   r   Útest_https_sniP  s    


zTestUrlopen.test_https_snic                 C   sd   |   ¡ }tjjd|j ddid}tj |¡ W d   ƒ n1 sD0    Y  |  |jd d¡ d S )Nr×   ZRangezbytes=20-39©r\   )rÑ   ry   r   ÚRequestr   r”   rÚ   r¾   ©r   r«   Zreqr   r   r   Útest_sending_headers`  s    ÿz TestUrlopen.test_sending_headersc                 C   sv   |   ¡ }tjjd|j ddid}tj |¡ W d   ƒ n1 sD0    Y  |  d|j ¡ ¡ |  	d|j ¡ ¡ d S )Nr×   zX-SoMe-hEaderZfoobarrù   zX-Some-Header)
rÑ   ry   r   rú   r   r”   ZassertInr¾   ÚkeysZassertNotInrû   r   r   r   Útest_sending_headers_camelh  s    ÿz&TestUrlopen.test_sending_headers_camelc                 C   sn   |   ¡ }tj d|j ¡@}dD ]}|  t||ƒd| ¡ q |  | ¡ d¡ W d   ƒ n1 s`0    Y  d S )Núhttp://localhost:%s)r±   rÌ   ÚinfoÚgeturlz3object returned from urlopen lacks the %s attributezcalling 'read' failed)rÑ   ry   r   r”   r   r“   rÔ   r±   )r   r«   Úopen_urlÚattrr   r   r   Ú
test_basicq  s    ÿzTestUrlopen.test_basicc                 C   sl   |   ¡ }tj d|j ¡}| | ¡ }W d   ƒ n1 s<0    Y  |  |tjj	d¡ |  
| ¡ d¡ d S )Nrÿ   zEobject returned by 'info' is not an instance of email.message.MessageZplain)rÑ   ry   r   r”   r   r   ZassertIsInstanceÚemailÚmessageZMessagerÚ   Zget_content_subtype)r   r«   r  Zinfo_objr   r   r   Ú	test_infoy  s    ÿ&ÿzTestUrlopen.test_infoc                 C   s\   |   ¡ }tj d|j ¡}| | ¡ }W d   ƒ n1 s<0    Y  |  |d|j ¡ d S )Nrÿ   )rÑ   ry   r   r”   r   r  rÚ   )r   r«   r  rÍ   r   r   r   Útest_geturl„  s
    &zTestUrlopen.test_geturlc                 C   sB   d}|   dg |fg¡}tj d|j ¡}|D ]}|  ||¡ q,d S )Nrß   rk   rÿ   )rÑ   ry   r   r”   r   rÚ   )r   rÛ   r«   rÎ   Úliner   r   r   Útest_iterationŒ  s
    zTestUrlopen.test_iterationc              
   C   s”   ddddd d g}d  |¡}|  dg |fg¡}tj d	|j ¡}t|ƒD ]0\}}|  ||| d
|t|| ƒt|ƒf ¡ qJ|  |d t|ƒ¡ d S )Ns   We
s   got
s   here
s	   verylong i    ó   
rÈ   rk   rÿ   zQFetched line number %s doesn't match expected:
    Expected length was %s, got %sr2   )	r   rÑ   ry   r   r”   r   Ú	enumeraterÚ   r[   )r   ÚlinesrÛ   r«   rÎ   Úindexr	  r   r   r   Útest_line_iteration“  s    
þÿzTestUrlopen.test_line_iterationc                 C   s¬   |   dg dfdg dfg¡}tj ¡ }tj d|j ¡}|  d |j¡ | |d 	d¡¡ |  d|j¡ |  d| 
d¡¡ | |d 	d¡¡ |  d	|j¡ |  d
| 
d¡¡ d S )Nrk   s   anyrÿ   Ú1zus-asciió   1zContent-lengthZ
1234567890s
   1234567890Z10)rÑ   ry   r   r’   rú   r   rÚ   rÎ   r­   r7   Z
get_header)r   r«   rª   r   r   r   r   Útest_issue16464Ÿ  s    þ
zTestUrlopen.test_issue16464)N)N)N)r   r   r   r   r…   r”   r‡   rÑ   rÖ   rÜ   rÝ   rÞ   rã   rä   rì   ró   rô   rø   rü   rþ   r  r  r  r
  r  r  r   r   r   r‹   r   rÅ   ¸  s.   


	rÅ   c                  C   s    t  ¡ } tjt jg| ¢R Ž  d S r"   )r   Zthreading_setupÚunittestZaddModuleCleanupZthreading_cleanup)Úthread_infor   r   r   ÚsetUpModule²  s    r  Ú__main__)*ru   r    r  Úurllib.parsery   Zurllib.requestZhttp.serverr   r   r  r4   Útestr   Ztest.supportr   ré   ÚImportErrorr_   ÚdirnameÚ__file__Úherer   rë   rñ   r   r   r   r   r   r&   re   ra   rw   ZTestCaser   Zrequires_hashdigestrž   rÄ   rÅ   r  r   Úmainr   r   r   r   Ú<module>   s>   
y,!(M+ {
