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Zdd Zdd ZdS )Ś
MockServerzNon-socket HTTP serverc             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__Ś__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S )ŚMockHandlerzNon-socket HTTP handlerc             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   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    r:   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 )a  Utility to compare a generic 2.1/2.2+ iterator with an iterable

    If running under Python 2.2+, this tests the iterator using iter()/next(),
    as well as __getitem__.  'make_it' must be a function returning a fresh
    iterator to be tested (since this may test the iterator twice).r   é   zToo many items from __getitem__zToo many items from .__next__()N)ŚAssertionErrorŚ
IndexErrorŚiterŚStopIterationŚ	NameErrorŚnext)Śmake_itŚmatchŚitŚnŚitemr   r   r   Ścompare_generic_iterR   s4    
 
 
 rG   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
r0   z
Hello, world!z
iso-8859-1)r   r2   ŚversionŚsplitŚassertEqualr.   )r   r8   Ś
has_lengthŚpyverr   r   r   Ścheck_helloy   s    zIntegrationTests.check_helloc             C   s   t  \}}|  |” d S )N)r:   rO   )r   r8   r9   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/)r:   r/   rL   Ś
splitlines)r   r#   r8   r9   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

)r6   r   s!   HTTP/1.0 414 Request-URI Too Long)r:   rL   rR   )r   r8   r9   r   r   r   Śtest_request_length   s    z$IntegrationTests.test_request_lengthc             C   s"   t tt\}}| j|dd d S )NF)rM   )r:   r   r)   rO   )r   r8   r9   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'>)r:   r   Ś
assertTrueŚendswithrL   rR   )r   rW   r8   r9   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   rW   ±   s    zWIntegrationTests.test_status_validation_errors.<locals>.create_bad_app.<locals>.bad_appr   )r\   rW   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.rX   )ŚsubTestr:   rY   rZ   rL   rR   )r   r]   Ztestsr\   Zexc_messager8   r9   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   rW   Å   s    z1IntegrationTests.test_wsgi_input.<locals>.bad_apps;   A server error occurred.  Please contact the administrator.rX   r<   )r:   r   rY   rZ   rL   rR   )r   rW   r8   r9   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   )ra   rb   r   r   r   r5   Ņ   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)
r:   r   rY   rZ   r2   rJ   rK   r.   r   rL   )r   r5   r8   r9   ZverŚpyrN   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.   )ra   rb   r   r   r   r5   ē   s    z-IntegrationTests.test_cp1252_url.<locals>.apps   GET /%80 HTTP/1.0)r6   s   HTTP/1.0 200 OKs   Content-Type: text/plains#   Date: Wed, 24 Dec 2008 13:29:32 GMTó    s   /)r:   r   rL   r   ŚANYrR   )r   r5   r8   r9   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   r5     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   ro   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ŚGETrI   éd   r;   )Ztimeout)r   r   r#   Zgetresponser`   ŚsignalŚSIGUSR1ŚwaitŚfloatŚlenŚclose)ŚhttpZresponse)rr   Śmain_threadrl   Śreceivedr7   r   r   Ś
run_client  s    


z;IntegrationTests.test_interrupted_write.<locals>.run_client)Śtargetru   )r   Zget_attributerv   r   r   r   ZHOSTZ
addCleanupZserver_closeŚ	threadingZEventrw   Ś	get_identZThreadŚstartZhandle_requestr-   rL   rn   )r   r5   ro   rs   Zoriginalr   Z
backgroundr   )rr   r}   rl   r~   r7   r   Śtest_interrupted_writeż   s"    z'IntegrationTests.test_interrupted_writeN)T)r   r   r    rO   rP   rS   rU   rV   r[   r_   rc   rg   rk   r   r   r   r   r   rH   w   s   
rH   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   rL   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   rL   ZassertIs)r   ŚkeyŚvalueŚaltr   r   r   r   ŚcheckDefault9  s    



