B
    H/\E                 @   s  d dl mZ d dlmZ ejdd yd dlmZ W n  ek
rT   d dlmZ Y nX d dl	Z	d dl
Z
yd dlmZ W n  ek
r   d dlmZ Y nX d dlZd d	lmZ d dlmZ d dlZd d
lmZmZ d dlmZ d dlmZ d dlmZ dZejZdZdZdZde
j kZ!dddZ"G dd de#Z$dd Z%dd Z&G dd de'Z(e(j)Z*G dd dej+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+Z1G d*d+ d+e+Z2G d,d- d-e+Z3G d.d/ d/e+Z4G d0d1 d1e4Z5G d2d3 d3e+Z6G d4d5 d5e+Z7G d6d7 d7e+Z8G d8d9 d9e+Z9G d:d; d;e+Z:d dl;Ze<ej=d<Z>e>rG d=d> d>e:Z?G d?d@ d@e:Z@e>rG dAdB dBe?e@ZAG dCdD dDe+ZBG dEdF dFe+ZCG dGdH dHeCZDG dIdJ dJe+ZEG dKdL dLeEZFG dMdN dNeEZGG dOdP dPe+ZHG dQdR dRe+ZIG dSdT dTeIZJG dUdV dVe+ZKG dWdX dXe+ZLG dYdZ dZe+ZMG d[d\ d\e+ZNG d]d^ d^e+ZOG d_d` d`e+ZPG dadb dbeKZQG dcdd dde+ZRG dedf dfe+ZSG dgdh dhe+ZTG didj dje+ZUG dkdl dle+ZVG dmdn dne+ZWG dodp dpe+ZXG dqdr dre+ZYG dsdt dtejZZ[G dudv dve+Z\G dwdx dxe+Z]ddydzZ^G d{d| d|ej_Z`G d}d~ d~e+ZaG dd de+ZbG dd de+Zc[,eddkree  dS )    )print_function)monkeyF)Zthread)parse_qsN)StringIO)BytesIO)	validator)PY3PYPY)socket)pywsgi)InputzContent-LengthTz-vZOKzInternal Server Error)   i  c               @   s   e Zd ZdS )ConnectionClosedN)__name__
__module____qualname__ r   r   8lib/python3.7/site-packages/gevent/tests/test__pywsgi.pyr   A   s   r   c             C   s   |   }|st|d}i }x|    }|s2P |d}y|dd\}}W n   td|f   Y nX | dd |D kstd|||f |||< q W ||fS )Nzlatin-1z:    zFailed to split: %rc             S   s   h | ]}|  qS r   )lower).0xr   r   r   	<setcomp>U   s    zread_headers.<locals>.<setcomp>z$Header %r:%r sent more than once: %r)readliner   decodestripsplitprintr   AssertionError)fdZresponse_lineheaderslinekeyvaluer   r   r   read_headersE   s$    

(r$   c             c   s   x|   }| }yt|d}W n   td|   Y nX |dkrd| d}|dksbtt|P | |}|V  | d}|dkstt|qW d S )N   zFailed to parse chunk size: %rr      s   
)r   r   intr   readr   repr)r   r!   Z
chunk_sizeZcrlfdatar   r   r   iread_chunksZ   s     


r+   c               @   sZ   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
edddZdS )Responsec             C   s   || _ || _d | _d| _yf|d d dd\}}| _t|| _|d\}| _|dksdt	t
|| jdks|t	t
| jW n" tk
r   td|   Y nX d S )	NF r&   /HTTP)z1.0z1.1z	Error: %r)status_liner    bodychunksr   reasonr'   codeversionr   r)   	Exceptionr   )selfr1   r    r6   r5   r0   r   r   r   __init__o   s    
zResponse.__init__c             c   s   | j V  | jV  | jV  d S )N)r1   r    r2   )r8   r   r   r   __iter__~   s    zResponse.__iter__c             C   s"   | j j| j| j| j| jf}d| S )Nz0<%s status_line=%r headers=%r body=%r chunks=%r>)	__class__r   r1   r    r2   r3   )r8   argsr   r   r   __str__   s    zResponse.__str__c             C   sL   t |dr*| j|ksHtd| j|| f n| j|ksHtd| j|| f d S )N__contains__z$Unexpected code: %r (expected %r)
%s)hasattrr5   r   )r8   r5   r   r   r   
assertCode   s    
 zResponse.assertCodec             C   s"   | j |kstd| j || f d S )Nz&Unexpected reason: %r (expected %r)
%s)r4   r   )r8   r4   r   r   r   assertReason   s    zResponse.assertReasonc             C   s"   | j |kstd| j || f d S )Nz'Unexpected version: %r (expected %r)
%s)r6   r   )r8   r6   r   r   r   assertVersion   s    zResponse.assertVersionc             C   s.   | j |d}||ks*td|||| f d S )NFz)Unexpected header %r: %r (expected %r)
%s)r    getr   )r8   headerr#   Z
real_valuer   r   r   assertHeader   s    
zResponse.assertHeaderc             C   s:   t |trtr|d}| j|ks6td| j|| f d S )Nasciiz$Unexpected body: %r (expected %r)
%s)
isinstancestrr   encoder2   r   )r8   r2   r   r   r   
assertBody   s    
zResponse.assertBodyr   default1.1Nc             C   sh  t |\}}	| ||	}
|d k	r(|
| |dkr:t|}|d k	rL|
| |d k	r^|
| |
jdkrl|
S |d k	rt|trt	|}|

d| ynd|	ddkrt|	krtd tt||
_d|
j|
_n,t|	krt|	t }|||
_n
| |
_W n*   td	|
  d
d l}|   Y nX |d k	r@|
| |d k	rd||
jksdt||
jf|
S )NrK   d   zContent-LengthchunkedzTransfer-Encoding zhWARNING: server used chunked transfer-encoding despite having Content-Length header (libevent 1.x's bug)    z)Response.read failed to read the body:
%sr   )r$   r@   REASONSrC   rA   rB   r5   rG   r'   rH   rE   CONTENT_LENGTHr   listr+   r3   joinr2   r(   	traceback	print_excrJ   r   )clsr   r5   r4   r6   r2   r3   content_lengthZ_status_liner    r8   ZnumrU   r   r   r   r(      sH    






 


zResponse.read)r   rK   rL   NNN)r   r   r   r9   r:   r=   r@   rA   rB   rE   rJ   classmethodr(   r   r   r   r   r,   m   s    r,   c                   s   e Zd ZdZeeZdZdZdZdd Z	dd Z
dd	 ZejrXejrXd
d Z fddZdd Zdd Zdd Zdd Z  ZS )TestCaseNrO   Z	localhostc             C   s   dd l }|d}|S )Nr   zgevent.pywsgi)loggingZ	getLogger)r8   r[   loggerr   r   r   init_logger   s    
zTestCase.init_loggerc             C   s,   |    }| _tj| jdf|||d| _d S )Nr   )logZ	error_log)r]   r\   r   
WSGIServerlisten_addrserver)r8   applicationr\   r   r   r   init_server   s    zTestCase.init_serverc             C   sH   | j }| jd k	r| |}| | | j  | jj| _tj	|  d S )N)
rb   r   rc   ra   startZserver_portport	greentestrZ   setUp)r8   rb   r   r   r   rg      s    




zTestCase.setUpc             C   s   | j t| |S )N)close_on_teardownappendweakrefref)r8   resourcer   r   r   _close_on_teardown   s    zTestCase._close_on_teardownc                s$   dd | j D | _ tt|   d S )Nc             S   s   g | ]}| d k	r| qS )Nr   )r   rr   r   r   
<listcomp>   s    z5TestCase._tearDownCloseOnTearDown.<locals>.<listcomp>)rh   superrZ   _tearDownCloseOnTearDown)r8   )r;   r   r   rq      s    z!TestCase._tearDownCloseOnTearDownc          	   C   sB   t j|  | jd k	r8tjd | j  W d Q R X d | _d S )Ng      ?)rf   rZ   tearDownra   geventTimeout	start_newstop)r8   r   r   r   rr      s
    
