+
    Nj8                    P   R t ^ RIHt ^ RIt^ RIHt ^ RIHt ^ RI	H
t
 ^RIHt ^RIHt ^RIHt ]P"                  '       d   ^ R	IHt ^ R
IHt ^ RIHt  ! R R]4      t ! R R]4      t]3R R llt ! R R4      t ! R R4      t ! R R4      t ! R R4      t ! R R4      tR# )a  
WSGI Protocol Linter
====================

This module provides a middleware that performs sanity checks on the
behavior of the WSGI server and application. It checks that the
:pep:`3333` WSGI spec is properly implemented. It also warns on some
common HTTP errors such as non-empty responses for 304 status codes.

.. autoclass:: LintMiddleware

:copyright: 2007 Pallets
:license: BSD-3-Clause
)annotationsN)TracebackType)urlparse)warn)Headers)is_entity_header)FileWrapper)StartResponse)WSGIApplication)WSGIEnvironmentc                      ] tR t^!tRtRtR# )WSGIWarningz Warning class for WSGI warnings. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       Z/data/cameron/venvs/serve_omidlab/lib/python3.14/site-packages/werkzeug/middleware/lint.pyr   r   !       *r   r   c                      ] tR t^%tRtRtR# )HTTPWarningz Warning class for HTTP warnings.r   Nr   r   r   r   r   r   %   r   r   r   c               (    V ^8  d   QhRRRRRRRR/# )	   contextstrobjobjectneedtypereturnNoner   )formats   "r   __annotate__r&   )   s(     
 
 
& 
 
t 
r   c           	         \        V4      VJd>   \        V : R VP                  : R\        V4      P                  : R2\        ^R7       R# R# )z
 requires z, got .
stacklevelN)r"   r   r   r   )r   r   r!   s   &&&r   
check_typer+   )   sH    CykDMM#4F49;M;M:PPQR	
 r   c                  R    ] tR t^2tR R ltR R ltR R ltR R ltR	 R
 ltRt	R# )InputStreamc                    V ^8  d   QhRRRR/# )r   streamzt.IO[bytes]r#   r$   r   )r%   s   "r   r&   InputStream.__annotate__3   s      { t r   c                	    Wn         R # N_streamselfr/   s   &&r   __init__InputStream.__init__3       r   c                    V ^8  d   QhRRRR/# r   argst.Anyr#   bytesr   )r%   s   "r   r&   r0   6   s     ( (% (E (r   c                	    \        V4      ^ 8X  d   \        R\        ^R7       M"\        V4      ^8w  d   \        R\        ^R7       V P                  P                  ! V!  # )    zWSGI does not guarantee an EOF marker on the input stream, thus making calls to 'wsgi.input.read()' unsafe. Conforming servers may never return from this call.r)   z2Too many parameters passed to 'wsgi.input.read()'.)lenr   r   r4   readr6   r<   s   &*r   rB   InputStream.read6   sW    t9>*  Y!^D
 ||  $''r   c                    V ^8  d   QhRRRR/# r;   r   )r%   s   "r   r&   r0   G   s     , ,e , ,r   c                	    \        V4      ^ 8X  d   \        R\        ^R7       M.\        V4      ^8X  d   \        R\        ^R7       M\        R4      hV P                  P
                  ! V!  # )r@   z_Calls to 'wsgi.input.readline()' without arguments are unsafe. Use 'wsgi.input.read()' instead.r)   z~'wsgi.input.readline()' was called with a size hint. WSGI does not support this, although it's available on all major servers.z5Too many arguments passed to 'wsgi.input.readline()'.)rA   r   r   	TypeErrorr4   readlinerC   s   &*r   rH   InputStream.readlineG   sd    t9>0	 Y!^O	 STT||$$d++r   c                   V ^8  d   QhRR/# )r   r#   zt.Iterator[bytes]r   )r%   s   "r   r&   r0   Z   s      + r   c                	     \        V P                  4      #   \         d!    \        R \        ^R7       \        R4      u # i ; i)z'wsgi.input' is not iterable.r)   r   )iterr4   rG   r   r   r6   s   &r   __iter__InputStream.__iter__Z   s;    	%% 	0+!L8O	s    (AAc                   V ^8  d   QhRR/# r   r#   r$   r   )r%   s   "r   r&   r0   a         t r   c                	^    \        R \        ^R7       V P                  P                  4        R# )z(The application closed the input stream!r)   Nr   r   r4   closerM   s   &r   rU   InputStream.closea        7QRSr   r3   N)
