B
    u9a9r  ã               @   s´  d dl mZ d dlmZ d dlmZ d dl mZ d dlmZ d dl	m
Z
 d dlmZmZmZ d dlmZ d d	lmZ d d
lmZmZ d dlmZ d dlmZ d dlmZmZmZ d dlm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%Z%d dl Z G dd„ deƒZ&G dd„ deƒZ'dd„ Z(dd„ Z)e(dfdd„Z*dd„ Z+G dd„ deƒZ,G d d!„ d!eƒZ-G d"d#„ d#eƒZ.G d$d%„ d%eƒZ/G d&d'„ d'e/ƒZ0G d(d)„ d)eƒZ1e2d*kr°e  3¡  dS )+é    )Úmock)Úsupport)ÚNoLogRequestHandler)ÚTestCase)Úsetup_testing_defaults)ÚHeaders)ÚBaseHandlerÚBaseCGIHandlerÚSimpleHandler)Úutil)Ú	validator)Ú
WSGIServerÚWSGIRequestHandler)Úmake_server)ÚHTTPConnection)ÚStringIOÚBytesIOÚBufferedReader)Ú
BaseServer)Úpython_implementationNc               @   s   e Zd Zdd„ Zdd„ ZdS )Ú
MockServerc             C   s   t  | ||¡ |  ¡  d S )N)r   Ú__init__Úserver_bind)ÚselfÚserver_addressZRequestHandlerClass© r   ú"/usr/lib/python3.7/test_wsgiref.pyr      s    zMockServer.__init__c             C   s"   | j \}}|| _|| _|  ¡  d S )N)r   Zserver_nameZserver_portÚsetup_environ)r   ZhostZportr   r   r   r       s    
zMockServer.server_bindN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r      s   r   c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚMockHandlerc             C   s   | j | _| j\| _| _d S )N)ÚrequestZ
connectionZrfileZwfile)r   r   r   r   Úsetup)   s    zMockHandler.setupc             C   s   d S )Nr   )r   r   r   r   Úfinish-   s    zMockHandler.finishN)r   r   r    r#   r$   r   r   r   r   r!   '   s   r!   c             C   s   |dddgƒ dgS )Nz200 OK)zContent-Typez
text/plain)ÚDatezMon, 05 Jun 2006 18:49:54 GMTs   Hello, world!r   )ÚenvironÚstart_responser   r   r   Ú	hello_app1   s    r(   c             C   s2   |dddgƒ d  | d | d | d g¡ d¡gS )	Nz200 OK)zContent-Typez
text/plain)r%   zMon, 05 Jun 2006 18:49:54 GMTú;ZHTTP_X_TEST_HEADERÚQUERY_STRINGÚ	PATH_INFOz
iso-8859-1)ÚjoinÚencode)r&   r'   r   r   r   Ú
header_app9   s    r.   s   GET / HTTP/1.0

c             C   sb   t dd| ttƒ}tt|ƒƒ}tƒ }tj}tƒ  }t_z| ||fd¡ W d |t_X | 	¡ | 	¡ fS )NÚ éP   )z	127.0.0.1i¸"  )
r   r   r!   r   r   ÚsysÚstderrr   Zfinish_requestÚgetvalue)ÚappÚdataÚserverZinpÚoutZolderrÚerrr   r   r   Ú	run_amockD   s    r9   c             C   sâ   | ƒ }d}x$|D ]}|| |ks$t ‚|d7 }qW y||  W n tk
rP   Y nX t d|ƒ‚yttf W n tk
r|   Y nbX | ƒ }t|ƒ|k	r”t ‚x|D ]}t|ƒ|ksšt ‚qšW yt|ƒ W n tk
rÒ   Y nX t d|ƒ‚d S )Nr   é   zToo many items from __getitem__zToo many items from .__next__())ÚAssertionErrorÚ
IndexErrorÚiterÚStopIterationÚ	NameErrorÚnext)Úmake_itÚmatchÚitÚnÚitemr   r   r   Úcompare_generic_iterR   s4    
 
 
 rF   c               @   sf   e Z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S )ÚIntegrationTestsTc             C   sF   t ƒ d tj ¡ d  }|  |d| d |r0dp2d d  d¡¡ d S )	Nú/r   z(HTTP/1.0 200 OK
Server: WSGIServer/0.2 zA
Content-Type: text/plain
Date: Mon, 05 Jun 2006 18:49:54 GMT
zContent-Length: 13
r/   z
Hello, world!z
iso-8859-1)r   r1   ÚversionÚsplitÚassertEqualr-   )r   r7   Ú
has_lengthÚpyverr   r   r   Úcheck_helloy   s    zIntegrationTests.check_helloc             C   s   t ƒ \}}|  |¡ d S )N)r9   rN   )r   r7   r8   r   r   r   Útest_plain_hello†   s    
z!IntegrationTests.test_plain_helloc             C   s*   d}t t|ƒ\}}|  | ¡ d d¡ d S )Nsm   GET /p%61th/?query=test HTTP/1.0
X-Test-Header: Python test 
X-Test-Header: Python test 2
Content-Length: 0