zTestCase.tearDownc                sX   t jjf    }trT jfddG  fdddt}| }|S )Nc                 s`   d|kr| d|d< d|kr(| |S d|d< | |}|j  fdd}||_| |S )Nbufsize	bufferingmodeZrwbc                s   t | tr| d}  | S )NrF   )rG   rH   rI   )r*   )_rconn_writer   r   write  s    

z1TestCase.connect.<locals>.makefile.<locals>.write)popr{   rm   )r<   kwargsZrconnr{   )conn_makefiler8   )rz   r   makefile  s    


z"TestCase.connect.<locals>.makefilec                   s   e Zd Z fddZdS )zTestCase.connect.<locals>.proxyc                s   |dkrS t  |S )Nr   )getattr)r8   name)connr   r   r   __getattribute__  s    z0TestCase.connect.<locals>.proxy.__getattribute__N)r   r   r   r   r   )r   r   r   r   proxy  s   r   )r
   Zcreate_connectionconnect_addrre   rm   r   r   object)r8   resultr   r   )r   r~   r   r8   r   connect  s    
zTestCase.connectc             C   s   |   jddS )Nr   )rw   )r   r   )r8   r   r   r   r   %  s    zTestCase.makefilec             O   s*   |   jdd}|d t|f||S )Nr   )rw   z#GET / HTTP/1.1
Host: localhost

)r   r   r{   	read_http)r8   r<   r}   r   r   r   r   urlopen(  s    
zTestCase.urlopen)r   r   r   ra   staticmethodr   rb   r`   r   r]   rc   rg   rf   ZCPYTHONZPY2rm   rq   rr   r   r   r   __classcell__r   r   )r;   r   rZ      s   	$rZ   c               @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
CommonTestsc             C   sr   |   }|d t|dd}|jddkr6ts6d S |d t|ddd	d
 |d t|dd |  d S )Nz#GET / HTTP/1.1
Host: localhost

zhello world)r2   
Connectionclosez+GET /notexist HTTP/1.1
Host: localhost

i  z	Not Foundz	not found)r5   r4   r2   )r   r{   r   r    rC   server_implements_pipeliner   )r8   r   responser   r   r   
test_basic0  s    


zCommonTests.test_basicc          
   C   s   t sd S |  }|d t|dd td}y<tjjd|d}zt|ddd	d
 |  W d |  X W n, tk
r } z||k	r W d d }~X Y nX d S )NzNGET / HTTP/1.1
Host: localhost

GET /notexist HTTP/1.1
Host: localhost

zhello world)r2   z@HTTP pipelining not supported; the second request is thrown awayg      ?)	exceptioni  z	Not Foundz	not found)r5   r4   r2   )	r   r   r{   r   r   rs   rt   ru   r   )r8   r   r   Ztimeoutexr   r   r   test_pipeline<  s    
zCommonTests.test_pipelinec          
   C   s   |   }|d t|}|jddkr2ts2d S |d t| |d y| }W n4 tjk
r } z|j	d t
kr~ W d d }~X Y nX | |d|f  d S )Nz#GET / HTTP/1.1
Host: localhost

r   r   z6GET / HTTP/1.1
Host: localhost
Connection: close

r   zCThe remote side is expected to close the connection, but it sent %r)r   r{   r   r    rC   r   r   r
   errorr<   CONN_ABORTED_ERRORSassertFalse)r8   r   r   r   r   r   r   r   test_connection_closeN  s     


z!CommonTests.test_connection_closec             C   sr   |   }g }xtdD ]}|d qW d|}d| }|| | }|dd }| |d |  d S )Ni  pathr/   z%GET /%s HTTP/1.0
Host: localhost

r.   r   Z414)	r   rangeri   rT   r{   r   r   assertEqualr   )r8   r   
path_parts_r   requestr   statusr   r   r   SKIP_test_006_reject_long_urlsc  s    

z*CommonTests.SKIP_test_006_reject_long_urlsN)r   r   r   r   r   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 )TestNoChunksNc             C   sH   |  |d |d }|dkr4|ddg ddgS |ddg d	d
gS )Nzwsgi.input_terminated	PATH_INFOr/   z200 OK)zContent-Typez
text/plains   hello s   worldz404 Not Founds   not s   found)
assertTruerC   )r8   envstart_responser   r   r   r   rb   v  s    zTestNoChunks.applicationc             C   sx   |   }|d t|dd}| |j |dd tsB|   }|d t|ddd	d
}| |j |dd d S )Nz#GET / HTTP/1.1
Host: localhost

zhello world)r2   zContent-Length11z,GET /not-found HTTP/1.1
Host: localhost

i  z	Not Foundz	not found)r5   r4   r2   9)r   r{   r   r   r3   rE   r   )r8   r   r   r   r   r   test  s    

zTestNoChunks.test)r   r   r   r   rb   r   r   r   r   r   r   q  s   	r   c               @   s   e Zd Zdd ZdS )TestExplicitContentLengthc             C   sL   |  |d |d }|dkr6|dddg ddgS |d	dd
g ddgS )Nzwsgi.input_terminatedr   r/   z200 OK)zContent-Typez
text/plain)zContent-Lengthr   s   hello s   worldz404 Not Found)zContent-Lengthr   s   not s   found)r   rC   )r8   r   r   r   r   r   r   rb     s    z%TestExplicitContentLength.applicationN)r   r   r   rb   r   r   r   r   r     s   r   c               @   s   e Zd Zedd ZdS )	TestYieldc             c   s:   | d }|dkr$|ddg dV  n|ddg dV  d S )Nr   r/   z200 OK)zContent-Typez
text/plains   hello worldz404 Not Founds	   not foundr   )r   r   r   r   r   r   rb     s    zTestYield.applicationN)r   r   r   r   rb   r   r   r   r   r     s   r   c               @   s   e Zd ZdZedd ZdS )TestBytearrayNc             C   sB   | d }|dkr,|ddg t dt dgS |ddg t dgS )	Nr   r/   z200 OK)zContent-Typez
text/plains   hello s   worldz404 Not Founds	   not found)	bytearray)r   r   r   r   r   r   rb     s    zTestBytearray.application)r   r   r   r   r   rb   r   r   r   r   r     s   r   c               @   s    e Zd Zedd Zdd ZdS )MultiLineHeaderc             C   s"   d| d kst |ddg dgS )Nztest.submitCONTENT_TYPEz200 OK)zContent-Typez
text/plains   ok)r   )r   r   r   r   r   rb     s    zMultiLineHeader.applicationc             C   s(   d d}|  }|| t| dS )z
issue #116z
)zPOST / HTTP/1.0zHost: localhostz9Content-Type: multipart/related; boundary="====XXXX====";z$ type="text/xml";start="test.submit"zContent-Length: 0rO   rO   N)rT   r   r{   r   )r8   r   r   r   r   r   test_multiline_116  s
    
z"MultiLineHeader.test_multiline_116N)r   r   r   r   rb   r   r   r   r   r   r     s   r   c               @   s    e Zd Zedd Zdd ZdS )
TestGetArgc             C   sR   | d  d}tr|d}t|ddgd }|ddg d	||f dgS )
Nz
wsgi.input   rF   ar   r   z200 OK)zContent-Typez
text/plainza is %s, body is %s)r(   r   r   r   rC   rI   )r   r   r2   r   r   r   r   rb     s    
zTestGetArg.applicationc             C   s>   |   }dd}|| |d t|dd |  d S )Nz
)zPOST / HTTP/1.0zHost: localhostzContent-Length: 3rO   za=aZ01234567890123456789za is a, body is a=a)r2   )r   rT   r{   r   r   )r8   r   r   r   r   r   test_007_get_arg  s    

zTestGetArg.test_007_get_argN)r   r   r   r   rb   r   r   r   r   r   r     s   	r   c               @   s4   e Zd ZdZdd Zdd ZdZdd Zd	d
 ZdS )TestCloseIterNc             C   s   |ddg | S )Nz200 OK)zContent-Typez
