
    wdf2                     l   d 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
 dd	lmZ 	 dd
lmZ n# e$ r	 dd
lmZ Y nw xY w G d de          Z G d de          ZddZ G d de          Z G d de          Z G d de          Ze G d de                      Z G d de          ZdS )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
    )warn   )implements_iterator)PY2)string_types)Headers)is_entity_header)FileWrapper)urlparsec                       e Zd ZdZdS )WSGIWarningz Warning class for WSGI warnings.N__name__
__module____qualname____doc__     ]/var/www/book.euthymeo.com/html/venv/lib/python3.11/site-packages/werkzeug/middleware/lint.pyr   r              ****r   r   c                       e Zd ZdZdS )HTTPWarningz Warning class for HTTP warnings.Nr   r   r   r   r   r   "   r   r   r      c                     t          |          t          ur0t          d| dt          |          j        dt                     d S d S )N'z' requires strings, got ')typestrr   r   r   )contextobj
stacklevels      r   check_stringr!   &   sW    Cyy18$s)):L:L:LM	
 	
 	
 	
 	
 r   c                   ,    e Zd Zd Zd Zd Zd Zd ZdS )InputStreamc                     || _         d S N_streamselfstreams     r   __init__zInputStream.__init__/       r   c                     t          |          dk    rt          dt          d           n*t          |          dk    rt          dt          d            | j        j        | S )Nr   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   r       z2Too many parameters passed to 'wsgi.input.read()'.)lenr   r   r'   readr)   argss     r   r1   zInputStream.read2   s    t99>>*      YY!^^D   
 !t| $''r   c                     t          |          dk    rt          dt          d           n:t          |          dk    rt          dt          d           nt          d           | j        j        | S )Nr   z_Calls to 'wsgi.input.readline()' without arguments are unsafe. Use 'wsgi.input.read()' instead.r   r.   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()'.)r0   r   r   	TypeErrorr'   readliner2   s     r   r6   zInputStream.readlineC   s    t99>>0	     YY!^^O	     STTT$t|$d++r   c                     	 t          | j                  S # t          $ r) t          dt          d           t          d          cY S w xY w)Nz'wsgi.input' is not iterable.r   r.   r   )iterr'   r5   r   r   r)   s    r   __iter__zInputStream.__iter__V   sW    	%%% 	 	 	0+!LLLL88OOO	s    0A	A	c                 f    t          dt          d           | j                                         d S )Nz(The application closed the input stream!r   r.   r   r   r'   closer9   s    r   r=   zInputStream.close]   3    7QRSSSSr   N)r   r   r   r+   r1   r6   r:   r=   r   r   r   r#   r#   .   s_          ( ( (", , ,&      r   r#   c                   ,    e Zd Zd Zd Zd Zd Zd ZdS )ErrorStreamc                     || _         d S r%   r&   r(   s     r   r+   zErrorStream.__init__c   r,   r   c                 Z    t          d|           | j                            |           d S )Nzwsgi.error.write())r!   r'   writer)   ss     r   rC   zErrorStream.writef   s/    )1---1r   c                 8    | j                                          d S r%   )r'   flushr9   s    r   rG   zErrorStream.flushj   s    r   c                 :    |D ]}|                      |           d S r%   )rC   )r)   seqlines      r   
