B
    u9aa  ã               @   sf  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 yd dlZW n ek
rx   dZY nX 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 G dd„ de	jƒZ!dd„ Z"G dd„ de	jƒZ#da$dd„ Z%dd„ Z&e'dkrbe	 (¡  dS )é    N)Úsupportz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   ú+/usr/lib/python3.7/test_urllib2_localnet.pyr       s    
zLoopbackHttpServer.__init__c             C   s    | j  ¡ \}}| d¡ ||fS )zHTTPServer method, overridden.g      $@)r   Z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_serverZEventÚreadyZprotocol_versionr   ÚhttpdZserver_portÚport)r
   Úrequest_handlerr   r   r   r   8   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   ÚstopA   s    zLoopbackHttpServerThread.stopc             C   s$   | j  ¡  x| js| j ¡  qW d S )N)r   Úsetr   r   Úhandle_request)r
   r   r   r   ÚrunI   s    
zLoopbackHttpServerThread.runN)r   r   r   r   r   r   r   r   r   r   r   r   5   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Ú_qop)r
   r   r   r   r   S   s
    zDigestAuthHandler.__init__c             C   s
   || _ d S )N)r&   )r
   Zqopr   r   r   Úset_qopZ   s    zDigestAuthHandler.set_qopc             C   s
   || _ d S )N)r$   )r
   Zusersr   r   r   Ú	set_users]   s    zDigestAuthHandler.set_usersc             C   s
   || _ d S )N)r%   )r
   Zrealmr   r   r   Ú	set_realma   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_nonced   s    z!DigestAuthHandler._generate_noncec             C   s†   |  d¡}||d d … }| d¡}i }xX|D ]P}| d¡\}}| ¡ }|d dkrn|d dkrn|dd… }n| ¡ }|||< q.W |S )Nú r*   ú,ú=r   ú"éÿÿÿÿ)ÚfindÚsplitÚstrip)r
   Zauth_strZfirst_space_indexÚpartsÚ	auth_dictÚpartÚnameÚvaluer   r   r   Ú_create_auth_dictj   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)sr+   z%(method)s:%(uri)sÚHA1ÚHA2z3%(HA1)s:%(nonce)s:%(nc)s:%(cnonce)s:%(qop)s:%(HA2)sÚresponse)Úupdater,   r-   r/   r0   )r
   r=   rB   rC   rD   Z
final_dictZHA1_strrE   ZHA2_strrF   Zresponse_strrG   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 RequiredzContent-Typez	text/htmlzProxy-Authenticatez(Digest realm="%s", qop="%s",nonce="%s", s   Proxy Authentication Required.F)Úsend_responseÚsend_headerr%   r&   r3   Úend_headersÚwfileÚwrite)r
   r   r   r   r   Ú_return_auth_challenge   s    z(DigestAuthHandler._return_auth_challengec             C   sÎ   t | jƒdkrdS d|jkr&|  |¡S |  |jd ¡}|d | jkrT| j|d  }n
|  |¡S | d¡| jkrx|  |¡S | j |d ¡ d}x*|j|j	gD ]}|  
|||j|¡ršd}qšW |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-AuthorizationZusernamer2   FN)Úlenr$   ÚheadersrO   rA   Úgetr#   ÚremoveÚpathÚ
short_pathrI   Zcommand)r
   r   r=   rB   Zauth_validatedrT   r   r   r   r   œ   s,    	




z DigestAuthHandler.handle_requestN)r   r   r   r   r   r'   r(   r)   r3   rA   rI   rO   r   r   r   r   r   r    P   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:%sr+   c             O   s   t jjj| f|ž|Ž d S )N)r   r   ÚBaseHTTPRequestHandlerr   )r
   ÚargsÚkwargsr   r   r   r   Ò   s    zBasicAuthHandler.__init__c             G   s   d S )Nr   )r
   Úformatr[   r   r   r   Úlog_messageÕ   s    zBasicAuthHandler.log_messagec             C   s"   |   d¡ |  dd¡ |  ¡  d S )NéÈ   zContent-typez	text/html)rJ   rK   rL   )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"zContent-typez	text/html)rJ   rK   ÚREALMrL   )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 r_   s   It works)rQ   rR   rb   rM   rN   ÚENCODED_AUTHrJ   rL   )r
   r   r   r   Údo_GETä   s    