text/plainr   )r8   r   r   r   r   r   rb     s    zTestCloseIter.applicationc             c   s   t dV  dV  d S )Ns   Hello World   !)r   )r8   r   r   r   r:     s    
zTestCloseIter.__iter__Fc             C   s   |  j d7  _ d S )Nr   )closed)r8   r   r   r   r     s    zTestCloseIter.closec             C   s<   d| _ |  }|d t|dddgd | | j d d S )NFz#GET / HTTP/1.1
Host: localhost

s   Hello World!s   Hello Worldr   )r2   r3   r   )r   r   r{   r   r   )r8   r   r   r   r   test_close_is_called  s
    
z"TestCloseIter.test_close_is_called)	r   r   r   r   rb   r:   r   r   r   r   r   r   r   r     s   r   c               @   s6   e Zd ZdddgZdd Zdd Zdd	 Zd
d ZdS )TestChunkedApps   thiss   iss   chunkedc             C   s   d | jS )NrP   )rT   r3   )r8   r   r   r   r2     s    zTestChunkedApp.bodyc             c   s6   |  |d |ddg x| jD ]
}|V  q$W d S )Nzwsgi.input_terminatedz200 OK)zContent-Typez
text/plain)r   rC   r3   )r8   r   r   chunkr   r   r   rb   
  s    zTestChunkedApp.applicationc             C   s|   |   }|d t||  d d}trF|dd | |j| j n2|dd |dtt	|   | |jd d S )Nz6GET / HTTP/1.1
Host: localhost
Connection: close

)r2   r3   zTransfer-EncodingrN   FzContent-Length)
r   r{   r   r2   server_implements_chunkedrE   r   r3   rH   len)r8   r   r   r   r   r   test_chunked_response  s    
z$TestChunkedApp.test_chunked_responsec             C   sp   |   }|d t|}| |j|   | |jdd  |jd}|d k	rl| |tt|   d S )Nz6GET / HTTP/1.0
Host: localhost
Connection: close

zTransfer-EncodingzContent-Length)	r   r{   r   r   r2   r    rC   rH   r   )r8   r   r   rX   r   r   r   test_no_chunked_http_1_0  s    
z'TestChunkedApp.test_no_chunked_http_1_0N)r   r   r   r3   r2   rb   r   r   r   r   r   r   r     s
   
r   c               @   s   e Zd Zdd gd ZdS )TestBigChunks   ai    r   N)r   r   r   r3   r   r   r   r   r   '  s   r   c               @   s$   e Zd Zdd Zdd Zdd ZdS )TestNegativeReadc             C   s@   |  |d |ddg |d dkr<|d d}|gS d S )Nzwsgi.input_terminatedz200 OK)zContent-Typez
text/plainr   z/readz
wsgi.input)r   rC   r(   )r8   r   r   r*   r   r   r   rb   -  s
    zTestNegativeRead.applicationc             C   s&   |   }d}|| t|dd d S )Nsl   POST /read HTTP/1.1
Host: localhost
Connection: close
Transfer-Encoding: chunked

2
oh
4
 hai
0

zoh hai)r2   )r   r{   r   )r8   r   r*   r   r   r   test_negative_chunked_read4  s    
z+TestNegativeRead.test_negative_chunked_readc             C   s&   |   }d}|| t|dd d S )NsT   POST /read HTTP/1.1
Host: localhost
Connection: close
Content-Length: 6

oh haizoh hai)r2   )r   r{   r   )r8   r   r*   r   r   r   test_negative_nonchunked_read<  s    
z.TestNegativeRead.test_negative_nonchunked_readN)r   r   r   rb   r   r   r   r   r   r   r   +  s   r   c               @   s,   e Zd ZdZedd Zdd Zdd ZdS )TestNegativeReadlineNc             C   s0   |ddg | d dkr,| d  d}|gS d S )Nz200 OK)zContent-Typez
text/plainr   z	/readlinez
wsgi.inputr   )r   )r   r   r*   r   r   r   rb   H  s    z TestNegativeReadline.applicationc             C   s&   |   }d}|| t|dd d S )Nsp   POST /readline HTTP/1.1
Host: localhost
Connection: close
Transfer-Encoding: chunked

2
oh
4
 hai
0

zoh hai)r2   )r   r{   r   )r8   r   r*   r   r   r   test_negative_chunked_readlineO  s    
z3TestNegativeReadline.test_negative_chunked_readlinec             C   s&   |   }d}|| t|dd d S )NsX   POST /readline HTTP/1.1
Host: localhost
Connection: close
Content-Length: 6

oh haizoh hai)r2   )r   r{   r   )r8   r   r*   r   r   r   !test_negative_nonchunked_readlineW  s    
z6TestNegativeReadline.test_negative_nonchunked_readline)r   r   r   r   r   rb   r   r   r   r   r   r   r   E  s   r   c               @   sD   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S )TestChunkedPostc                s   |   d |ddg  d dkr< d d}|gS  d dkrhd	d
 t fdddD }|S  d dkrdd
 t fdddD S d S )Nzwsgi.input_terminatedz200 OK)zContent-Typez
text/plainr   z/az
wsgi.input   z/bc             S   s   g | ]}|qS r   r   )r   r   r   r   r   ro   k  s    z/TestChunkedPost.application.<locals>.<listcomp>c                  s    d  dS )Nz
wsgi.inputr   )r(   r   )r   r   r   <lambda>k  s    z-TestChunkedPost.application.<locals>.<lambda>rP   z/cc             S   s   g | ]}|qS r   r   )r   r   r   r   r   ro   o  s    c                  s    d  dS )Nz
wsgi.inputr   )r(   r   )r   r   r   r   o  s    )r   rC   r(   iter)r8   r   r   r*   linesr   )r   r   rb   c  s    zTestChunkedPost.applicationc             C   sr   |   }d}|| t|dd |   }||dd t|dd |   }||dd t|dd d S )Nsi   POST /a HTTP/1.1
Host: localhost
Connection: close
Transfer-Encoding: chunked

2
oh
4
 hai
0

zoh hai)r2   s   /as   /bs   /c)r   r{   r   replace)r8   r   r*   r   r   r   test_014_chunked_postq  s    
z%TestChunkedPost.test_014_chunked_postc             C   s&   d}|   }|| t|dd d S )Nst   POST /a HTTP/1.1
Host: localhost
Connection: close
Content-Length: 12
Transfer-Encoding: chunked

{"hi": "ho"}i  )r5   )r   r{   r   )r8   r*   r   r   r   r   #test_229_incorrect_chunk_no_newline  s    
z3TestChunkedPost.test_229_incorrect_chunk_no_newlinec             C   s&   d}|   }|| t|dd d S )Nsv   POST /a HTTP/1.1
Host: localhost
Connection: close
Content-Length: 12
Transfer-Encoding: chunked

{"hi": "ho"}
i  )r5   )r   r{   r   )r8   r*   r   r   r   r    test_229_incorrect_chunk_non_hex  s    
z0TestChunkedPost.test_229_incorrect_chunk_non_hexc             C   s&   d}|   }|| t|dd d S )Nsw   POST /a HTTP/1.1
Host: localhost
Connection: close
Transfer-Encoding: chunked

2;token="oh hi"
oh
4
 hai
0

zoh hai)r2   )r   r{   r   )r8   r*   r   r   r   r   !test_229_correct_chunk_quoted_ext  s    
z1TestChunkedPost.test_229_correct_chunk_quoted_extc             C   s&   d}|   }|| t|dd d S )Nsu   POST /a HTTP/1.1
Host: localhost
Connection: close
Transfer-Encoding: chunked

2;token=oh_hi
oh
4
 hai
0

zoh hai)r2   )r   r{   r   )r8   r*   r   r   r   r    test_229_correct_chunk_token_ext  s    
z0TestChunkedPost.test_229_correct_chunk_token_extc             C   s6   d}| ddd }|  }|| t|dd d S )Nsu   POST /a HTTP/1.1
Host: localhost
Connection: close
Transfer-Encoding: chunked

2;token=oh_hi
oh
4
 hai
0

s   oh_his   _oh_hii  i  )r5   )r   r   r{   r   )r8   r*   r   r   r   r   +test_229_incorrect_chunk_token_ext_too_long  s
    