éÿÿÿÿs+   Python test,Python test 2;query=test;/path/)r9   r.   rK   Ú
splitlines)r   r"   r7   r8   r   r   r   Útest_environŠ   s
    
zIntegrationTests.test_environc             C   s2   t ddd  d d\}}|  | ¡ d d¡ d S )Ns   GET ó   xi  s    HTTP/1.0

)r5   r   s!   HTTP/1.0 414 Request-URI Too Long)r9   rK   rQ   )r   r7   r8   r   r   r   Útest_request_length—   s    z$IntegrationTests.test_request_lengthc             C   s"   t ttƒƒ\}}| j|dd d S )NF)rL   )r9   r   r(   rN   )r   r7   r8   r   r   r   Útest_validated_helloœ   s    z%IntegrationTests.test_validated_helloc             C   s@   dd„ }t t|ƒƒ\}}|  | d¡¡ |  | ¡ d d¡ d S )Nc             S   s   |ddƒ dgS )Nz200 OK)zContent-Typez
text/plainzHello, world!r   )r&   r'   r   r   r   Úbad_app¢   s    
z>IntegrationTests.test_simple_validation_error.<locals>.bad_apps;   A server error occurred.  Please contact the administrator.éþÿÿÿz^AssertionError: Headers (('Content-Type', 'text/plain')) must be of type list: <class 'tuple'>)r9   r   Ú
assertTrueÚendswithrK   rQ   )r   rV   r7   r8   r   r   r   Útest_simple_validation_error¡   s    
z-IntegrationTests.test_simple_validation_errorc          
   C   st   dd„ }dddg}x\|D ]T\}}| j |d: t||ƒƒ\}}|  | d¡¡ |  | ¡ d |¡ W d Q R X qW d S )	Nc                s   ‡ fdd„}|S )Nc                s   |ˆ dgƒ dgS )N)zContent-Typeztext/plain; charset=utf-8s   Hello, world!r   )r&   r'   )Ústatusr   r   rV   ±   s    zWIntegrationTests.test_status_validation_errors.<locals>.create_bad_app.<locals>.bad_appr   )r[   rV   r   )r[   r   Úcreate_bad_app°   s    zFIntegrationTests.test_status_validation_errors.<locals>.create_bad_app)Z200z4AssertionError: Status must be at least 4 characters)z20X OKz8AssertionError: Status message must begin w/3-digit code)Z200OKz;AssertionError: Status message must have a space after code)r[   s;   A server error occurred.  Please contact the administrator.rW   )ÚsubTestr9   rX   rY   rK   rQ   )r   r\   Ztestsr[   Zexc_messager7   r8   r   r   r   Útest_status_validation_errors¯   s    z.IntegrationTests.test_status_validation_errorsc             C   s@   dd„ }t t|ƒƒ\}}|  | d¡¡ |  | ¡ d d¡ d S )Nc             S   s   | d   ¡  |ddgƒ dgS )Nz
