U
    ÌZj�6  ã                   @   s  d Z ddl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 ejr~dd
lmZ ddlmZ ddlmZ G dd„ deƒZG dd„ deƒZefeeejddœdd„ZG dd„ dƒZG dd„ dƒZG dd„ dƒZG dd„ dƒZG dd„ dƒ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
é    N)ÚTracebackType)Úurlparse)Úwarné   )ÚHeaders)Úis_entity_header)ÚFileWrapper)ÚStartResponse)ÚWSGIApplication)ÚWSGIEnvironmentc                   @   s   e Zd ZdZdS )ÚWSGIWarningz Warning class for WSGI warnings.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   ú[/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/werkzeug/middleware/lint.pyr      s   r   c                   @   s   e Zd ZdZdS )ÚHTTPWarningz Warning class for HTTP warnings.Nr   r   r   r   r   r   "   s   r   )ÚcontextÚobjÚneedÚreturnc                 C   s8   t |ƒ|k	r4t| ›d|j›dt |ƒj›d�tdd� d S )Nz
 requires z, got Ú.é   ©Ú
stacklevel)Útyper   r   r   )r   r   r   r   r   r   Ú
check_type&   s    ýr   c                   @   sh   e Zd Zeje ddœdd„Zejedœdd„Zejedœdd	„Z	ej
e d
œdd„Zdd
œdd„ZdS )ÚInputStreamN©Ústreamr   c                 C   s
   || _ d S ©N©Ú_stream©Úselfr!   r   r   r   Ú__init__0   s    zInputStream.__init__)Úargsr   c                 G   sB   t |ƒdkrtdtdd� nt |ƒdkr6tdtdd� | jj|Ž S )Nr   zŸWSGI 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&   r(   r   r   r   r+   3   s    ûýzInputStream.readc                 G   sL   t |ƒdkrtdtdd� n$t |ƒdkr8tdtd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()'.)r*   r   r   Ú	TypeErrorr$   Úreadliner,   r   r   r   r.   D   s    üüzInputStream.readline©r   c                 C   s<   zt | jƒW S  tk
r6   tdtdd� t dƒ Y S X d S )Nz'wsgi.input' is not iterable.r   r   r   )Úiterr$   r-   r   r   ©r&   r   r   r   Ú__iter__W   s
    zInputStream.__iter__c                 C   s   t dtdd� | j ¡  d S )Nz(The application closed the input stream!r   r   ©r   r   r$   Úcloser1   r   r   r   r4   ^   s    zInputStream.close)r   r   r   ÚtÚIOÚbytesr'   ÚAnyr+   r.   ÚIteratorr2   r4   r   r   r   r   r   /   s
   r   c                   @   sd   e Zd Zeje ddœdd„Zeddœdd„Zddœd	d
„Zej	e ddœdd„Z
ddœdd„ZdS )ÚErrorStreamNr    c                 C   s
   || _ d S r"   r#   r%   r   r   r   r'   d   s    zErrorStream.__init__©Úsr   c                 C   s   t d|tƒ | j |¡ d S )Nzwsgi.error.write())r   Ústrr$   Úwrite©r&   r<   r   r   r   r>   g   s    zErrorStream.writer/   c                 C   s   | j  ¡  d S r"   )r$   Úflushr1   r   r   r   r@   k   s    zErrorStream.flush)Úseqr   c                 C   s   |D ]}|   |¡ qd S r"   )r>   )r&   rA   Úliner   r   r   Ú
writelinesn   s    zErrorStream.writelinesc                 C   s   t dtdd� | j ¡  d S )Nz(The application closed the error stream!r   r   r3   r1   r   r   r   r4   r   s    zErrorStream.close)r   r   r   r5   r6   r=   r'   r>   r@   ÚIterablerC   r4   r   r   r   r   r:   c   s
   r:   c                   @   s@   e Zd Zejegef eje ddœdd„Z	eddœdd„Z