z;TestChunkedPost.test_229_incorrect_chunk_token_ext_too_longN)
r   r   r   rb   r   r   r   r   r   r   r   r   r   r   r   `  s   r   c               @   sD   e Zd ZdZdZeeee Zdd Zdd Z	dd Z
d	d
 ZdS )TestUseWrites   abcdes   endc             C   s   |d dkr,|ddd| j fg}|| j nZ|d dkrP|ddg}|| j n6|d dkr~|ddg}|| j || j ntd| jgS )	Nr   z/explicit-content-lengthz200 OK)zContent-Typez
text/plainzContent-Lengthz/no-content-lengthz/no-content-length-twicezInvalid url)rX   r2   r7   end)r8   r   r   r{   r   r   r   rb     s    
zTestUseWrite.applicationc             C   sD   |   }|d t|| j| j d}|d| j |dd d S )NzMGET /explicit-content-length HTTP/1.1
Host: localhost
Connection: close

)r2   zContent-LengthzTransfer-EncodingF)r   r{   r   r2   r   rE   rX   )r8   r   r   r   r   r   test_explicit_content_length  s
    
z)TestUseWrite.test_explicit_content_lengthc             C   sV   |   }|d t|| j| j d}trD|dd |dd n|d| j d S )NzGGET /no-content-length HTTP/1.1
Host: localhost
Connection: close

)r2   zContent-LengthFzTransfer-EncodingrN   )r   r{   r   r2   r   r   rE   rX   )r8   r   r   r   r   r   test_no_content_length  s    
z#TestUseWrite.test_no_content_lengthc             C   s~   |   }|d t|| j| j | j d}trj|dd |dd |j| j| j| jgkszt|jn|dt	d d S )NzMGET /no-content-length-twice HTTP/1.1
Host: localhost
Connection: close

)r2   zContent-LengthFzTransfer-EncodingrN      )
r   r{   r   r2   r   r   rE   r3   r   rH   )r8   r   r   r   r   r   test_no_content_length_twice  s    
"z)TestUseWrite.test_no_content_length_twiceN)r   r   r   r2   r   rH   r   rX   rb   r   r   r   r   r   r   r   r     s   
r   c               @   sR   e Zd ZejejedZejejedZ	dd Z
dddZd	d
 ZdS )HttpsTestCaseztest_server.crtztest_server.keyc             C   s"   t j| jdf|| j| jd| _d S )Nr   )certfilekeyfile)r   r_   r`   r   r   ra   )r8   rb   r   r   r   rc     s    zHttpsTestCase.init_serverGETNc             K   s   dd l }|  }||}|jdd}|d|  |d k	rp|dt|  || |dd krz||d< n
|d |  zt|f|S |	  |	  |	  X d S )Nr   r   )rw   z %s / HTTP/1.1
Host: localhost
zContent-Length: %s

r2   z
)
sslr   Zwrap_socketr   r{   r   rC   flushr   r   )r8   method	post_bodyr}   r   Zraw_socksockr   r   r   r   r     s"    



zHttpsTestCase.urlopenc             C   s4   |d dkst |d |ddg |d dgS )Nzwsgi.url_schemeZhttpsz200 OK)zContent-Typez
text/plainz
wsgi.input
   )r   r(   )r8   environr   r   r   r   rb     s    zHttpsTestCase.application)r   N)r   r   r   osr   rT   dirname__file__r   r   rc   r   rb   r   r   r   r   r     s
   
r   Zcreate_default_contextc               @   s   e Zd Zdd ZdS )HttpsSslContextTestCasec             C   s@   ddl m} | }|j| j| jd tj| jdf||d| _d S )Nr   )_create_unverified_context)r   r   )Zssl_context)	
gevent.sslr   Zload_cert_chainr   r   r   r_   r`   ra   )r8   rb   r   contextr   r   r   rc     s
    z#HttpsSslContextTestCase.init_serverN)r   r   r   rc   r   r   r   r   r     s   r   c               @   s&   e Zd Zeedr"dd Zdd ZdS )	TestHttpsr   c             C   s    | j ddd}| |jd d S )NZPOSTabc)r   r   )r   r   r2   )r8   r   r   r   r   test_012_ssl_server#  s    zTestHttps.test_012_ssl_serverc             C   s   |   }| |jd d S )NrO   )r   r   r2   )r8   r   r   r   r   test_013_empty_return'  s    zTestHttps.test_013_empty_returnN)r   r   r   r?   r
   r   r   r   r   r   r   r     s   
r   c               @   s   e Zd ZdS )TestHttpsWithContextN)r   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 )TestInternationalNc             C   sB   d}t r|d}| |d | | |d d |ddg g S )Ns   /приветzlatin-1r   ZQUERY_STRINGzC%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81=%D0%BE%D1%82%D0%B2%D0%B5%D1%82z
200 PASSED)zContent-Typez
text/plain)r   r   r   )r8   r   r   Z
path_bytesr   r   r   rb   2  s    
zTestInternational.applicationc             C   s4   |   }|ddd t| ddddd d S )	Ns   GET /%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82?%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81=%D0%BE%D1%82%D0%B2%D0%B5%D1%82 HTTP/1.1
Host: localhost
Connection: close

   
s   
PASSEDFrO   r   )r4   r3   r2   rX   )r   sendallr   r   r   )r8   r   r   r   r   r   =  s    zTestInternational.test)r   r   r   r   rb   r   r   r   r   r   r   /  s   r   c                   sH   e Zd ZdZdZdZeZ fddZ fddZ	dd	 Z
d
d Z  ZS )"TestNonLatin1HeaderFromApplicationFNs   Ὂ3c                s   t t|   g | _d S )N)rp   r   rg   errors)r8   )r;   r   r   rg   N  s    z(TestNonLatin1HeaderFromApplication.setUpc                s   g | _ tt|   d S )N)r   rp   r   rr   )r8   )r;   r   r   rr   R  s    z+TestNonLatin1HeaderFromApplication.tearDownc             C   sD   y|ddd| j fg W n&   | jt d d   Y nX g S )Nz
200 PASSED)zContent-Typez
text/plainzCustom-Headerr&   )rD   r   ri   sysexc_info)r8   r   r   r   r   r   rb   V  s    z.TestNonLatin1HeaderFromApplication.applicationc             C   s   |   }|   |d | jrnt| ddd | jtjd | 	t
| jd | jd \}}| |t n$t| dd	d | 	t
| jd d S )
Ns   GET / HTTP/1.1

i  zInternal Server Error)r5   r4   )Z
where_typer   r   r   r   )r   expect_one_errorr   should_errorr   r   assert_errorr   SecureEnvironr   r   r   assertIsInstanceUnicodeError)r8   r   r   vr   r   r   r   a  s    
z'TestNonLatin1HeaderFromApplication.test)r   r   r   error_fatalr   rD   r   r   rg   rr   rb   r   r   r   r   )r;   r   r   G  s   r   c               @   s   e Zd ZdZdZdS ))TestNonLatin1UnicodeHeaderFromApplicationu   Ὂ3TN)r   r   r   rD   r   r   r   r   r   r  p  s   r  c               @   s    e Zd ZdZdd Zdd ZdS )TestInputReadlineNc             C   sd   |d }g }x6|  }|sP tr*|dn|}|t|d  qW |dg  tr`dd |D S |S )Nz
wsgi.inputrF   r.   z	200 helloc             S   s   g | ]}| d qS )rF   )rI   )r   lr   r   r   ro     s    z1TestInputReadline.application.<locals>.<listcomp>)r   r   r   ri   r)   )r8   r   r   inputr   r!   r   r   r   rb     s    
zTestInputReadline.applicationc             C   s<   |   }d}|dt||f  |  t|ddd d S )Nzhello

world
123zMPOST / HTTP/1.1
Host: localhost
Connection: close
Content-Length: %s