wsgi.inputz200 OK)zContent-Typeztext/plain; charset=utf-8s   data)Úread)ÚeÚsr   r   r   rV   Å   s    z1IntegrationTests.test_wsgi_input.<locals>.bad_apps;   A server error occurred.  Please contact the administrator.rW   r;   )r9   r   rX   rY   rK   rQ   )r   rV   r7   r8   r   r   r   Útest_wsgi_inputÄ   s    z IntegrationTests.test_wsgi_inputc             C   sl   dd„ }t t|ƒƒ\}}|  | d¡¡ tj ¡ d  d¡}tƒ  d¡}|d | }|  	d| d |¡ d S )	Nc             S   s   |dddgƒ dgS )Nz200 OK)zContent-Typeztext/plain; charset=utf-8)r%   zWed, 24 Dec 2008 13:29:32 GMTs   datar   )r`   ra   r   r   r   r4   Ò   s    z3IntegrationTests.test_bytes_validation.<locals>.appz"GET / HTTP/1.0" 200 4
r   Úasciió   /s(   HTTP/1.0 200 OK
Server: WSGIServer/0.2 sV   
Content-Type: text/plain; charset=utf-8
Date: Wed, 24 Dec 2008 13:29:32 GMT

data)
r9   r   rX   rY   r1   rI   rJ   r-   r   rK   )r   r4   r7   r8   ZverÚpyrM   r   r   r   Útest_bytes_validationÑ   s    
z&IntegrationTests.test_bytes_validationc             C   s>   dd„ }t t|ƒdd\}}|  dtjdddd	g| ¡ ¡ d S )
Nc             S   s   |dddgƒ | d   d¡gS )Nz200 OK)zContent-Typez
text/plain)r%   zWed, 24 Dec 2008 13:29:32 GMTr+   Úlatin1)r-   )r`   ra   r   r   r   r4   ç   s    z-IntegrationTests.test_cp1252_url.<locals>.apps   GET /€%80 HTTP/1.0)r5   s   HTTP/1.0 200 OKs   Content-Type: text/plains#   Date: Wed, 24 Dec 2008 13:29:32 GMTó    s   /€€)r9   r   rK   r   ÚANYrQ   )r   r4   r7   r8   r   r   r   Útest_cp1252_urlæ   s    	z IntegrationTests.test_cp1252_urlc                sÒ   t  td¡‰dd„ }G dd„ dttƒ}tt jd||d‰|  ˆj¡ t	 
¡ ‰ ‡ fdd	„}t tj|¡}|  tjtj|¡ d ‰t	 ¡ ‰‡ ‡‡‡‡fd
d„}t	j|d}| ¡  ˆ ¡  | ¡  |  ˆt jd ¡ d S )NÚpthread_killc             S   s   |dg ƒ dt j gS )Nz200 OKó    )r   ÚSOCK_MAX_SIZE)r&   r'   r   r   r   r4     s    
z4IntegrationTests.test_interrupted_write.<locals>.appc               @   s   e Zd ZdS )z<IntegrationTests.test_interrupted_write.<locals>.WsgiHandlerN)r   r   r    r   r   r   r   ÚWsgiHandler  s   rn   r   )Zhandler_classc                s   ˆ   ¡  d S )N)Úset)ZsignumÚframe)Úinterruptedr   r   Úsignal_handler  s    z?IntegrationTests.test_interrupted_write.<locals>.signal_handlerc           	      sp   t ˆjŽ } |  dd¡ |  ¡ @}| d¡ x"ˆˆtjƒ ˆ jtdƒdr,P q,W t	| ¡ ƒ‰W d Q R X |  
¡  d S )NÚGETrH   éd   r:   )Ztimeout)r   r   r"   Zgetresponser_   ÚsignalÚSIGUSR1ÚwaitÚfloatÚlenÚclose)ÚhttpZresponse)rq   Úmain_threadrk   Úreceivedr6   r   r   Ú
run_client  s    


z;IntegrationTests.test_interrupted_write.<locals>.run_client)Útargetrt   )r   Zget_attributeru   r   r   r   ZHOSTZ
addCleanupZserver_closeÚ	threadingZEventrv   Ú	get_identZThreadÚstartZhandle_requestr,   rK   rm   )r   r4   rn   rr   Zoriginalr~   Z
backgroundr   )rq   r|   rk   r}   r6   r   Útest_interrupted_writeý   s"    z'IntegrationTests.test_interrupted_writeN)T)r   r   r    rN   rO   rR   rT   rU   rZ   r^   rb   rf   rj   rƒ   r   r   r   r   rG   w   s   
rG   c               @   sˆ   e Zd Zdd„ Zd!dd„Zdd„ Z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S )#ÚUtilityTestsc             C   sJ   ||dœ}t  |¡ |  t  |¡|¡ |  |d |¡ |  |d |¡ |S )N)ÚSCRIPT_NAMEr+   r+   r…   )r   r   rK   Zshift_path_info)r   Zsn_inZpi_inÚpartZsn_outZpi_outÚenvr   r   r   Ú
checkShift1  s    

zUtilityTests.checkShiftNc             C   s|   i }t  |¡ t|tƒr*|  || t¡ n,t|tƒrF|  || t¡ n|  || |¡ ||i}t  |¡ |  || |¡ d S )N)r   r   Ú
isinstancer   ZassertIsInstancer   rK   ZassertIs)r   ÚkeyÚvalueÚaltr‡   r   r   r   ÚcheckDefault9  s    