r   r   r   r   r7   rB   rH   rN   rU   r   r   r   r   r-   r-   2   s     (",& r   r-   c                  R    ] tR t^ftR R ltR R ltR R ltR R ltR	 R
 ltRt	R# )ErrorStreamc                    V ^8  d   QhRRRR/# )r   r/   z	t.IO[str]r#   r$   r   )r%   s   "r   r&   ErrorStream.__annotate__g   s      y T r   c                	    Wn         R # r2   r3   r5   s   &&r   r7   ErrorStream.__init__g   r9   r   c                    V ^8  d   QhRRRR/# )r   sr   r#   r$   r   )r%   s   "r   r&   r[   j   s      s t r   c                	^    \        R V\        4       V P                  P                  V4       R# )zwsgi.error.write()N)r+   r   r4   writer6   r_   s   &&r   ra   ErrorStream.writej   s!    'C01r   c                   V ^8  d   QhRR/# rQ   r   )r%   s   "r   r&   r[   n   s      t r   c                	:    V P                   P                  4        R # r2   )r4   flushrM   s   &r   rf   ErrorStream.flushn   s    r   c                    V ^8  d   QhRRRR/# )r   seqzt.Iterable[str]r#   r$   r   )r%   s   "r   r&   r[   q   s      o $ r   c                	:    V F  pV P                  V4       K  	  R # r2   )ra   )r6   ri   lines   && r   
writelinesErrorStream.writelinesq   s    DJJt r   c                   V ^8  d   QhRR/# rQ   r   )r%   s   "r   r&   r[   u   rR   r   c                	^    \        R \        ^R7       V P                  P                  4        R# )z(The application closed the error stream!r)   NrT   rM   s   &r   rU   ErrorStream.closeu   rW   r   r3   N)
r   r   r   r   r7   ra   rf   rl   rU   r   r   r   r   rY   rY   f   s      r   rY   c                  .    ] tR t^ztR R ltR R ltRtR# )GuardedWritec               $    V ^8  d   QhRRRRRR/# )r   ra   zt.Callable[[bytes], object]chunks	list[int]r#   r$   r   )r%   s   "r   r&   GuardedWrite.__annotate__{   s#      9 9 QU r   c                	    Wn         W n        R # r2   )_write_chunks)r6   ra   rt   s   &&&r   r7   GuardedWrite.__init__{   s    r   c                    V ^8  d   QhRRRR/# )r   r_   r>   r#   r$   r   )r%   s   "r   r&   rv      s     $ $% $D $r   c                	    \        R V\        4       V P                  V4       V P                  P	                  \        V4      4       R# )zwrite()N)r+   r>   rx   ry   appendrA   rb   s   &&r   __call__GuardedWrite.__call__   s/    9a'ACF#r   )ry   rx   N)r   r   r   r   r7   r~   r   r   r   r   rr   rr   z   s    $ $r   rr   c                  R    ] tR t^tR R ltR R ltR R ltR R ltR	 R
 ltRt	R# )GuardedIteratorc               (    V ^8  d   QhRRRRRRRR/# )	r   iteratort.Iterable[bytes]headers_settuple[int, Headers]rt   ru   r#   r$   r   )r%   s   "r   r&   GuardedIterator.__annotate__   s2     
 
#
 )
 	

 