%shelloz'hello\n' '\n' 'world\n' '123' )r4   r2   )r   r{   r   r   r   )r8   r   Zcontentr   r   r   r     s    zTestInputReadline.test)r   r   r   r   rb   r   r   r   r   r   r  x  s   r  c               @   s   e Zd Zdd ZdS )TestInputIterc             C   sd   |d }g }x6|D ].}|sP t r*|dn|}|t|d  qW |dg  t r`dd |D S |S )Nz
wsgi.inputrF   r.   z	200 helloc             S   s   g | ]}| d qS )rF   )rI   )r   r  r   r   r   ro     s    z-TestInputIter.application.<locals>.<listcomp>)r   r   ri   r)   )r8   r   r   r  r   r!   r   r   r   rb     s    

zTestInputIter.applicationN)r   r   r   rb   r   r   r   r   r    s   r  c               @   s   e Zd Zdd ZdS )TestInputReadlinesc             C   sH   |d }dd |  D }dd |D }|dg  trDdd |D S |S )Nz
wsgi.inputc             S   s   g | ]}t r|d n|qS )rF   )r   r   )r   r  r   r   r   ro     s    z2TestInputReadlines.application.<locals>.<listcomp>c             S   s   g | ]}t |d  qS )r.   )r)   )r   r!   r   r   r   ro     s    z	200 helloc             S   s   g | ]}| d qS )rF   )rI   )r   r  r   r   r   ro     s    )	readlinesr   )r8   r   r   r  r   r   r   r   rb     s
    
zTestInputReadlines.applicationN)r   r   r   rb   r   r   r   r   r    s   r  c               @   s    e Zd ZdZdd Zdd ZdS )
TestInputNNc             C   s   |d  d |dg  g S )Nz
wsgi.input   z200 OK)r(   )r8   r   r   r   r   r   rb     s    
zTestInputN.applicationc             C   s   |    d S )N)r   )r8   r   r   r   r     s    zTestInputN.test)r   r   r   r   rb   r   r   r   r   r   r	    s   r	  c               @   s&   e Zd Ze ZdZdd Zdd ZdS )	TestErrorFc             C   s   t d| _| jd S )NzTestError.application)rf   ExpectedExceptionr   )r8   r   r   r   r   r   rb     s    zTestError.applicationc             C   s(   |    | jdd | tj| j d S )Ni  )r5   )r   r   r   rf   r  r   )r8   r   r   r   r     s    zTestError.testN)r   r   r   r   r   r   rb   r   r   r   r   r   r    s   r  c               @   s   e Zd Zdd ZdS )TestError_after_start_responsec             C   s"   t d| _|ddg | jd S )Nz*TestError_after_start_response.applicationz200 OK)zContent-Typez
text/plain)rf   r  r   )r8   r   r   r   r   r   rb     s    z*TestError_after_start_response.applicationN)r   r   r   rb   r   r   r   r   r    s   r  c               @   s    e Zd Zedd Zdd ZdS )TestEmptyYieldc             c   s   |ddg dV  dV  d S )Nz200 OK)zContent-Typez
text/plainrP   r   )r   r   r   r   r   rb     s    zTestEmptyYield.applicationc             C   sT   |   jdd}|d tr$g }nd}t|d|d | }| |dd|  d S )	Nr   )rw   z6GET / HTTP/1.1
Host: localhost
Connection: close

FrO   )r2   r3   rP   zgot garbage: %r)r   r   r{   r   r   r(   r   )r8   r   r3   garbager   r   r   test_err  s    
zTestEmptyYield.test_errN)r   r   r   r   rb   r  r   r   r   r   r    s   r  c               @   s    e Zd Zedd Zdd ZdS )TestFirstEmptyYieldc             c   s   |ddg dV  dV  d S )Nz200 OK)zContent-Typez
text/plainrP   s   hellor   )r   r   r   r   r   rb     s    zTestFirstEmptyYield.applicationc             C   sX   |   jdd}|d tr&dg}nd}t|d|d | }| |dkd	|  d S )
Nr   )rw   z6GET / HTTP/1.1
Host: localhost
Connection: close

s   helloFr  )r2   r3   rP   zgot garbage: %r)r   r   r{   r   r   r(   r   )r8   r   r3   r  r   r   r   r    s    
zTestFirstEmptyYield.test_errN)r   r   r   r   rb   r  r   r   r   r   r    s   r  c               @   s    e Zd Zedd Zdd ZdS )TestEmptyYield304c             c   s   |dg  dV  dV  d S )Nz304 Not modifiedrP   r   )r   r   r   r   r   rb     s    
zTestEmptyYield304.applicationc             C   sH   |   jdd}|d t|dddd | }| |dd	|  d S )
Nr   )rw   z6GET / HTTP/1.1
Host: localhost
Connection: close

i0  rO   F)r5   r2   r3   rP   zgot garbage: %r)r   r   r{   r   r(   r   )r8   r   r  r   r   r   r  
  s
    
zTestEmptyYield304.test_errN)r   r   r   r   rb   r  r   r   r   r   r    s   r  c               @   s    e Zd ZdZdd Zdd ZdS )TestContentLength304Nc          
   C   sL   y|ddg W n. t k
r> } z|dg  |jS d }~X Y n
X t dd S )Nz304 Not modified)zContent-LengthZ100z
200 Raisedz)start_response did not fail but it should)r   r<   )r8   r   r   r   r   r   r   rb     s    
z TestContentLength304.applicationc             C   sN   |   jdd}|d d}t|dd|dd | }| |d	d
|  d S )Nr   )rw   z6GET / HTTP/1.1
Host: localhost
Connection: close

zGInvalid Content-Length for 304 response: '100' (must be absent or zero)r   ZRaisedF)r5   r4   r2   r3   rP   zgot garbage: %r)r   r   r{   r   r(   r   )r8   r   r2   r  r   r   r   r    s    
zTestContentLength304.test_err)r   r   r   r   rb   r  r   r   r   r   r    s   	r  c               @   s    e Zd ZdZdd Zdd ZdS )TestBody304Nc             C   s   |dg  dgS )Nz304 Not modifieds   bodyr   )r8   r   r   r   r   r   rb   *  s    
zTestBody304.applicationc          
   C   sf   |   jdd}|d yt| W n2 tk
rX } z| t|d W d d }~X Y n
X tdd S )Nr   )rw   z6GET / HTTP/1.1
Host: localhost
Connection: close

z"The 304 response must have no bodyzAssertionError must be raised)r   r   r{   r   r   r   rH   )r8   r   r   r   r   r   r  .  s    
"zTestBody304.test_err)r   r   r   r   rb   r  r   r   r   r   r  '  s   r  c               @   s$   e Zd ZdZdZdd Zdd ZdS )TestWrite304Nc             C   s>   |dg }d| _ y|d W n tk
r8   d| _  Y nX d S )Nz304 Not modifiedFr2   T)error_raisedr   )r8   r   r   r{   r   r   r   rb   =  s    
zTestWrite304.applicationc          	   C   s`   |   jdd}|d | t}t| W d Q R X |j}| t|d | 	| j
d d S )Nr   )rw   s6   GET / HTTP/1.1
Host: localhost
Connection: close

z"The 304 response must have no bodyzwrite() must raise)r   r   r{   assertRaisesr   r   r   r   rH   r   r  )r8   r   excr   r   r   r   r  F  s    
zTestWrite304.test_err)r   r   r   r   r  rb   r  r   r   r   r   r  9  s   	r  c               @   s   e Zd Zedd ZdS )TestEmptyWritec             C   s    |ddg}|d |d g S )Nz200 OK)zContent-Typez
text/plainrP   r   )r   r   r{   r   r   r   rb   R  s    zTestEmptyWrite.applicationN)r   r   r   r   rb   r   r   r   r   r  P  s   r  c               @   s,   e Zd ZdZdZdd Zdd Zdd ZdS )BadRequestTestsNc             C   s$   |  |d | j |ddg dgS )NrR   z200 OK)zContent-Typez
text/plains   hello)r   rX   )r8   r   r   r   r   r   rb   _  s    zBadRequestTests.applicationc             C   s6   d| _ |  jdd}|d| j   t|dd d S )Nz-100r   )rw   z7GET / HTTP/1.1
Host: localhost
Content-Length: %s

)r   i  )r5   )rX   r   r   r{   r   )r8   r   r   r   r   test_negative_content_lengthd  s    z,BadRequestTests.test_negative_content_lengthc             C   s6   d| _ |  jdd}|d| j   t|dd d S )Nr   r   )rw   z7GET / HTTP/1.1
Host: localhost
Content-Length: %s

)r   i  )r5   )rX   r   r   r{   r   )r8   r   r   r   r   test_illegal_content_lengthj  s    z+BadRequestTests.test_illegal_content_length)r   r   r   r   rX   rb   r  r  r   r   r   r   r  Z  s
   r  c               @   sp   e Zd ZdZ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S )ChunkedInputTestsrO   Nc             C   s   |d }g }|d }|dkr.| d}|g}nH|dkrPx>|D ]}|| q<W n&|dkrn| d |d ntd	|d