zUtilityTests.checkDefaultc             K   s   t  |¡ |  || |¡ d S )N)r   r   rK   )r   rŠ   r‹   Úkwr   r   r   ÚcheckCrossDefaultI  s    
zUtilityTests.checkCrossDefaultc             K   s    t  |¡ |  t  |¡|¡ d S )N)r   r   rK   Zapplication_uri)r   ÚurirŽ   r   r   r   ÚcheckAppURIM  s    
zUtilityTests.checkAppURIr:   c             K   s"   t  |¡ |  t  ||¡|¡ d S )N)r   r   rK   Zrequest_uri)r   r   ZqueryrŽ   r   r   r   ÚcheckReqURIQ  s    
zUtilityTests.checkReqURIc             C   sb   ||fdd„}t ||ƒ |ƒ }|  |jj¡ x|D ]}q2W |  |jj¡ | ¡  |  |jj¡ d S )Nc             S   s   t  t| ƒ|¡S )N)r   ZFileWrapperr   )ÚtextÚsizer   r   r   rA   W  s    z%UtilityTests.checkFW.<locals>.make_it)rF   ÚassertFalseZfilelikeÚclosedrz   rX   )r   r“   r”   rB   rA   rC   rE   r   r   r   ÚcheckFWU  s    

zUtilityTests.checkFWc             C   s^   |   ddddd¡ |   ddddd¡ |   ddd dd¡ |   ddddd¡ |   dd	ddd¡ d S )
Nr/   rH   z/xÚxz/az/x/yz/a/xz/yz/x/)rˆ   )r   r   r   r   ÚtestSimpleShiftsg  s
    zUtilityTests.testSimpleShiftsc             C   sÊ   |   ddddd¡ |   ddddd¡ |   dddd	d¡ |   dd
dd	d¡ |   dddd	d¡ |   dddd	d¡ |   ddddd¡ |   ddddd¡ |   ddddd¡ |   ddddd¡ |   ddd dd¡ d S )Nz/a/bz/../yz..z/az/yr/   z//yÚyz/a/b/yz//y/rH   z/./yz/./y/z///./..//y/.//z/y/z///z/a/b/z/.//z/x//r˜   z/a/b/xz/.)rˆ   )r   r   r   r   ÚtestNormalizedShiftsn  s    z!UtilityTests.testNormalizedShiftsc             C   sJ   xDddddddddd	d
ddt ƒ fdtƒ fdgD ]\}}|  ||¡ q.W d S )N)ÚSERVER_NAMEz	127.0.0.1)ÚSERVER_PORTÚ80)ÚSERVER_PROTOCOLzHTTP/1.0)Ú	HTTP_HOSTz	127.0.0.1)ZREQUEST_METHODrs   )r…   r/   )r+   rH   )zwsgi.version)r:   r   )zwsgi.run_oncer   )zwsgi.multithreadr   )zwsgi.multiprocessr   z
wsgi.inputzwsgi.errors)zwsgi.url_schemer{   )r   r   r   )r   rŠ   r‹   r   r   r   ÚtestDefaults{  s     zUtilityTests.testDefaultsc             C   st   | j dddd | j dddd | j dddd | j ddd	d | j dd
dd | j dddd | j dddd d S )Nr    zfoo.bar)rœ   zwsgi.url_schemeÚhttpsÚon)ÚHTTPSÚ1Úyesr{   Úfoor   rž   Z443)r   )r   r   r   r   ÚtestCrossDefaultsŽ  s    zUtilityTests.testCrossDefaultsc             C   sn   |   t i ¡d¡ |   t ddi¡d¡ |   t ddi¡d¡ |   t ddi¡d¡ |   t ddi¡d¡ d S )Nr{   r¤   r§   r£   r¢   r¦   r¥   )rK   r   Zguess_scheme)r   r   r   r   ÚtestGuessScheme—  s
    zUtilityTests.testGuessSchemec             C   sv   |   d¡ | j ddd | j ddd | j ddd	d
 | j ddd | j dddd | j ddd | j ddd d d S )Nzhttp://127.0.0.1/zhttp://127.0.0.1/spamz/spam)r…   zhttp://127.0.0.1/sp%E4mu   /spÃ¤mzhttp://spam.example.com:2071/zspam.example.com:2071Z2071)r    r   zhttp://spam.example.com/zspam.example.com)rœ   z	127.0.0.1)r    rœ   zhttps://127.0.0.1/r£   )r¤   zhttp://127.0.0.1:8000/Z8000)r   r    )r‘   )r   r   r   r   ÚtestAppURIsž  s    