r   c                	l    Wn         \        V4      P                  V n        R V n        W n        W0n        R# )FN)	_iteratorrL   __next___nextclosedr   rt   )r6   r   r   rt   s   &&&&r   r7   GuardedIterator.__init__   s,     "(^,,
&r   c                   V ^8  d   QhRR/# )r   r#   r   r   )r%   s   "r   r&   r      s      / r   c                	    V # r2   r   rM   s   &r   rN   GuardedIterator.__iter__   s    r   c                   V ^8  d   QhRR/# )r   r#   r>   r   )r%   s   "r   r&   r      s      % r   c                	    V P                   '       d   \        R \        ^R7       V P                  4       pV P                  '       g   \        R\        ^R7       \        RV\        4       V P                  P                  \        V4      4       V# )z Iterated over closed 'app_iter'.r)   z8The application returned before it started the response.zapplication iterator items)
r   r   r   r   r   r+   r>   rt   r}   rA   )r6   rvs   & r   r   GuardedIterator.__next__   sj    ;;;3[QOZZ\J 	/U;3r7#	r   c                   V ^8  d   QhRR/# rQ   r   )r%   s   "r   r&   r      s     / /t /r   c                	   R V n         \        V P                  R4      '       d   V P                  P                  4        V P                  '       Ed%   V P                  w  r\        V P                  4      pVP                  R\        R7      pVR8X  dm   V FH  w  rVVP                  4       pVR9  g   K  \        V4      '       g   K1  \        RV: R2\        ^R7       KJ  	  V'       d   \        R\        ^R7       R# R# ^dTu;8:  d   ^8  g
   M V^8X  d>   V^ 8w  d   \        V R	2\        ^R7       V'       d   \        V R
2\        ^R7       R# R# Ve   WC8w  d   \        R\        ^R7       R# R# R# R# )TrU   zcontent-length)r"   i0  zEntity header z found in 304 response.r)   z#304 responses must not have a body.z- responses must have an empty content length.z  responses must not have a body.NzGContent-Length and the number of bytes sent to the client do not match.)expireszcontent-location)r   hasattrr   rU   r   sumrt   getintlowerr   r   r   r   )r6   status_codeheaders
bytes_sentcontent_lengthkey_values   &      r   rU   GuardedIterator.close   s`   4>>7++NN  "#'#3#3 KT[[)J$[[)9[DNc!#*KC))+C"AAFVG G ,SG3JK''( $+ =##$  )c)[C-?!Q&&-'TU##$
 &-'GH##$   +0L, 	 1M+G r   c                   V ^8  d   QhRR/# rQ   r   )r%   s   "r   r&   r      s     	 	 	r   c                	x    V P                   '       g    \        R \        ^R7       R# R#   \         d     R# i ; i)z4Iterator was garbage collected before it was closed.r)   N)r   r   r   	ExceptionrM   s   &r   __del__GuardedIterator.__del__   s:    {{{J    s   * 99)r   r   rt   r   r   N)
r   r   r   r   r7   rN   r   rU   r   r   r   r   r   r   r      s!    
"/b	 	r   r   c                  b    ] tR t^tRtR R ltR R ltR R ltR R	 ltR
 R lt	R R lt
RtR# )LintMiddlewarea`  Warns about common errors in the WSGI and HTTP behavior of the
server and wrapped application. Some of the issues it checks are:

-   invalid status codes
-   non-bytes sent to the WSGI server
-   strings returned from the WSGI application
-   non-empty conditional responses
-   unquoted etags
-   relative URLs in the Location header
-   unsafe calls to wsgi.input
-   unclosed iterators

Error information is emitted using the :mod:`warnings` module.

:param app: The WSGI application to wrap.

.. code-block:: python

    from werkzeug.middleware.lint import LintMiddleware
    app = LintMiddleware(app)
c                    V ^8  d   QhRRRR/# )r   appr
   r#   r$   r   )r%   s   "r   r&   LintMiddleware.__annotate__   s      O  r   c                	    Wn         R # r2   r   )r6   r   s   &&r   r7   LintMiddleware.__init__   s    r   c                    V ^8  d   QhRRRR/# )r   environr   r#   r$   r   )r%   s   "r   r&   r      s     * *_ * *r   c                	   \        V4      \        Jd   \        R \        ^R7       R F"  pW!9  g   K  \        RV: R2\        ^R7       K$  	  VR,          R8w  d   \        R\        ^R7       VP	                  RR4      pVP	                  RR4      pV'       d%   V^ ,          R	8w  d   \        R
V: 2\        ^R7       V'       d)   V^ ,          R	8w  d   \        RV: 2\        ^R7       R# R# R# )z/WSGI environment is not a standard Python dict.r)   wsgi.versionzRequired environment key z
 not foundz"Environ is not a WSGI 1.0 environ.SCRIPT_NAME 	PATH_INFO/z+'SCRIPT_NAME' does not start with a slash: z)'PATH_INFO' does not start with a slash: N)	REQUEST_METHODSERVER_NAMESERVER_PORTr   
wsgi.inputwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_once)   r@   )r"   dictr   r   r   )r6   r   r   script_name	path_infos   &&   r   check_environLintMiddleware.check_environ   s    =$A


C !/wjA 

" >"f,5{qQkk-4KKR0	;q>S0=k_M 1,;I=I -9r   c               (    V ^8  d   QhRRRRRRRR/# )	r   statusr   r   zlist[tuple[str, str]]exc_infoz?None | tuple[type[BaseException], BaseException, TracebackType]r#   r   r   )r%   s   "r   r&   r   )  s3     2( 2(2( '2( T	2(
 
2(r   c                	   \        R V\        4       VP                  R^4      ^ ,          p\        V4      ^8w  g   VP	                  4       '       g   \        R\        ^R7       \        V4      ^8  g   V^,          R8w  d   \        RV: R2\        ^R7       \        V4      pV^d8  d   \        R\        ^R7       \        V4      \        Jd   \        R\        ^R7       V F  p\        V4      \        Jg   \        V4      ^8w  d   \        R	\        ^R7       Vw  rx\        V4      \        Jg   \        V4      \        Jd   \        R
\        ^R7       VP                  4       R 8X  g   K  \        R\        ^R7       K  	  Ve)   \        V\        4      '       g   \        R\        ^R7       \        V4      p	V P                  V	4       WY3# )r   Nz!Status code must be three digits.r)    zInvalid value for status zJ. Valid status strings are three digits, a space and a status explanation.zStatus code < 100 detected.zHeader list is not a list.z#Header items must be 2-item tuples.z'Header keys and values must be strings.zFThe status header is not supported due to conflicts with the CGI spec.zInvalid value for exc_info.)r+   r   splitrA   	isdecimalr   r   r   r"   listtupler   
isinstancer   check_headers)
r6   r   r   r   status_code_strr   itemnamevalueheaders_objs
   &&&&      r   check_start_response#LintMiddleware.check_start_response)  s}    	8VS) ,,tQ/21$O,E,E,G,G4kaPv;?fQi3.+F: 6= =	 /*.J=$-{qIDDz&#d)q.:KTUVKDDz$U3(>={WX zz|x'4 	   