dg |S )Nz
wsgi.inputr   z/short-readr   z/linesz/pingr   s   pongzbad pathz200 OK)zContent-Typez
text/plain)r(   ri   RuntimeError)r8   r   r   r  r   pidr   r   r   r   rb   u  s    


zChunkedInputTests.applicationc             C   s   |d kr| j }t||dS )N)dirt)r!  chunk_encode)r8   r3   r!  r   r   r   r"    s    zChunkedInputTests.chunk_encodec          	   C   s   | j ddddddddg|d	S )
Nthisz is rN   z
linez 2
Zline3rO   )r!  )r"  )r8   r!  r   r   r   r2     s    zChunkedInputTests.bodyc             C   s   | d t|dd d S )NzGET /ping HTTP/1.1

pong)r2   )r{   r   )r8   r   r   r   r   ping  s    
zChunkedInputTests.pingc             C   sH   y|  | W n4 tk
rB   tr$ |  jdd}|  | Y nX d S )Nr   )rw   )r&  r   r   r   r   )r8   r   r   r   r   ping_if_possible  s    z"ChunkedInputTests.ping_if_possiblec             C   sX   |   }d| }|  }|jdd}|| t|dd | | |  |  d S )NsN   POST /short-read HTTP/1.1
transfer-encoding: Chunked
Content-Length:1000

r   )rw   z
this is ch)r2   )r2   r   r   r{   r   r'  r   )r8   r2   reqr   r   r   r   r   #test_short_read_with_content_length  s    

z5ChunkedInputTests.test_short_read_with_content_lengthc             C   sD   |   }d| }|  jdd}|| t|dd | | d S )NsK   POST /short-read HTTP/1.1
transfer-encoding: Chunked
Content-Length:0

r   )rw   z
this is ch)r2   )r2   r   r   r{   r   r'  )r8   r2   r(  r   r   r   r   (test_short_read_with_zero_content_length  s    
z:ChunkedInputTests.test_short_read_with_zero_content_lengthc             C   sD   |   }d| }|  jdd}|| t|dd | | d S )Ns9   POST /short-read HTTP/1.1
transfer-encoding: Chunked

r   )rw   z
this is ch)r2   )r2   r   r   r{   r   r'  )r8   r2   r(  r   r   r   r   test_short_read  s    
z!ChunkedInputTests.test_short_readc          
   C   s   | j dd}d| }|  jdd}|| yt|dd W nB tk
r } z$t|drntsnt	d	 d S  W d d }~X Y nX | 
| d S )
Nz; here is dirt bla)r!  s3   POST /ping HTTP/1.1
transfer-encoding: Chunked

r   )rw   r%  )r2   zUnexpected code: 400ZChunkedNotImplementedWarning)r2   r   r   r{   r   r   rH   
startswithr   r   r'  )r8   r2   r(  r   r   r   r   r   	test_dirt  s    
zChunkedInputTests.test_dirtc             C   sP   |   }dt| }|d}||7 }|  jdd}|| t|dd d S )NzHPOST /lines HTTP/1.1
Content-Length: %s
transfer-encoding: Chunked

zlatin-1r   )rw   zthis is chunked
line 2
line3)r2   )r2   r   rI   r   r   r{   r   )r8   r2   r(  r   r   r   r   test_chunked_readline  s    

z'ChunkedInputTests.test_chunked_readlinec             C   s   |    d}d| }|  }|jddd}|| |  |  ~~t j  t	d t
jrdd l}|  t	d t j  |  t	d | td d S )	Ns   4
this9   POST /short-read HTTP/1.1
transfer-encoding: Chunked

r   wb)rw   ry   g{Gz?r   z1unexpected end of file while parsing chunked data)r   r   r   r{   r   rs   Zget_hubZloopZ
update_nowZsleeprf   r	   gccollectr   IOError)r8   r2   r(  r   r   r0  r   r   r   test_close_before_finished  s(    



z,ChunkedInputTests.test_close_before_finished)N)N)r   r   r   r!  r   rb   r"  r2   r&  r'  r)  r*  r+  r-  r.  r3  r   r   r   r   r  q  s   

	

r  c               @   s    e Zd ZdZdd Zdd ZdS )Expect100ContinueTestsNc             C   sl   t |d }|dkr(|dddg dgS |d d}||d |d 7 }|d	d
tt|fdg |gS )NrR   i   z417 Expectation Failed)zContent-Length7)zContent-Typez
text/plains   failurez
wsgi.inputr   z200 OKzContent-Length)r'   r(   rH   r   )r8   r   r   rX   textr   r   r   rb     s    z"Expect100ContinueTests.applicationc          
   C   s   |   jdd}|d yt|ddd W nB tk
rn } z$t|dr\ts\td d S  W d d }~X Y nX |d	 t|d
d t|dd d S )Nr   )rw   zOPUT / HTTP/1.1
Host: localhost
Content-length: 1025
Expect: 100-continue

i  Zfailure)r5   r2   zUnexpected code: 400Z 100ContinueNotImplementedWarningzSPUT / HTTP/1.1
Host: localhost
Content-length: 7
Expect: 100-continue

testingrM   )r5   testing)r2   )	r   r   r{   r   r   rH   r,  server_implements_100continuer   )r8   r   r   r   r   r   test_continue  s    

z$Expect100ContinueTests.test_continue)r   r   r   r   rb   r9  r   r   r   r   r4  
  s   r4  c               @   s    e Zd ZdZdd Zdd ZdS )MultipleCookieHeadersTestNc             C   s.   |  |d d |  |d d |dg  g S )NZHTTP_COOKIEzname1="value1"; name2="value2"ZHTTP_COOKIE2znameA="valueA"; nameB="valueB"z200 OK)r   )r8   r   r   r   r   r   rb   0  s    
z%MultipleCookieHeadersTest.applicationc             C   s.   |   jdd}|ddd t| d S )Nr   )rw   z~GET / HTTP/1.1
Host: localhost
Cookie: name1="value1"
Cookie2: nameA="valueA"
Cookie2: nameB="valueB"
Cookie: name2="value2"

r$  z
)r   r   r{   r   r   )r8   r   r   r   r   r   6  s    zMultipleCookieHeadersTest.test)r   r   r   r   rb   r   r   r   r   r   r:  ,  s   r:  c               @   s4   e Zd ZdZdZdd Zdd Zdd Zdd	 ZdS )
TestLeakInputNc             C   s   t |  d | _d | _d S )N)rZ   rr   _leak_wsgi_input_leak_environ)r8   r   r   r   rr   F  s    
zTestLeakInput.tearDownc             C   sR   |d }|d | _ || _|dkr.td|d< d}|ddtt|fd	g |gS )
Nr   z
wsgi.inputz/leak-framer   _leaks   foobarz200 OKzContent-Length)zContent-Typez
text/plain)r<  r=  r   	_getframerH   r   )r8   r   r   r  r6  r   r   r   rb   K  s    
zTestLeakInput.applicationc             C   s8   |   jdd}|d | }| |d| d S )Nr   )rw   s%   GET / HTTP/1.0
Connection: close

s   HTTP/1.1 200 OK)r   r   r{   r(   r   r,  )r8   r   r   r   r   r   !test_connection_close_leak_simpleV  s    
z/TestLeakInput.test_connection_close_leak_simplec             C   sD   |   jdd}|d | }| |d| | jd d S )Nr   )rw   s/   GET /leak-frame HTTP/1.0
Connection: close