zUtilityTests.testAppURIsc             C   s¢   |   d¡ | j ddd | j ddd | j dddd	 | j d
ddd	 | j dddd	 | j dddd	 | j ddddd | j ddddd | j dddddd d S )Nzhttp://127.0.0.1/zhttp://127.0.0.1/spamz/spam)r…   zhttp://127.0.0.1/sp%E4mu   /spÃ¤mzhttp://127.0.0.1/spammity/spamz	/spammity)r…   r+   z http://127.0.0.1/spammity/sp%E4mz"http://127.0.0.1/spammity/spam;hamz	/spam;hamz/http://127.0.0.1/spammity/spam;cookie=1234,5678z/spam;cookie=1234,5678z%http://127.0.0.1/spammity/spam?say=nizsay=ni)r…   r+   r*   z'http://127.0.0.1/spammity/spam?s%E4y=nizs%E4y=nir   )r’   )r   r   r   r   ÚtestReqURIs¬  s"    




zUtilityTests.testReqURIsc             C   s   |   ddddg¡ d S )NZ–xyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzéx   ZxxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzZxyzxyzxyzxyzxyzxyzxyzxyzxyzxyz)r—   )r   r   r   r   ÚtestFileWrapper¿  s    zUtilityTests.testFileWrapperc             C   sŒ   xBd  ¡ D ]6}x0|| ¡ | ¡ | ¡ fD ]}|  t |¡¡ q(W q
W xBd  ¡ D ]6}x0|| ¡ | ¡ | ¡ fD ]}|  t |¡¡ qlW qNW d S )NzbConnection Keep-Alive Proxy-Authenticate Proxy-Authorization TE Trailers Transfer-Encoding Upgradez4Accept Cache-Control Date Pragma Trailer Via Warning)rJ   ÚtitleÚupperÚlowerrX   r   Zis_hop_by_hopr•   )r   ZhoprŒ   r   r   r   ÚtestHopByHopÂ  s    zUtilityTests.testHopByHop)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„   /  s   

	r„   c               @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚHeaderTestsc             C   sÎ  dg}|   ttƒ ƒd¡ |   ttg ƒƒd¡ |   tt|d d … ƒƒd¡ |   t|d d … ƒ ¡ dg¡ |   t|d d … ƒ ¡ dg¡ |   t|d d … ƒ ¡ |¡ |  t|ƒ ¡ |¡ tƒ }|d= d|d< xT|j|j|j	|j
fD ]<}|  |dƒ¡ |  |dƒ¡ |  |d	ƒ¡ |  |dƒ¡ qÞW |   |d d¡ d
|d< |   |d	 d
¡ |   | 	d¡d
g¡ |   | dd¡d
¡ |   | dd¡d¡ |   | dd¡d
¡ |   | dd¡d¡ |   |d d
¡ |   |d d¡ d S )N)r˜   rš   r   r:   r˜   rš   r§   ÚbarÚFooZFOOÚbazZwheeZzoo)rK   ry   r   ÚkeysÚvaluesÚitemsZassertIsNotÚ__contains__ÚgetÚget_allÚ__getitem__rX   r•   Ú
setdefault)r   ÚtestÚhÚmr   r   r   ÚtestMappingInterfaceÓ  s4    z HeaderTests.testMappingInterfacec             C   s   |   ttd¡ d S )Nr§   )ÚassertRaisesÚ	TypeErrorr   )r   r   r   r   ÚtestRequireListó  s    zHeaderTests.testRequireListc             C   s€   t ƒ }|  t|ƒd¡ |jdddd |  |d d¡ |  t|ƒd¡ |jddd d	 |  | d¡dd
g¡ |  t|ƒd¡ d S )Nz
r§   r³   Zspam)rµ   zbar; baz="spam"zfoo: bar; baz="spam"

r´   )Zcheesezbar; cheesez*foo: bar; baz="spam"
Foo: bar; cheese

)r   rK   ÚstrZ
add_headerr»   )r   r¿   r   r   r   Ú
testExtrasö  s    

zHeaderTests.testExtrasN)r   r   r    rÁ   rÄ   rÆ   r   r   r   r   r²   Ñ  s    r²   c               @   s"   e Zd Zeej ¡ ƒZdd„ ZdS )ÚErrorHandlerc          	   K   s*   t |ƒ tj| tƒ tƒ tƒ |ddd d S )NT)ÚmultithreadÚmultiprocess)r   r	   r   r   r   )r   rŽ   r   r   r   r     s    zErrorHandler.__init__N)	r   r   r    ÚdictÚosr&   r¸   Z
os_environr   r   r   r   r   rÇ     s   rÇ   c               @   s   e Zd Zdd„ ZdS )ÚTestHandlerc              C   s   ‚ d S )Nr   )r   r   r   r   Úhandle_error  s    zTestHandler.handle_errorN)r   r   r    rÍ   r   r   r   r   rÌ     s   rÌ   c               @   s„   e 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d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS ) ÚHandlerTestsc             C   sJ   |j }x>dD ]6}|dkr$|jd kr$q|  t|d| ƒ|d|  ¡ qW d S )N)rI   rÈ   rÉ   Zrun_onceÚfile_wrapperrÏ   Zwsgi_zwsgi.)r&   Zwsgi_file_wrapperrK   Úgetattr)r   Úhandlerr‡   Úattrr   r   r   ÚcheckEnvironAttrs   s
    