zBasicAuthHandler.do_GETN)r   r   r   r   ÚUSERÚPASSWDra   ZUSER_PASSWDÚbase64Z	b64encoder/   Údecoderd   r   r^   r`   rb   re   r   r   r   r   rV   É   s   rV   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| f|ž|Ž d S )N)Údigest_auth_handlerr   r   rZ   r   )r
   rk   r[   r\   r   r   r   r   ü   s    zFakeProxyHandler.__init__c             G   s   d S )Nr   )r
   r]   r[   r   r   r   r^     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   r_   ZOKzContent-Typez	text/htmlzYou've reached %s!<BR>r+   sF   Our apologies, but our server is down due to a sudden zombie invasion.)ÚurllibÚparseZurlparserT   rU   rk   r   rJ   rK   rL   rM   rN   Úbytes)r
   ZscmZnetlocrT   ÚparamsZqueryZfragmentr   r   r   re     s    zFakeProxyHandler.do_GETN)r   r   r   r   r   r^   re   r   r   r   r   rj   õ   s   rj   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 )ÚBasicAuthTestsrW   rX   Z	IncorrectrY   c                sT   t t| ƒ ¡  dd„ }t|ƒ| _|  | j¡ d| jj | _| j 	¡  | jj
 ¡  d S )Nc              _   s
   t | |ŽS )N)rV   )r[   r\   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)Úsuperrp   ÚsetUpr   r   Ú
addCleanupÚstop_serverr   Ú
server_urlÚstartr   Úwait)r
   rq   )Ú	__class__r   r   rs     s    

zBasicAuthTests.setUpc             C   s   | j  ¡  d | _ d S )N)r   r   )r
   r   r   r   ru   '  s    
zBasicAuthTests.stop_serverc                s   t t| ƒ ¡  d S )N)rr   rp   ÚtearDown)r
   )ry   r   r   rz   +  s    zBasicAuthTests.tearDownc             C   s|   t j ¡ }| | j| j| j| j¡ t j t j 	|¡¡ y|  
t j | j¡¡ W n( t jjk
rv   |  d| j ¡ Y nX d S )Nz!Basic auth failed for the url: %s)rl   r   ÚHTTPBasicAuthHandlerÚadd_passwordra   rv   rf   rg   Úinstall_openerÚbuild_openerÚ
assertTrueÚurlopenÚerrorÚ	HTTPErrorÚfail)r
   Ú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 )N)rl   r   r{   r|   ra   rv   rf   ÚINCORRECT_PASSWDr}   r~   ÚassertRaisesr   r‚   r€   )r
   r„   r   r   r   Útest_basic_auth_httperror7  s    
z(BasicAuthTests.test_basic_auth_httperror)r   r   r   rf   rg   r†   ra   rs   ru   rz   r…   rˆ   Ú__classcell__r   r   )ry   r   rp     s   	rp   c                   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 )N)ÚosÚenvironÚclearrH   )Úold_environr   r   r   Úrestore_environH  s    
z-ProxyAuthTests.setUp.<locals>.restore_environrc   ÚNO_PROXYÚno_proxyc                 s   t ˆ jf| ž|ŽS )N)rj   rk   )r[   r\   )r
   r   r   Úcreate_fake_proxy_handlerS  s    z7ProxyAuthTests.setUp.<locals>.create_fake_proxy_handlerzhttp://127.0.0.1:%dr   )rr   rŠ   rs   rt   r‹   rŒ   Úcopyr    rk   r(   rf   rg   r)   ra   r   r   ru   rw   r   rx   r   rl   r   ZProxyHandlerZProxyDigestAuthHandlerÚproxy_digest_handlerr~   Úopener)r
   r   r’   Z	proxy_urlÚhandler)ry   )r
   r   rs   E  s$    



zProxyAuthTests.setUpc             C   s   | j  ¡  d | _ d S )N)r   r   )r
   r   r   r   ru   `  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|   ra   ÚURLrf   rg   rk   r'   r‡   rl   r   r‚   r•   Úopen)r
   r   r   r   Ú-test_proxy_with_bad_password_raises_httperrord  s    
z<ProxyAuthTests.test_proxy_with_bad_password_raises_httperrorc             C   s(   | j  d¡ |  tjj| jj| j¡ d S )Nr!   )	rk   r'   r‡   rl   r   r‚   r•   r˜   r—   )r
   r   r   r   Ú,test_proxy_with_no_password_raises_httperrorl  s    
z;ProxyAuthTests.test_proxy_with_no_password_raises_httperrorc             C   sN   | j  | j| j| j| j¡ | j d¡ | j 	| j¡}x| 
¡ r@q6W | ¡  d S )Nr!   )r”   r|   ra   r—   rf   rg   rk   r'   r•   r˜   ÚreadÚclose)r
   Úresultr   r   r   Útest_proxy_qop_auth_worksr  s    
z(ProxyAuthTests.test_proxy_qop_auth_worksc             C   st   | j  | j| j| j| j¡ | j d¡ y| j 	| j¡}W n t
jjk
rT   d }Y nX |rpx| ¡ rfq\W | ¡  d S )Nzauth-int)r”   r|   ra   r—   rf   rg   rk   r'   r•   r˜   rl   r   ÚURLErrorr›   rœ   )r
   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—   rf   rg   ra   rs   ru   r™   rš   rž   r    r‰   r   r   )ry   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.   |   ¡ }x |r(| j |¡}||d … }q