s   HTTP/1.1 200 OKr>  )r   r   r{   r(   r   r,  r=  r|   )r8   r   r   r   r   r    test_connection_close_leak_frame\  s
    
z.TestLeakInput.test_connection_close_leak_frame)	r   r   r   r<  r=  rr   rb   r@  rA  r   r   r   r   r;  A  s   r;  c               @   sT   e Zd ZdZd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S )TestHTTPResponseSplittingNz200 OKr   c             C   s$   t |  d | _tj| _tj| _d S )N)rZ   rg   	start_excrB  r   r    )r8   r   r   r   rg   l  s    
zTestHTTPResponseSplitting.setUpc             C   s   t |  d | _d S )N)rZ   rr   rC  )r8   r   r   r   rr   r  s    
z"TestHTTPResponseSplitting.tearDownc          
   C   sF   y|| j | j W n( tk
r: } z
|| _W d d }~X Y nX d | _dS )Nr   )r   r    r7   rC  )r8   r   r   er   r   r   rb   v  s    z%TestHTTPResponseSplitting.applicationc             C   s@   |   }|d |  | | jt | | jjd | d S )Nz#GET / HTTP/1.0
Host: localhost

r   )r   r{   r(   r   rC  
ValueErrorr   r<   )r8   messager   r   r   r   _assert_failure  s
    
z)TestHTTPResponseSplitting._assert_failurec             C   s   d| _ | d d S )Nz0200 OK
Connection: close
Content-Length: 0

z$carriage return or newline in status)r   rG  )r8   r   r   r   test_newline_in_status  s    z0TestHTTPResponseSplitting.test_newline_in_statusc             C   s   dg| _ | d d S )N)ZTestzHi
Connection: closez*carriage return or newline in header value)r    rG  )r8   r   r   r   test_newline_in_header_value  s    z6TestHTTPResponseSplitting.test_newline_in_header_valuec             C   s   dg| _ | d d S )N)zTest
ZHiz)carriage return or newline in header name)r    rG  )r8   r   r   r   test_newline_in_header_name  s    z5TestHTTPResponseSplitting.test_newline_in_header_name)r   r   r   r   r   r    rC  rg   rr   rb   rG  rH  rI  rJ  r   r   r   r   rB  c  s   	rB  c               @   s    e Zd ZdZdd Zdd ZdS )TestInvalidEnvironNc             C   sN   x>|  D ]2\}}|dks$|dr
|dkr
td||f q
W |dg  g S )N)rR   r   ZHTTP_Z	HTTP_HOSTz&Unexpected environment variable: %s=%rz200 OK)itemsr,  r   )r8   r   r   r"   r#   r   r   r   rb     s    
zTestInvalidEnviron.applicationc             C   s8   |   }|d t| |   }|d t| d S )Nz#GET / HTTP/1.0
Host: localhost

z#GET / HTTP/1.1
Host: localhost

)r   r{   r   )r8   r   r   r   r   r     s    

zTestInvalidEnviron.test)r   r   r   r   rb   r   r   r   r   r   rK    s   rK  c               @   s    e Zd ZdZdd Zdd ZdS )TestInvalidHeadersDroppedNc             C   s   |  d| |dg  g S )NZHTTP_X_AUTH_USERz200 OK)assertNotIn)r8   r   r   r   r   r   rb     s    
z%TestInvalidHeadersDropped.applicationc             C   s   |   }|d t| d S )Nz$GET / HTTP/1.0
x-auth_user: bob

)r   r{   r   )r8   r   r   r   r   r     s    
zTestInvalidHeadersDropped.test)r   r   r   r   rb   r   r   r   r   r   rM    s   rM  c               @   s   e Zd Zdd ZdS )Handlerc             C   sd   | j d}|d dkrR|| j d7 }| dkrB| jd n| d| d S || j   S d S )N   r   <      s   <policy-file-request/>s   HELLOzInvalid request: %r)Zrfiler(   r   r
   r   Z	log_errorr   )r8   r*   r   r   r   read_requestline  s    zHandler.read_requestlineN)r   r   r   rS  r   r   r   r   rO    s   rO  c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )TestHandlerSubclassNc             C   s   |dg  g S )Nz200 OKr   )r8   r   r   r   r   r   rb     s    
zTestHandlerSubclass.applicationc             C   s   t j| jdf|td| _d S )Nr   )Zhandler_class)r   r_   r`   rO  ra   )r8   rb   r   r   r   rc     s    zTestHandlerSubclass.init_serverc             C   sz   |   }|d |  | | d |   }|d |  t| |   }|d |  | | d d S )Ns   <policy-file-request/> s   HELLOz6GET / HTTP/1.1
Host: localhost
Connection: close

z<policy-file-XXXuest/> rP   )r   r{   r   r   r(   r   )r8   r   r   r   r   r     s    


zTestHandlerSubclass.test)r   r   r   r   rb   rc   r   r   r   r   r   rT    s   rT  c               @   s$   e Zd ZdZedd Zdd ZdS )TestErrorAfterChunkNc             c   s    |ddg dV  t dd S )Nz200 OK)zContent-Typez
text/plains   hellorU  )rf   r  )r   r   r   r   r   rb     s    zTestErrorAfterChunk.applicationc             C   s@   |   jdd}|   |d | tt| | tj	 d S )Nr   )rw   z;GET / HTTP/1.1
Host: localhost
Connection: keep-alive

)
r   r   r   r{   r  rE  r   r   rf   r  )r8   r   r   r   r   r     s
    
zTestErrorAfterChunk.test)r   r   r   r   r   rb   r   r   r   r   r   rU    s   rU  c             C   sB   |d krd}d}x,| D ]$}dt |||f }||d7 }qW |S )NrO   rP   z
%x%s
%s
rF   )r   rI   )r3   r!  bcr   r   r   r   r"    s    
r"  c                   s   e Zd Zd#ddZer" f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 )$TestInputRawNFc             C   sB   t |trt|}d}nt |tr0tr0|d}tt|||dS )NTrF   )rX   chunked_input)rG   rS   r"  rH   r   rI   r   r   )r8   r*   rX   rY  r   r   r   
make_input  s    

zTestInputRaw.make_inputc                s0   t |tr|d}tt| j||f|  d S )NrF   )rG   rH   rI   rp   rX  r   )r8   r*   Zexpectedr<   )r;   r   r   r     s    

zTestInputRaw.assertEqualc             C   s    | j ddd}| t|j d S )N1r&   )rX   )rZ  r  r2  r(   )r8   ir   r   r   test_short_post  s    zTestInputRaw.test_short_postc             C   s"   | j ddd}| t|jd d S )Nr[  r&   )rX   )rZ  r  r2  r(   )r8   r\  r   r   r    test_short_post_read_with_length  s    z-TestInputRaw.test_short_post_read_with_lengthc             C   s    | j ddd}| t|j d S )Nr[  r&   )rX   )rZ  r  r2  r   )r8   r\  r   r   r   test_short_post_readline  s    z%TestInputRaw.test_short_post_readlinec             C   s&   | j ddd}| }| |d d S )N12r&   )rX   )rZ  r(   r   )r8   r\  r*   r   r   r   	test_post   s    zTestInputRaw.test_postc             C   s(   | j ddd}|d}| |d d S )Nr`  r&   )rX   r   )rZ  r(   r   )r8   r\  r*   r   r   r   test_post_read_with_length%  s    
z'TestInputRaw.test_post_read_with_lengthc             C   s(   |  dddg}| }| |d d S )Nr[  2rO   r`  )rZ  r(   r   )r8   r\  r*   r   r   r   test_chunked*  s    zTestInputRaw.test_chunkedc             C   s*   |  dddg}|d}| |d d S )Nr[  rc  rO   r   r`  )rZ  r(   r   )r8   r\  r*   r   r   r   test_chunked_read_with_length/  s    
z*TestInputRaw.test_chunked_read_with_lengthc             C   s    |  ddg}| t|j d S )Nr[  rc  )rZ  r  r2  r(   )r8   r\  r   r   r   test_chunked_missing_chunk4  s    z'TestInputRaw.test_chunked_missing_chunkc             C   s"   |  ddg}| t|jd d S )Nr[  rc  r   )rZ  r  r2  r(   )r8   r\  r   r   r   +test_chunked_missing_chunk_read_with_length8  s    z8TestInputRaw.test_chunked_missing_chunk_read_with_lengthc             C   s    |  ddg}| t|j d S )Nr[  rc  )rZ  r  r2  r   )r8   r\  r   r   r   #test_chunked_missing_chunk_readline<  s    z0TestInputRaw.test_chunked_missing_chunk_readlinec             C   s    | j ddd}| t|j d S )Nz2
1T)rY  )rZ  r  r2  r(   )r8   r\  r   r   r   test_chunked_short_chunk@  s    z%TestInputRaw.test_chunked_short_chunkc             C   s"   | j ddd}| t|jd d S )Nz2
1T)rY  r&   )rZ  r  r2  r(   )r8   r\  r   r   r   )test_chunked_short_chunk_read_with_lengthD  s    z6TestInputRaw.test_chunked_short_chunk_read_with_lengthc             C   s    | j ddd}| t|j d S )Nz2
1T)rY  )rZ  r  r2  r   )r8   r\  r   r   r   !test_chunked_short_chunk_readlineH  s    z.TestInputRaw.test_chunked_short_chunk_readlinec             C   s   t d d}dtjd  }|d7 }|| }d}d}t d|d	t| t|d
r^| | d tsztsz| 	t
t|j| | j||d}| | d | ||d | ||| | j|| t|d d}| | d | ||d | ||| | ||d d S )NzBEGIN 32bits
   asdf