dS )ÚGuardedWriteN)r>   Úchunksr   c                 C   s   || _ || _d S r"   )Ú_writeÚ_chunks)r&   r>   rF   r   r   r   r'   x   s    zGuardedWrite.__init__r;   c                 C   s*   t d|tƒ |  |¡ | j t|ƒ¡ d S )Nzwrite())r   r7   rG   rH   Úappendr*   r?   r   r   r   Ú__call__|   s    
zGuardedWrite.__call__)r   r   r   r5   ÚCallabler7   ÚobjectÚListÚintr'   rJ   r   r   r   r   rE   w   s   $rE   c                   @   sn   e Zd Zeje ejeef ej	e ddœdd„Z
d dœdd„Zedœdd	„Zddœd
d„Zddœdd„ZdS )ÚGuardedIteratorN)ÚiteratorÚheaders_setrF   r   c                 C   s(   || _ t|ƒj| _d| _|| _|| _d S )NF)Ú	_iteratorr0   Ú__next__Ú_nextÚclosedrQ   rF   )r&   rP   rQ   rF   r   r   r   r'   ƒ   s
    zGuardedIterator.__init__r/   c                 C   s   | S r"   r   r1   r   r   r   r2   �   s    zGuardedIterator.__iter__c                 C   sP   | j rtdtdd� |  ¡ }| js0tdtdd� td|tƒ | j t	|ƒ¡ |S )Nz Iterated over closed 'app_iter'.r   r   z8The application returned before it started the response.zapplication iterator items)
rU   r   r   rT   rQ   r   r7   rF   rI   r*   )r&   Úrvr   r   r   rS   ’   s    ýzGuardedIterator.__next__c                 C   sþ   d| _ t| jdƒr| j ¡  | jrú| j\}}t| jƒ}|jdtd�}|dkr”|D ]2\}}| 	¡ }|dkrPt
|ƒrPtd|›d�tƒ qP|rútd	tƒ nfd
|  kr¨dk s²n |dkrà|dkrÊt|› d�tƒ |rút|› d�tƒ n|d k	rú||krútdtƒ d S )NTr4   zcontent-length)r   i0  )Úexpireszcontent-locationzEntity header z found in 304 response.z#304 responses must not have a body.éd   éÈ   éÌ   r   z- responses must have an empty content length.z  responses must not have a body.zGContent-Length and the number of bytes sent to the client do not match.)rU   ÚhasattrrR   r4   rQ   ÚsumrF   ÚgetrN   Úlowerr   r   r   r   )r&   Ústatus_codeÚheadersZ
bytes_sentÚcontent_lengthÚkeyÚ_valuer   r   r   r4   £   s@    



ÿ
 ÿþýzGuardedIterator.closec                 C   s.   | j s*ztdtƒ W n tk
r(   Y nX d S )Nz4Iterator was garbage collected before it was closed.)rU   r   r   Ú	Exceptionr1   r   r   r   Ú__del__È   s     ÿzGuardedIterator.__del__)r   r   r   r5   rD   r7   ÚTuplerN   r   rM   r'   r2   rS   r4   re   r   r   r   r   rO   ‚   s   û%rO   c                   @   s¸   e Zd ZdZdddœdd„Zdddœd	d
„Zeejej	eef  ej
ej	eje eef  ej	eef dœdd„Zeddœdd„Zeje ddœdd„Zejejeje dœd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 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)
    r
   N)Úappr   c                 C   s
   || _ d S r"   )rh   )r&   rh   r   r   r   r'   é   s    zLintMiddleware.__init__r   )Úenvironr   c                 C   sÀ   t |ƒtk	rtdtdd� dD ]"}||krtd|›d�tdd� q|d d	kr\td
tdd� | dd¡}| dd¡}|r˜|d dkr˜td|›�tdd� |r¼|d dkr¼td|›�tdd� d S )Nz/WSGI environment is not a standard Python dict.é   r   )	ÚREQUEST_METHODZSERVER_NAMEZSERVER_PORTúwsgi.versionú
wsgi.inputúwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_oncezRequired environment key z
 not foundr   rl   )r)   r   z"Environ is not a WSGI 1.0 environ.ZSCRIPT_NAMEÚ Z	PATH_INFOr   ú/z+'SCRIPT_NAME' does not start with a slash: z)'PATH_INFO' does not start with a slash: )r   Údictr   r   r]   )r&   ri   rb   Úscript_nameZ	path_infor   r   r   Úcheck_environì   s:    ý