W d S )N)Ú	send_headrM   rN   )r
   ÚbodyZdoner   r   r   re   •  s    z8GetRequestHandler.<locals>.FakeHTTPRequestHandler.do_GETc             S   s2   | j d }| j t|ƒ¡}|  ¡  | j |¡ d S )NzContent-Length)rQ   Zrfiler›   Úintre   Úrequestsr1   )r
   Zcontent_lengthZ	post_datar   r   r   Údo_POST›  s    
z9GetRequestHandler.<locals>.FakeHTTPRequestHandler.do_POSTc                s€   | j ˆ _| j | j¡ ˆ d¡\}}}|  |¡ x&|D ]\}}|  ||d| ji ¡ q6W |rt|  dd¡ |  	¡  |S |  	¡  d S )Nr   r   zContent-typez
text/plain)
rQ   Úheaders_receivedr¥   r1   rT   ÚpoprJ   rK   r   rL   )r
   Zresponse_coderQ   r£   Úheaderr@   )ÚFakeHTTPRequestHandlerÚ	responsesr   r   r¢   ¡  s    
z;GetRequestHandler.<locals>.FakeHTTPRequestHandler.send_headc             W   s   d S )Nr   )r
   r[   r   r   r   r^   °  s    z=GetRequestHandler.<locals>.FakeHTTPRequestHandler.log_messageN)r   r   r   Zserver_versionr¥   r§   r   re   r¦   r¢   r^   r   )rª   r«   r   r   rª   Ž  s   rª   )r   r   rZ   )r«   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d,d	d
„Zd-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 ).Ú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                s@   t t| ƒ ¡  dd„ }|  |tj ¡ ¡ dtjd< dtjd< d S )Nc             S   s   t j ¡  t j | ¡ d S )N)r‹   rŒ   r   rH   )rŽ   r   r   r   r   Ä  s    
z*TestUrlopen.setUp.<locals>.restore_environÚ*r   r‘   )rr   r­   rs   rt   r‹   rŒ   r“   )r
   r   )ry   r   r   rs   À  s
    
zTestUrlopen.setUpNc             K   sl   g }t jj||f|Ž}z@| | d¡¡ | | ¡ ¡ | | d¡¡ | | ¡ ¡ W d | ¡  X d 	|¡S )Nr_   i   ó    )
rl   r   r€   ÚextendÚ	readlinesr1   Úreadliner›   rœ   r   )r
   ÚurlÚdatar\   ÚlÚfr   r   r   r€   Ë  s    
zTestUrlopen.urlopenc             C   s   | j  ¡  d | _ d S )N)r   r   )r
   r   r   r   ru   Ø  s    
zTestUrlopen.stop_serverc             C   sZ   |d krdg dfg}t |ƒ}t|ƒ| _|  | j¡ | j ¡  | jj ¡  | jj}||_|S )Nr_   s   we don't care)	r¬   r   r   rt   ru   rw   r   rx   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 kr6dg dfg}t|ƒ}|| fd|i|—Ž}|j|_|S )NZHTTPSHandlerzssl support requiredr   )Úmake_https_serverr_   s   we care a bitZhandler_class)Úhasattrrl   r   ÚskipTestZtest.ssl_serversr¸   r¬   r   )r
   r«   r\   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_elserc   r_   z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
r_   )zTransfer-EncodingZchunkedzhttp://localhost:%s/)r·   r€   r   r½   )r
   r¾   Zchunked_startrG   r–   r´   r   r   r   Útest_chunked  s    
zTestUrlopen.test_chunkedc          
   C   sŒ   d}|   dg |fg¡}y|  d|j ¡ W n6 tjjk