ghij
r   r   r   s   qjk
l    :;$ NzData len
bit_length#   )rX   s   asdf
s   ghij
r      q)r   r   ZMAX_REQUEST_LINEr   r?   r   rm  r   r	   r  OverflowErrorr   r   rZ  )r8   r*   Z	long_dataZpartial_datanr\  r   r   r   test_32bit_overflowL  s*    
z TestInputRaw.test_32bit_overflow)NF)r   r   r   rZ  r   r   r]  r^  r_  ra  rb  rd  re  rf  rg  rh  ri  rj  rk  rr  r   r   r   )r;   r   rX    s"   
rX  c               @   s    e Zd Zedd Zdd ZdS )Test414c             C   s   t dd S )Nzshould not get there)r   )r   r   r   r   r   rb   p  s    zTest414.applicationc             C   s4   |   }dd }|d| d t|dd d S )Nr   i N  z"GET /%s HTTP/1.0
Hello: world

zlatin-1i  )r5   )r   r{   rI   r   )r8   r   Zlongliner   r   r   r   t  s    zTest414.testN)r   r   r   r   rb   r   r   r   r   r   rs  n  s   rs  c               @   sH   e Zd ZG dd deZdd Zedd Zdd Zd	d
 Z	dd Z
dS )TestLoggingc               @   s0   e Zd ZdZdZdZdd Zdd Zdd ZdS )zTestLogging.LoggerNc             C   s   ||f| _ d S )N)logged)r8   levelmsgr   r   r   r^     s    zTestLogging.Logger.logc             C   s
   || _ d S )N)accessed)r8   rw  r   r   r   access  s    zTestLogging.Logger.accessc             C   s   | j S )N)thing)r8   r   r   r   	get_thing  s    zTestLogging.Logger.get_thing)	r   r   r   rx  ru  rz  r^   ry  r{  r   r   r   r   Logger~  s   r|  c             C   s   |   S )N)r|  )r8   r   r   r   r]     s    zTestLogging.init_loggerc             C   s   |ddg dgS )Nz200 OK)zContent-Typez
text/plains   hellor   )r   r   r   r   r   rb     s    zTestLogging.applicationc             C   sZ   |  t| jjtj | jjd | jjd | | jjj	d | | jjj
d d S )Nry  r{   )   r{   )r   rG   ra   r^   r   ZLoggingLogAdapterry  r{   r   rx  ru  )r8   r   r   r   test_proxy_methods_on_log  s
    z%TestLogging.test_proxy_methods_on_logc             C   s>   d| j j_| | j j d | j j`| | j j d  d S )N*   )ra   r^   rz  r   r{  )r8   r   r   r   test_set_attributes  s    
zTestLogging.test_set_attributesc             C   s:   |    | jjjd }| d|k| | d|k| d S )Nr   z"GET / HTTP/1.1" 200 r$  )r   ra   r^   ru  r   )r8   rw  r   r   r   test_status_log  s    zTestLogging.test_status_logN)r   r   r   r   r|  r]   r   rb   r~  r  r  r   r   r   r   rt  {  s   	rt  c                   sP   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
  ZS )TestEnvironNc                s   t t| | tj| j_d S )N)rp   r  rc   r   r   ra   Zenviron_class)r8   rb   )r;   r   r   rc     s    zTestEnviron.init_serverc             C   s   |  |tj |ddg g S )Nz200 OK)zContent-Typez
text/plain)r   r   r   )r8   r   r   r   r   r   rb     s    zTestEnviron.applicationc             C   s   |    d S )N)r   )r8   r   r   r   !test_environ_is_secure_by_default  s    z-TestEnviron.test_environ_is_secure_by_defaultc             C   s   t  }| dt| | dt| d|d< | dt| | dt| d|_| tddit| | tddit| |`d|_| tddit| | tddit| d|_| tddit| | tddit| |`d S )	Nz'<pywsgi.SecureEnviron dict (keys: 0) atr#   r"   z'<pywsgi.SecureEnviron dict (keys: 1) atF)zmissing valuez<MASKED>)r"   )r   r   ZassertInr)   rH   secure_reprr   Zwhitelist_keys)r8   r   r   r   r   test_default_secure_repr  s"    z$TestEnviron.test_default_secure_reprc             C   s   G dd dt j}| }| |j d|_| |j | ti t| | ti t| d|_d|_	d|d< | tddit| | tddit| ~~dd l
}|  d S )	Nc               @   s   e Zd ZdZdS )z>TestEnviron.test_override_class_defaults.<locals>.EnvironClassr   N)r   r   r   	__slots__r   r   r   r   EnvironClass  s   r  FT)r"   r   r"   r   )r   r   r   r  Zdefault_secure_reprr   r   rH   r)   Zdefault_whitelist_keysr0  r1  )r8   r  r   r0  r   r   r   test_override_class_defaults  s      z(TestEnviron.test_override_class_defaultsc             C   s,   x&t jt jfD ]}| |  | qW d S )N)r   Environr   r   copy)r8   rW   r   r   r   test_copy_still_secure  s    z"TestEnviron.test_copy_still_securec       	      C   s   dd l }dd l}xtjtjfD ]}ddi}||}| || | || | || xJtd|jd D ]6}|	||}| 
d| ||}| t|t qhW | |	||	| qW d S )Nr   r"   r#   r   s   Environ)picklejsonr   r  r   r   r   r   ZHIGHEST_PROTOCOLdumpsrN  loadstypedict)	r8   r  r  rW   Zbltinr   ZprotocolZenv_dumpZloadedr   r   r   test_pickle_copy_returns_dict  s    
z)TestEnviron.test_pickle_copy_returns_dict)r   r   r   r   rc   rb   r  r  r  r  r  r   r   r   )r;   r   r    s   r  __main__)N)fZ
__future__r   rs   r   Z	patch_allZurllib.parser   ImportErrorZurlparser   r   Z	cStringIOr   ior   rj   Zwsgiref.validater   Zgevent.testingr7  rf   r   r	   r
   r   Zgevent.pywsgir   rR   r   r   r   r8  argvDEBUGrQ   r7   r   r$   r+   r   r,   r(   r   rZ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ZHAVE_SSLCONTEXTr   r   r   r   r   r  r  r  r  r	  r  r  r  r  r  r  r  r  r  r  r  r4  r:  r;  rB  rK  rM  ZWSGIHandlerrO  rT  rU  r"  ZBaseTestCaserX  rs  rt  r  r   mainr   r   r   r   <module>   s   
YeC$U3$)

 ""0
i5`