8U(C(C.Jg&;'''r   c                    V ^8  d   QhRRRR/# )r   r   r   r#   r$   r   )r%   s   "r   r&   r   ]  s      W  r   c                	   VP                  R 4      pVew   VP                  R4      '       d3   VP                  R4      '       d   \        R\        ^R7       VR,          pVR,          VRR u;8X  d   R8X  g   M \        R\        ^R7       VP                  R	4      pVe2   \	        V4      P
                  '       g   \        R
\        ^R7       R# R# R# )etagNw/z)Weak etag indicator should be upper case.r)   :r   NN:Nr   N"zUnquoted etag emitted.locationz+Absolute URLs required for location header.)zW/r   )r   
startswithr   r   r   netloc)r6   r   r   r   s   &&  r   r   LintMiddleware.check_headers]  s    {{6"|,,??4((C##$ BxHRS	0S0-{qI;;z*H%,,,A  -  r   c                    V ^8  d   QhRRRR/# )r   app_iterr   r#   r$   r   )r%   s   "r   r&   r   x  s      '8 T r   c                	Z    \        V\        4      '       d   \        R \        ^R7       R# R# )zThe application returned a string. The response will send one character at a time to the client, which will kill performance. Return a list or iterable instead.r)   N)r   r   r   r   )r6   r   s   &&r   check_iteratorLintMiddleware.check_iteratorx  s)    h$$6  %r   c               $    V ^8  d   QhRRRRRR/# )r   r<   r=   kwargsr#   r   r   )r%   s   "r   r&   r     s"     5
 5
e 5
u 5
9J 5
r   c                	,  a aaa \        V4      ^8w  d   \        R\        ^R7       V'       d   \        R\        ^R7       V^ ,          pV^,          oS P                  V4       \	        VR,          4      VR&   \        VR,          4      VR&   \        VR&   . o. oR VVV V3R llpS P                  V\        P                  ! R	V4      4      pS P                  V4       \        V\        P                  ! \        \        \        3,          S4      S4      # )
r   zA WSGI app takes two arguments.r)   z+A WSGI app does not take keyword arguments.r   r   zwsgi.file_wrapperc               $    V ^8  d   QhRRRRRR/# )r   r<   r=   r   r#   zt.Callable[[bytes], None]r   )r%   s   "r   r&   -LintMiddleware.__call__.<locals>.__annotate__  s)     	S 	S	S$)	S&	Sr   c                 @  < \        V 4      R9  d    \        R\        V 4       R2\        ^R7       V'       d   \        R\        ^R7       V ^ ,          pV ^,          p\        V 4      ^8X  d
   V ^,          MRpSP                  W#V4      SR&   \	        S! W#V4      S4      # )r   zInvalid number of arguments: z, expected 2 or 3.r)   z1'start_response' does not take keyword arguments.N:NNN>   r      )rA   r   r   r   rr   )	r<   r   r   r   r   rt   r   r6   start_responses	   *,   r   checking_start_response8LintMiddleware.__call__.<locals>.checking_start_response  s     4y&3CI;>PQ  G  q'F-1!WG t9>Qt  "66vQKNv I6RRr   r	   )rA   r   r   r   r-   rY   r   r   tcastr   r   r   r   r   )	r6   r<   r   r   r   r   rt   r   r   s	   f*,   @@@r   r~   LintMiddleware.__call__  s    t9>2KAN={WX $(7(,Q7# +GL,A B!,W]-C!D (3#$#%	S 	S4 88GQVVO=T%UVH%affU3<0+>
 	
r   r   N)r   r   r   r   r   r7   r   r   r   r   r~   r   r   r   r   r   r      s,    ,*X2(h65
 5
r   r   ) r   
__future__r   typingr   typesr   urllib.parser   warningsr   datastructuresr   httpr   wsgir   TYPE_CHECKING_typeshed.wsgir	   r
   r   Warningr   r   r   r+   r-   rY   rr   r   r   r   r   r   <module>r      s    #   !  $ # ???,..+' ++' + 8; 
1 1h ($ $[ [|T
 T
r   