r` } z| ¡ }| ¡  W d d }~X Y nX |  d¡ |  	||¡ |  	|j
dg¡ d S )Ns   Bad bad bad...i”  zhttp://localhost:%s/weeblez404 should raise URLErrorz/weeble)r·   r€   r   rl   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 )Ns   pycon 2008...r_   zhttp://localhost:%s/bizarrez/bizarre)r·   r€   r   r½   r¥   )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 )Ns   pycon 2008...r_   zhttp://localhost:%s/bizarres   get=with_feelingz/bizarre)r·   r€   r   r½   r¥   )r
   r¾   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)Úcafilezhttps://localhost:%s/bizarre)Úcontexts   we care a bit)r»   ÚsslÚcreate_default_contextÚCERT_localhostr€   r   r½   )r
   r–   rÅ   r´   r   r   r   Ú
test_https-  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 Q R X | j td}|  t	j
j¡}| jd|j td W d Q R X W d Q R X d S )N)Úcertfilerc   zhttps://localhost:%s/bizarre)rÄ   s   we care a bit)r»   rÈ   r   Úcheck_warningsÚDeprecationWarningr€   r   r½   r‡   rl   r   rŸ   ÚCERT_fakehostname)r
   r–   r´   Úcmr   r   r   Útest_https_with_cafile3  s    z"TestUrlopen.test_https_with_cafilec          
   C   sX   | j td}t dtf¡4 |  tjj¡}| j	d|j
 dd W d Q R X W d Q R X d S )N)rÊ   rc   zhttps://localhost:%s/bizarreT)Z	cadefault)r»   rÈ   r   rË   rÌ   r‡   rl   r   rŸ   r€   r   )r
   r–   rÎ   r   r   r   Útest_https_with_cadefaultD  s
    z%TestUrlopen.test_https_with_cadefaultc                s†   t d k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 )Nr   )Zssl_sockZserver_nameZinitial_context)Úsni_namer   r   Úcb_sniR  s    z*TestUrlopen.test_https_sni.<locals>.cb_sni)rÅ   rÊ   )rÄ   zhttps://localhost:%s)rÅ   Z	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_sniL  s    


zTestUrlopen.test_https_snic          	   C   sP   |   ¡ }tjjd|j ddid}tj |¡ W d Q R X |  |jd d¡ d S )Nzhttp://localhost:%s/ZRangezbytes=20-39)rQ   )r·   rl   r   ZRequestr   r€   r½   r§   )r
   r–   Zreqr   r   r   Útest_sending_headers\  s    
z TestUrlopen.test_sending_headersc             C   sb   |   ¡ }tj d|j ¡}x"dD ]}|  t||ƒd| ¡ q W z|  | ¡ d¡ W d | ¡  X d S )Nzhttp://localhost:%s)r›   rœ   ÚinfoÚgeturlz3object returned from urlopen lacks the %s attributezcalling 'read' failed)	r·   rl   r   r€   r   r   r¹   r›   rœ   )r
   r–   Úopen_urlÚattrr   r   r   Ú
test_basicd  s    
zTestUrlopen.test_basicc          	   C   sX   |   ¡ }tj d|j ¡}| | ¡ }W d Q R X |  |tjj	d¡ |  
| ¡ d¡ d S )Nzhttp://localhost:%szEobject returned by 'info' is not an instance of email.message.MessageZplain)r·   rl   r   r€   r   rÕ   ZassertIsInstanceÚemailÚmessageZMessager½   Zget_content_subtype)r
   r–   r×   Zinfo_objr   r   r   Ú	test_infoo  s    zTestUrlopen.test_infoc          	   C   sH   |   ¡ }tj d|j ¡}| | ¡ }W d Q R X |  |d|j ¡ d S )Nzhttp://localhost:%s)r·   rl   r   r€   r   rÖ   r½   )r
   r–   r×   r³   r   r   r   Útest_geturlz  s
    zTestUrlopen.test_geturlc             C   sF   d}|   dg |fg¡}tj d|j ¡}x|D ]}|  ||¡ q.W d S )Ns   pycon 2008...r_   zhttp://localhost:%s)r·   rl   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 ¡}x<t|ƒD ]0\}}|  ||| d
|t|| ƒt|ƒf ¡ qLW |  |d t|ƒ¡ d S )Ns   We
s   got
s   here
s	   verylong i    ó   
r¯   r_   zhttp://localhost:%szQFetched line number %s doesn't match expected:
    Expected length was %s, got %sr*   )	r   r·   rl   r   r€   r   Ú	enumerater½   rP   )r
   Úlinesr¾   r–   r´   ÚindexrÞ   r   r   r   Útest_line_iteration‰  s    
zTestUrlopen.test_line_iteration)N)N)N)r   r   r   r   rs   r€   ru   r·   r»   r¿   rÀ   rÁ   rÂ   rÃ   rÉ   rÏ   rÐ   rÓ   rÔ   rÙ   rÜ   rÝ   rß   rä   r‰   r   r   )ry   r   r­   ·  s*   


r­   c               C   s   t  ¡ ad S )N)r   Zthreading_setupÚthreads_keyr   r   r   r   ÚsetUpModule˜  s    ræ   c               C   s   t rtjt Ž  d S )N)rå   r   Zthreading_cleanupr   r   r   r   ÚtearDownModulež  s    rç   Ú__main__))rh   r‹   rÚ   Zurllib.parserl   Zurllib.requestZhttp.serverr   r   Zunittestr,   Ztestr   rÆ   ÚImportErrorrT   ÚdirnameÚ__file__Úherer   rÈ   rÍ   r   r   r   r   r   r    rZ   rV   rj   ZTestCaserp   rŠ   r¬   r­   rå   ræ   rç   r   Úmainr   r   r   r   Ú<module>   s>   
y,!(N+ `