zHandlerTests.checkEnvironAttrsc             C   sr   i }t |ƒ |j}ddlm} x,| ¡ D ] \}}||kr(|  || |¡ q(W x | ¡ D ]\}}|  ||¡ qVW d S )Nr   )r&   )r   r&   rË   r¸   rK   ÚassertIn)r   rÑ   Úemptyr‡   r&   ÚkÚvr   r   r   ÚcheckOSEnviron)  s     zHandlerTests.checkOSEnvironc             C   s<   t dd}| ¡  |  |¡ |  |¡ |  |jd d¡ d S )NÚY)ÚXrÚ   )rÌ   r   rÓ   rØ   rK   r&   )r   r¿   r   r   r   ÚtestEnviron3  s
    


zHandlerTests.testEnvironc             C   s6   t d d d i ƒ}| ¡  xdD ]}|  ||j¡ qW d S )N)zwsgi.url_schemez
wsgi.inputzwsgi.errors)r	   r   rÔ   r&   )r   r¿   rŠ   r   r   r   ÚtestCGIEnviron:  s    
zHandlerTests.testCGIEnvironc             C   sH   t dd}| ¡  |  |jd d¡ t ƒ }| ¡  |  |jd d¡ d S )Nr£   )r¤   zwsgi.url_schemer¢   r{   )rÌ   r   rK   r&   )r   r¿   r   r   r   Ú
testScheme@  s    
  zHandlerTests.testSchemec             C   s:   t ƒ }xdD ]}|  tt||ƒ¡ qW |  t|jd¡ d S )N)Z_flushZ	get_stdinZ
get_stderrZadd_cgi_varsr¾   )r   rÂ   ÚNotImplementedErrorrÐ   Z_write)r   r¿   Únamer   r   r   ÚtestAbstractMethodsF  s    
z HandlerTests.testAbstractMethodsc             C   s¸   dd„ }dd„ }dd„ }dd„ }t ƒ }| |¡ |  |j ¡ d	 d
¡¡ t ƒ }| |¡ |  |j ¡ d d
¡¡ t ƒ }| |¡ |  |j ¡ d¡ t ƒ }| |¡ |  |j ¡ d¡ d S )Nc             S   s   |dg ƒ | d   d¡gS )Nz200 OKzwsgi.url_schemez
iso-8859-1)r-   )r`   ra   r   r   r   Útrivial_app1Q  s    
z4HandlerTests.testContentLength.<locals>.trivial_app1c             S   s   |dg ƒ| d   d¡ƒ g S )Nz200 OKzwsgi.url_schemez
iso-8859-1)r-   )r`   ra   r   r   r   Útrivial_app2U  s    z4HandlerTests.testContentLength.<locals>.trivial_app2c             S   s   |dg ƒ d  d¡gS )Nz200 OKu   Ñ‚ÐµÑÑ‚zutf-8)r-   )r`   ra   r   r   r   Útrivial_app3Y  s    
z4HandlerTests.testContentLength.<locals>.trivial_app3c             S   s   |ddgƒ g S )Nz200 OK)zContent-LengthZ12345r   )r`   ra   r   r   r   Útrivial_app4]  s    z4HandlerTests.testContentLength.<locals>.trivial_app4z)Status: 200 OK
Content-Length: 4

httpz
iso-8859-1zStatus: 200 OK

https-   Status: 200 OK
Content-Length: 8

Ñ‚ÐµÑÑ‚s)   Status: 200 OK
Content-Length: 12345

)rÌ   ÚrunrK   Ústdoutr3   r-   )r   rá   râ   rã   rä   r¿   r   r   r   ÚtestContentLengthN  s,    



zHandlerTests.testContentLengthc             C   sž   dd„ }dd„ }t ƒ }| |¡ |  |j ¡ d d¡¡ |  |j ¡ d¡ t ƒ }| |¡ |  |j ¡ d|jt|j	ƒf  d¡|j	 ¡ |  
d	|j ¡ ¡ d S )
Nc             S   s   |dg ƒ g S )Nz200 OKr   )r`   ra   r   r   r   Únon_error_app‚  s    
z8HandlerTests.testBasicErrorOutput.<locals>.non_error_appc             S   s   t dƒ‚d S )Nz This should be caught by handler)r;   )r`   ra   r   r   r   Ú	error_app†  s    z4HandlerTests.testBasicErrorOutput.<locals>.error_appz%Status: 200 OK
Content-Length: 0