writelineszErrorStream.writelinesm   s0     	 	DJJt	 	r   c                 f    t          dt          d           | j                                         d S )Nz(The application closed the error stream!r   r.   r<   r9   s    r   r=   zErrorStream.closeq   r>   r   N)r   r   r   r+   rC   rG   rK   r=   r   r   r   r@   r@   b   s_                    r   r@   c                       e Zd Zd Zd ZdS )GuardedWritec                 "    || _         || _        d S r%   )_write_chunks)r)   rC   chunkss      r   r+   zGuardedWrite.__init__w   s    r   c                     t          d|           | j                            |           | j                            t          |                     d S )Nzwrite())r!   rP   rC   rQ   appendr0   rD   s     r   __call__zGuardedWrite.__call__{   sJ    Y"""!CFF#####r   N)r   r   r   r+   rU   r   r   r   rN   rN   v   s2          $ $ $ $ $r   rN   c                   ,    e Zd Zd Zd Zd Zd Zd ZdS )GuardedIteratorc                     || _         t          rt          |          j        | _        nt          |          j        | _        d| _        || _        || _        d S )NF)		_iteratorr   r8   next_next__next__closedheaders_setrR   )r)   iteratorr^   rR   s       r   r+   zGuardedIterator.__init__   sM    ! 	1h,DJJh0DJ&r   c                     | S r%   r   r9   s    r   r:   zGuardedIterator.__iter__   s    r   c                    | j         rt          dt          d           |                                 }| j        st          dt          d           t          d|           | j                            t          |                     |S )Nz Iterated over closed 'app_iter'.r   r.   z8The application returned before it started the response.zapplication iterator items)	r]   r   r   r[   r^   r!   rR   rT   r0   )r)   rvs     r   r\   zGuardedIterator.__next__   s    ; 	P3[QOOOOZZ\\ 	J    	126663r77###	r   c                    d| _         t          | j        d          r| j                                         | j        r| j        \  }}t          | j                  }|                    dt                    }|dk    rb|D ]D\  }}|	                                }|dvr't          |          rt          d|z  t                     E|rt          dt                     d S d S d	|cxk    rd
k     sn |dk    r<|dk    rt          d|z  t                     |rt          d|z  t                     d S d S |||k    rt          dt                     d S d S d S d S )NTr=   zcontent-length)r   i0  )expireszcontent-locationz'Entity header %r found in 304 response.z#304 responses must not have a body.d         r   z/%r responses must have an empty content length.z"%r responses must not have a body.zGContent-Length and the number of bytes sent to the client do not match.)r]   hasattrrY   r=   r^   sumrR   getintlowerr	   r   r   r   )r)   status_codeheaders
bytes_sentcontent_lengthkey_values          r   r=   zGuardedIterator.close   s   4>7++ 	#N  """ 	#'#3 KT[))J$[[)9[DDNc!!#*  KC))++C"AAAFVG GA EK[    M>LLLLLM M))))c))))[C-?-?!Q&&IKW#    <{JK       +*0L0L    7	 	4 ,+0L0Lr   c                 f    | j         s)	 t          dt                     d S # t          $ r Y d S w xY wd S )Nz4Iterator was garbage collected before it was closed.)r]   r   r   	Exceptionr9   s    r   __del__zGuardedIterator.__del__   s`    { 	JK        	 	s     
..N)r   r   r   r+   r:   r\   r=   ru   r   r   r   rW   rW      s`              "% % %N    r   rW   c                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	LintMiddlewarea  Warns about common errors in the WSGI and HTTP behavior of the
    server and wrapped application. Some of the issues it check are:

    -   invalid status codes
    -   non-bytestrings 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                     || _         d S r%   )app)r)   ry   s     r   r+   zLintMiddleware.__init__   s    r   c                    t          |          t          urt          dt          d           dD ] }||vrt          d|z  t          d           !|d         dk    rt          d	t          d           |                    d
d          }|                    dd          }|r&|d         dk    rt          d|z  t          d           |r(|d         dk    rt          d|z  t          d           d S d S d S )Nz/WSGI environment is not a standard Python dict.   r.   )	REQUEST_METHODSERVER_NAMESERVER_PORTwsgi.version
wsgi.inputwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_oncez%Required environment key %r not foundr   r   )r/   r   z"Environ is not a WSGI 1.0 environ.SCRIPT_NAME 	PATH_INFOr   /z-'SCRIPT_NAME' does not start with a slash: %rz+'PATH_INFO' does not start with a slash: %r)r   dictr   r   rj   )r)   environrq   script_name	path_infos        r   check_environzLintMiddleware.check_environ   sW   ==$$A   


 	 	C '!!;cA    
 >"f,,5{qQQQQkk-44KKR00	 	;q>S00?+M     	1,,=	I     	 	,,r   c                    t          d|           |                    d d          d         }t          |          dk    s|                                st	          t          d          d           t          |          dk     s|d         dk    rt	          t          d	          d           t          |          }|d
k     rt	          t          d          d           t          |          t          urt	          t          d          d           |D ]}t          |          t          ust          |          dk    rt	          t          d          d           |\  }}t          |          t          ust          |          t          urt	          t          d          d           |                                dk    rt	          t          d          d           |3t          |t                    st	          t          d          d           t          |          }|                     |           ||fS )Nstatusr/   r   r   z Status code must be three digitsr.   r{    zeInvalid value for status %r.  Valid status strings are three digits, a space and a status explanationre   zstatus code < 100 detectedzheader list is not a listr   z Headers must tuple 2-item tupleszheader items must be stringszFThe status header is not supported due to conflicts with the CGI spec.zinvalid value for exc_info)r!   splitr0   isdigitr   r   rk   r   listtupler   rl   
isinstancer   check_headers)r)   r   rn   exc_inform   itemnamevalues           r   check_start_responsez#LintMiddleware.check_start_response  sJ   Xv&&&ll4++A.{q  (;(;(=(= ?@@QOOOOv;;??fQi3../ 
     +&&9::qIIII==$$899aHHHH 	 	DDzz&&#d))q..[!CDDQRSSSSKD%Dzz$$U3(>(>[!?@@QOOOOzz||x''7   !    
8U(C(C9::qIIII'""7###G##r   c                    |                     d          }||                    d          r=|                    d          rt          t          d          d           |dd          }|d d         |d	d          cxk    rd
k    s n t          t          d          d           |                     d          }|4t	          |          j        s"t          t          d          d           d S d S d S )Netag)zW/w/r   z%weak etag indicator should be upcase.r{   r.   r   r/   "zunquoted etag emitted.locationz*absolute URLs required for location header)rj   
startswithr   r   r   netloc)r)   rn   r   r   s       r   r   zLintMiddleware.check_headersH  s-   {{6""|,,  ??4(( #$KLL#$   
 ABBx!HRSS	0000S0000[!9::qIIII;;z**H%%,  LMM         r   c                 b    t          |t                    rt          dt          d           d S d S )NzThe application returned astring. The response will send one character at a time to the client, which will kill performance. Return a list or iterable instead.r   r.   )r   r   r   r   )r)   app_iters     r   check_iteratorzLintMiddleware.check_iteratora  sL    h-- 	(      	 	r   c                     t          |          dk    rt          dt          d           |rt          dt          d           |\  }                     |           t	          |d                   |d<   t          |d                   |d<   t          |d<   g g  fd}                     ||          }                     |           t          |          S )	Nr   zA WSGI app takes two arguments.r.   z+A WSGI app does not take keyword arguments.r   r   zwsgi.file_wrapperc                  f   t          |           dvr't          dt          |           z  t          d           |rt          dt                     | d d         \  }}t          |           dk    r	| d         }nd }                    |||          d d <   t	           |||                    S )N)r   r   z1Invalid number of arguments: %s, expected 2 or 3.r   r.   z1'start_response' does not take keyword arguments.r   )r0   r   r   r   rN   )	r3   kwargsr   rn   r   rR   r^   r)   start_responses	        r   checking_start_responsez8LintMiddleware.__call__.<locals>.checking_start_response  s    4yy&&G#d))S      WH+VVV"2A2hOFG4yyA~~7!66vwQQKNvw I I6RRRr   )
r0   r   r   r   r#   r@   r
   ry   r   rW   )	r)   r3   r   r   r   r   rR   r^   r   s	   `     @@@r   rU   zLintMiddleware.__call__k  s#   t99>>2KANNNN 	={WX    #'7### +GL,A B B!,W]-C!D!D (3#$	S 	S 	S 	S 	S 	S 	S 	S* 88G%<==H%%%xf===r   N)
r   r   r   r   r+   r   r   r   r   rU   r   r   r   rw   rw      sz         ,  * * *X.$ .$ .$`  2  -> -> -> -> ->r   rw   N)r   )r   warningsr   _compatr   r   r   datastructuresr   httpr	   wsgir
   urllib.parser   ImportErrorWarningr   r   r!   objectr#   r@   rN   rW   rw   r   r   r   <module>r      sA          ) ) ) ) ) )       " " " " " " $ $ $ $ $ $ # # # # # #      "%%%%%%% " " "!!!!!!!!"+ + + + +' + + ++ + + + +' + + +
 
 
 
1 1 1 1 1& 1 1 1h    &   ($ $ $ $ $6 $ $ $ M M M M Mf M M M`F> F> F> F> F>V F> F> F> F> F>s   5 AA