ýýýzLintMiddleware.check_environ)Ústatusr`   Úexc_infor   c           	      C   s\  t d|tƒ | d d¡d }t|ƒdks0| ¡ s>tdtdd� t|ƒdk sV|d dkrltd	|›d
�tdd� t|ƒ}|dk rŠtdtdd� t|ƒt	k	r¤tdtdd� |D ]t}t|ƒt
k	sÄt|ƒdkrÒtdtdd� |\}}t|ƒtk	sôt|ƒtk	�rtdtdd� | ¡ dkr¨tdtdd� q¨|d k	�rBt|t
ƒ�sBtdtdd� t|ƒ}|  |¡ ||fS )Nrt   r)   r   r   z!Status code must be three digits.r   rj   ú zInvalid value for status zJ. Valid status strings are three digits, a space and a status explanation.rX   zStatus code < 100 detected.zHeader list is not a list.r   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=   Úsplitr*   Ú	isdecimalr   r   rN   r   ÚlistÚtupler^   Ú
isinstancer   Úcheck_headers)	r&   rt   r`   ru   Zstatus_code_strr_   ÚitemÚnameÚvaluer   r   r   Úcheck_start_response  sH    
ü  ÿü
z#LintMiddleware.check_start_response)r`   r   c                 C   s¢   |  d¡}|d k	rt| d¡r@| d¡r4tdtdd� |dd … }|d d… |d	d …   krdd
kstn tdtdd� |  d¡}|d k	ržt|ƒjsžtdtdd� d S )NÚetag)zW/úw/r‚   z)Weak etag indicator should be upper case.rj   r   r   r)   éÿÿÿÿú"zUnquoted etag emitted.Úlocationz+Absolute URLs required for location header.)r]   Ú
startswithr   r   r   Únetloc)r&   r`   r�   r…   r   r   r   r|   N  s(    


ý&

ýzLintMiddleware.check_headers)Úapp_iterr   c                 C   s   t |tƒrtdtdd� d S )Nz¤The application returned a bytestring. 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{   r7   r   r   )r&   rˆ   r   r   r   Úcheck_iteratori  s    
ûzLintMiddleware.check_iterator©r(   Úkwargsr   c                    sÞ   t |ƒdkrtdtdd� |r,tdtdd� |d }|d ‰ˆ |¡ t|d ƒ|d< t|d ƒ|d< t|d	< g ‰g ‰ tjtjtj	t
gd f d
œ‡ ‡‡‡fdd„}ˆ |t d|¡¡}ˆ |¡ t|t tjttf ˆ¡ˆ ƒS )Nr   zA WSGI app takes two arguments.r   z+A WSGI app does not take keyword arguments.r   r)   rm   rn   zwsgi.file_wrapperrŠ   c                     s„   t | ƒdkr&tdt | ƒ› d�tdd� |r4tdtƒ | d }| d }t | ƒd	krX| d nd }ˆ |||¡ˆd d …< tˆ|||ƒˆ ƒS )
N>   r   r   zInvalid number of arguments: z, expected 2 or 3.r   r   z1'start_response' does not take keyword arguments.r   r)   r   )r*   r   r   r€   rE   )r(   r‹   rt   r`   ru   ©rF   rQ   r&   Zstart_responser   r   Úchecking_start_responseŠ  s    ý
þz8LintMiddleware.__call__.<locals>.checking_start_responser	   )r*   r   r   rs   r   r:   r   r5   r8   rK   r7   rh   Úcastr‰   rO   rf   rN   r   )r&   r(   r‹   ri   r�   rˆ   r   rŒ   r   rJ   s  s6      ÿ
 þ
  ÿzLintMiddleware.__call__)r   r   r   r   r'   rs   r=   r5   rM   rf   ÚOptionalÚTypeÚBaseExceptionr   rN   r   r€   r|   rD   r7   r‰   r8   rJ   r   r   r   r   rg   Ò   s   .ÿù6
rg   ) r   Útypingr5   Útypesr   Úurllib.parser   Úwarningsr   Zdatastructuresr   Úhttpr   Zwsgir   ÚTYPE_CHECKINGZ_typeshed.wsgir	   r
   r   ÚWarningr   r   r=   rL   r�   r   r   r:   rE   rO   rg   r   r   r   r   Ú<module>   s&   	4P