z
iso-8859-1r/   z<Status: %s
Content-Type: text/plain
Content-Length: %d

r;   )rÇ   rå   rK   ræ   r3   r-   r2   Zerror_statusry   Z
error_bodyrÔ   )r   rè   ré   r¿   r   r   r   ÚtestBasicErrorOutput€  s    


z!HandlerTests.testBasicErrorOutputc                sR   d‰ ‡ fdd„}t ƒ }| |¡ |  |j ¡ d d¡ˆ  ¡ |  d|j ¡ ¡ d S )Ns   Some output has been sentc                s   |dg ƒˆ ƒ t dƒ‚d S )Nz200 OKz This should be caught by handler)r;   )r`   ra   )ÚMSGr   r   ré   ž  s    z4HandlerTests.testErrorAfterOutput.<locals>.error_appzStatus: 200 OK

z
iso-8859-1r;   )rÇ   rå   rK   ræ   r3   r-   rÔ   r2   )r   ré   r¿   r   )rë   r   ÚtestErrorAfterOutputœ  s    
z!HandlerTests.testErrorAfterOutputc       	   
   C   s  dd„ }d}d  d¡}xòdD ]ê}|r,d| p.d}xÔd	D ]Ì}xÆd
D ]¾}t|d}d|_||_||_| |¡ |  ||j ¡ ¡ t|d}d|_||_||_| |¡ |dkr¾|  |j ¡ d¡ q@|  	t
 |||f   d¡|j ¡ ¡|||f   d¡|j ¡ f¡ q@W q6W qW d S )Nc             S   s   |dg ƒ g S )Nz200 OKr   )r`   ra   r   r   r   rè   «  s    
z5HandlerTests.testHeaderFormats.<locals>.non_error_appzfHTTP/%s 200 OK\r\nDate: \w{3}, [ 0123]\d \w{3} \d{4} \d\d:\d\d:\d\d GMT\r\n%sContent-Length: 0\r\n\r\nz%Status: 200 OK
Content-Length: 0

z
iso-8859-1)z
FooBar/1.0NzServer: %s
r/   )z1.0z1.1)zHTTP/0.9zHTTP/1.0zHTTP/1.1)rŸ   FTzHTTP/0.9rh   )r-   rÌ   Zorigin_serverZhttp_versionZserver_softwarerå   rK   ræ   r3   rX   ÚrerB   )	r   rè   ZstdpatZshortpatZsswÚswrI   Úprotor¿   r   r   r   ÚtestHeaderFormats©  s4    







zHandlerTests.testHeaderFormatsc             C   s.   dd„ }t ƒ }| |¡ |  d|j ¡ ¡ d S )Nc             S   s   |ddgƒ dgS )Nz200 OK)zContent-Typeztext/plain; charset=utf-8s   datar   )r`   ra   r   r   r   r4   Õ  s    z'HandlerTests.testBytesData.<locals>.appsR   Status: 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 4

data)rÌ   rå   rK   ræ   r3   )r   r4   r¿   r   r   r   ÚtestBytesDataÔ  s
    
zHandlerTests.testBytesDatac                s>   ddi‰d‰ ‡ ‡fdd„}t ƒ }| |¡ |  ˆd d¡ d S )NÚclose_calledFs   Some output has been sentc                s(   |dg ƒˆ ƒ G ‡fdd„dt ƒ}|ƒ S )Nz200 OKc                   s    e Zd Zdd„ Z‡ fdd„ZdS )zHHandlerTests.testCloseOnError.<locals>.error_app.<locals>.CrashyIterablec             s   s   xdV  t dƒ‚qW d S )Ns   blahz This should be caught by handler)r;   )r   r   r   r   Ú__iter__ê  s    zQHandlerTests.testCloseOnError.<locals>.error_app.<locals>.CrashyIterable.__iter__c                s   dˆ d< d S )NTrò   r   )r   )Úside_effectsr   r   rz   î  s    zNHandlerTests.testCloseOnError.<locals>.error_app.<locals>.CrashyIterable.closeN)r   r   r    ró   rz   r   )rô   r   r   ÚCrashyIterableé  s   rõ   )Úobject)r`   ra   rõ   )rë   rô   r   r   ré   ç  s    z0HandlerTests.testCloseOnError.<locals>.error_appT)rÇ   rå   rK   )r   ré   r¿   r   )rë   rô   r   ÚtestCloseOnErrorä  s    
zHandlerTests.testCloseOnErrorc          	      sj   t ƒ ‰ G ‡ fdd„dƒ}ddi}ttƒ |ƒ tj|ƒ}d}|  t|¡ | t¡ W d Q R X |  	dˆ ¡ d S )Nc                   s    e Zd Z‡ fdd„Zdd„ ZdS )z4HandlerTests.testPartialWrite.<locals>.PartialWriterc                s   |d d… }ˆ   |¡ t|ƒS )Né   )Úextendry   )r   ÚbÚpartial)Úwrittenr   r   Úwriteú  s    
z:HandlerTests.testPartialWrite.<locals>.PartialWriter.writec             S   s   d S )Nr   )r   r   r   r   Úflushÿ  s    z:HandlerTests.testPartialWrite.<locals>.PartialWriter.flushN)r   r   r    rý   rþ   r   )rü   r   r   ÚPartialWriterù  s   rÿ   rŸ   zHTTP/1.0zshould not do partial writesss   HTTP/1.0 200 OK
Content-Type: text/plain
Date: Mon, 05 Jun 2006 18:49:54 GMT
Content-Length: 13