zUtilityTests.checkDefaultc             K   s   t  |” |  || |” d S )N)r   r   rL   )r   r   r   Śkwr   r   r   ŚcheckCrossDefaultI  s    
zUtilityTests.checkCrossDefaultc             K   s    t  |” |  t  |”|” d S )N)r   r   rL   Zapplication_uri)r   Śurir   r   r   r   ŚcheckAppURIM  s    
zUtilityTests.checkAppURIr;   c             K   s"   t  |” |  t  ||”|” d S )N)r   r   rL   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   rB   W  s    z%UtilityTests.checkFW.<locals>.make_it)rG   ŚassertFalseZfilelikeŚclosedr{   rY   )r   r   r   rC   rB   rD   rF   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 )
Nr0   rI   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/yr0   z//yŚyz/a/b/yz//y/rI   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_METHODrt   )r   r0   )r,   rI   )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¦   )rL   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)rK   ŚtitleŚupperŚlowerrY   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)rL   rz   r   ŚkeysŚvaluesŚitemsZassertIsNotŚ__contains__ŚgetŚget_allŚ__getitem__rY   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   rL   Ś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dZeej ” Zdd Z	dS )ŚErrorHandlerz/Simple handler subclass for testing BaseHandlerc          	   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    r!   ŚdictŚosr'   r¹   Z
os_environr   r   r   r   r   rČ     s   rČ   c               @   s   e Zd ZdZdd ZdS )ŚTestHandlerzASimple handler subclass for testing BaseHandler, w/error passthruc              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   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)rJ   rÉ   rŹ   Zrun_onceŚfile_wrapperrŠ   Zwsgi_zwsgi.)r'   Zwsgi_file_wrapperrL   Ś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¹   rL   Ś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Ł   rL   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   rL   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.   )ra   rb   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.   )ra   rb   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.   )ra   rb   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   )ra   rb   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Ķ   ŚrunrL   Śstdoutr4   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   )ra   rb   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<   )ra   rb   r   r   r   Ś	error_app  s    z4HandlerTests.testBasicErrorOutput.<locals>.error_appz%Status: 200 OK
Content-Length: 0

z
iso-8859-1r0   z<Status: %s
Content-Type: text/plain
Content-Length: %d

r<   )rČ   rę   rL   rē   r4   r.   r3   Zerror_statusrz   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<   )ra   rb   )ŚMSGr   r   rź     s    z4HandlerTests.testErrorAfterOutput.<locals>.error_appzStatus: 200 OK

z
iso-8859-1r<   )rČ   rę   rL   rē   r4   r.   rÕ   r3   )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   )ra   rb   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
r0   )z1.0z1.1)zHTTP/0.9zHTTP/1.0zHTTP/1.1)r    FTzHTTP/0.9ri   )r.   rĶ   Zorigin_serverZhttp_versionZserver_softwarerę   rL   rē   r4   rY   ŚrerC   )	r   ré   ZstdpatZshortpatZsswŚswrJ   Ś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   )ra   rb   r   r   r   r5   Õ  s    z'HandlerTests.testBytesData.<locals>.appsR   Status: 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 4

data)rĶ   rę   rL   rē   r4   )r   r5   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   r{   ī  s    zNHandlerTests.testCloseOnError.<locals>.error_app.<locals>.CrashyIterable.closeN)r   r   r    rō   r{   r   )rõ   r   r   ŚCrashyIterableé  s   rö   )Śobject)ra   rb   rö   )rģ   rõ   r   r   rź   ē  s    z0HandlerTests.testCloseOnError.<locals>.error_appT)rČ   rę   rL   )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é   )Śextendrz   )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   r2   r3   ZassertWarnsRegexŚDeprecationWarningrę   r)   rL   )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   r4   )r   r'   r  r3   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Õ   r4   ZassertIsNotNoneŚresultZheadersr\   r'   )r   r  r3   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ī   rv   r2   r   r   r"   r)   r/   r:   rG   rH   r   r³   rČ   rĶ   rĻ   r   Śmainr   r   r   r   Ś<module>   sL   
% 9 #7  