Hello, world!)
Ú	bytearrayr
   r   r1   r2   ZassertWarnsRegexÚDeprecationWarningrå   r(   rK   )r   rÿ   r&   r¿   Úmsgr   )rü   r   ÚtestPartialWriteö  s    	zHandlerTests.testPartialWritec          
      sz   ddi}xlt ttfD ]^‰ | jˆ dH G ‡ fdd„dƒ}tƒ }ttƒ |ƒ ||ƒ}| t¡ |  	| 
¡ ¡ W d Q R X qW d S )NrŸ   zHTTP/1.0)Ú	exceptionc                   s   e Zd Z‡ fdd„ZdS )zEHandlerTests.testClientConnectionTerminations.<locals>.AbortingWriterc                s   ˆ ‚d S )Nr   )r   rú   )r  r   r   rý     s    zKHandlerTests.testClientConnectionTerminations.<locals>.AbortingWriter.writeN)r   r   r    rý   r   )r  r   r   ÚAbortingWriter  s   r  )ÚConnectionAbortedErrorÚBrokenPipeErrorÚConnectionResetErrorr]   r   r
   r   rå   r(   r•   r3   )r   r&   r  r2   r¿   r   )r  r   Ú testClientConnectionTerminations  s    

z-HandlerTests.testClientConnectionTerminationsc                s   G dd„ dt ƒ‰ G ‡ fdd„dƒ}tƒ }ddi}ttƒ |ƒ ||ƒ}| t¡ |  d| ¡ ¡ |  |j	¡ |  |j
¡ |  |j¡ |  |j¡ d S )Nc               @   s   e Zd ZdS )zKHandlerTests.testDontResetInternalStateOnException.<locals>.CustomExceptionN)r   r   r    r   r   r   r   ÚCustomException"  s   r
  c                   s   e Zd Z‡ fdd„ZdS )zJHandlerTests.testDontResetInternalStateOnException.<locals>.AbortingWriterc                s   ˆ ‚d S )Nr   )r   rú   )r
  r   r   rý   *  s    zPHandlerTests.testDontResetInternalStateOnException.<locals>.AbortingWriter.writeN)r   r   r    rý   r   )r
  r   r   r  )  s   r  rŸ   zHTTP/1.0)Ú
ValueErrorr   r
   r   rå   r(   rÔ   r3   ZassertIsNotNoneÚresultZheadersr[   r&   )r   r  r2   r&   r¿   r   )r
  r   Ú%testDontResetInternalStateOnException!  s    
z2HandlerTests.testDontResetInternalStateOnExceptionN)r   r   r    rÓ   rØ   rÛ   rÜ   rÝ   rà   rç   rê   rì   rð   rñ   r÷   r  r	  r  r   r   r   r   rÎ     s   	
2+rÎ   Ú__main__)4Zunittestr   r¾   r   Ztest.test_httpserversr   r   Zwsgiref.utilr   Zwsgiref.headersr   Zwsgiref.handlersr   r	   r
   Zwsgirefr   Zwsgiref.validater   Zwsgiref.simple_serverr   r   r   Zhttp.clientr   Úior   r   r   Zsocketserverr   Úplatformr   rË   rí   ru   r1   r€   r   r!   r(   r.   r9   rF   rG   r„   r²   rÇ   rÌ   rÎ   r   Úmainr   r   r   r   Ú<module>   sL   
% 9 #7  
