o
    0׾g                    @   sz  d Z ddlmZ ddlZddlmZ ddlZddlZddlZddl	Z	ddl
m
Z
 ddlmZ ddlm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 eeddZdZg dZdZdZdZejdZe dd dD dd ej!D B Z"de"v sJ i Z#dZ$dZ%ddde&e'e%ffZ(e$e(e%fe#d< d Z)d!Z*ddde&e'e*ffZ+e)e+e*fe#d"< d#Z,d$Z-d%Z.d&d' Z/G d(d) d)e0Z1G d*d+ d+e2Z3G d,d- d-e4Z5z	ddl6Z6e6j7Z8W n e9y   dd.l:m;Z; G d/d0 d0e;j<Z=d1d2 Z8Y nw G d3d4 d4e4Z>G d5d6 d6e4Z?G d7d8 d8e4Z@G d9d: d:eAZBG d;d< d<eBZCG d=d> d>eCZDG d?d@ d@eZEdAdB ZFeGdCkr;eF  dS dS )Da  
A pure-Python, gevent-friendly WSGI server implementing HTTP/1.1.

The server is provided in :class:`WSGIServer`, but most of the actual
WSGI work is handled by :class:`WSGIHandler` --- a new instance is
created for each request. The server can be customized to use
different subclasses of :class:`WSGIHandler`.

.. important::

   This server is intended primarily for development and testing, and
   secondarily for other "safe" scenarios where it will not be exposed to
   potentially malicious input. The code has not been security audited,
   and is not intended for direct exposure to the public Internet. For production
   usage on the Internet, either choose a production-strength server such as
   gunicorn, or put a reverse proxy between gevent and the Internet.

.. versionchanged:: 23.9.0

   Complies more closely with the HTTP specification for chunked transfer encoding.
   In particular, we are much stricter about trailers, and trailers that
   are invalid (too long or featuring disallowed characters) forcibly close
   the connection to the client *after* the results have been sent.

   Trailers otherwise continue to be ignored and are not available to the
   WSGI application.

    )absolute_importN)BytesIO)datetime)unquote)socket)StreamServer)GreenletExit)reraise)partiallatin-1)encodingT)
WSGIServerWSGIHandlerLoggingLogAdapterEnvironSecureEnvironWSGISecureEnvironi    )MonTueWedThuFriSatSun)NJanFebMarAprMayJunJulAugSepOctNovDecasciic                 c   s    | ]}| d V  qdS )r&   Nencode.0c r,   W/var/www/html/backend_erp/backend_erp_env/lib/python3.10/site-packages/gevent/pywsgi.py	<genexpr>[   s    r.   z!#$%&'*+-.^_`|~0123456789c                 C   s   h | ]}| d qS )r&   r'   r)   r,   r,   r-   	<setcomp>]   s    r/      Az500 Internal Server Errors   Internal Server Error)zContent-Typez
text/plain)
ConnectionclosezContent-Length  z400 Bad Request   sK   HTTP/1.1 414 Request URI Too Long
Connection: close
Content-length: 0

sB   HTTP/1.1 400 Bad Request
Connection: close
Content-length: 0

s   HTTP/1.1 100 Continue

c              	   C   sH   t | \	}}}}}}}}}	dt| |t| ||||f }
|
d}
|
S )Nz#%s, %02d %3s %4d %02d:%02d:%02d GMTr   )timegmtime_WEEKDAYNAME
_MONTHNAMEr(   )	timestampyearmonthdayhhmmsswd_y_zvaluer,   r,   r-   format_date_timez   s   
rE   c                   @   s   e Zd ZdS )_InvalidClientInputN)__name__
__module____qualname__r,   r,   r,   r-   rF      s    rF   c                   @   s   e Zd Zdd ZdS )_InvalidClientRequestc                 C   s   t | | || _d S N)
ValueError__init__formatted_message)selfmessager,   r,   r-   rM      s   
z_InvalidClientRequest.__init__N)rG   rH   rI   rM   r,   r,   r,   r-   rJ      s    rJ   c                   @   s   e Zd ZdZdddZdd Zdd	 Zdd
dZdd Zdd Z	dddZ
dddZd ddZd ddZd ddZdd Zdd ZeZdS )!Inputrfilecontent_lengthr   positionchunked_inputchunk_length_chunked_input_errorNFc                 C   s.   || _ || _|| _d| _|| _d| _d| _d S )Nr   FrR   )rO   rS   rT   r   rV   r,   r,   r-   rM      s   
zInput.__init__c                 C   sH   | j rd S | jd u r | j| jpdk s| jr"	 | d}|sd S qd S d S )Nr       @  )rX   r   rU   rT   rV   read)rO   dr,   r,   r-   _discard   s    
zInput._discardc                 C   s$   | j d ur| j t d | _ d S d S rK   )r   sendall_CONTINUE_RESPONSErO   r,   r,   r-   _send_100_continue   s   

zInput._send_100_continuec                 C   s  |r| j j}n| j j}| j}|d u rdS |   || j }|d u r$|}n||kr*|}|s.dS z||}W n* ty^   |s> d}t||k r\|ds\||t	7 }t||k r\|drKY nw |  jt|7  _t||k r|ru|drw|st
d| jf |S )N       
z;unexpected end of file while reading request at position %s)rS   readliner\   rT   rb   rU   OverflowErrorlenendswithMAX_REQUEST_LINEIOError)rO   lengthuse_readlinereaderrT   leftr\   r,   r,   r-   _do_read   s<   

zInput._do_readc                 C   s   t  }	 |d}|sd| _td|dv rn|tvr#d| _td||| | dkr5d| _tdq|dkrYd	}|tk rR|d}|d
krJn|d7 }|tk s@d| _td|d
kr|| j|dd t	|
 d}|d	krz| |rz	 | |st|S d S )NrZ   TzEOF before chunk end reached)      ;zNon-hex data   zChunk-size too large.rq   r   rp   zToo large chunk extensionnewline_only)r   r\   rX   rF   _HEXwritetellri   _Input__read_chunk_size_crlfintgetvalue_Input__read_chunk_trailer)rO   rS   bufchariresultr,   r,   r-   __read_chunk_length   sF   $





zInput.__read_chunk_lengthc                 C   s   d}d}d}|t k r?|d}|dkr| j|dd 	 | S d}|dkr*|dkr*d}|s7|tvr7td|f |d7 }|t k s
d| _td	)
Nr   TFrZ   rp   rs      :zInvalid token character: %rzToo large chunk trailer)ri   r\   rx   _ALLOWED_TOKEN_CHARSrF   rX   )rO   rS   r~   emptyseen_field_namer}   r,   r,   r-   __read_chunk_trailerP  s$   
zInput.__read_chunk_trailerc                 C   sT   |s| d}|dkrd| _td|f | d}|dkr(d| _td|f d S )NrZ   rp   TzLine didn't end in CRLF: %rrd   zLine didn't end in LF: %r)r\   rX   rF   )rO   rS   rt   r}   r,   r,   r-   __read_chunk_size_crlfp  s   

zInput.__read_chunk_size_crlfc           	      C   s  | j }|   |dkrdS |r| j j}n| j j}g }| jdkr| j| j }|d ur/||k r/|}|dkru||}|sCd| _d| _tdt|}|	| |  j|7  _| j| jkr^| 
| |d urk||8 }|dkrkn|rt|d dkrtnn	| || _d| _| jdksd|S )Nr   rc   Tz1unexpected end of file while parsing chunked datarY   
   )rS   rb   re   r\   rW   rU   rX   rj   rg   appendrx   _Input__read_chunk_lengthjoin)	rO   rk   rl   rS   rm   response
maxreadlendatadatalenr,   r,   r-   _chunked_read|  sD   





!zInput._chunked_readc                 C   s.   |d ur
|dk r
d }| j r| |S | |S )Nr   rV   r   ro   )rO   rk   r,   r,   r-   r\     s
   

z
Input.readc                 C   s4   |d ur
|dk r
d }| j r| |dS | j|ddS )Nr   T)rl   r   )rO   sizer,   r,   r-   re     s
   zInput.readlinec                 C   s   t | S rK   )list)rO   hintr,   r,   r-   	readlines  s   zInput.readlinesc                 C   s   | S rK   r,   ra   r,   r,   r-   __iter__     zInput.__iter__c                 C   s   |   }|st|S rK   )re   StopIterationrO   liner,   r,   r-   next  s   z
Input.next)NF)FrK   )rG   rH   rI   	__slots__rM   r^   rb   ro   r   r{   rx   r   r\   re   r   r   r   __next__r,   r,   r,   r-   rQ      s     


3b
 

1

rQ   )clientc                       s>   e Zd Z fddZd
ddZedd Zedd	 Z  ZS )
OldMessagec                    s"   t tj| jdi | d| _d S )Nr4   r,   )superr   HTTPMessagerM   status)rO   kwargs	__class__r,   r-   rM     s   
zOldMessage.__init__Nc                 C   s   |  ||S rK   get)rO   namedefaultr,   r,   r-   	getheader     zOldMessage.getheaderc                 c   s$    | j D ]\}}d||f V  qd S )Nz%s: %s
)_headers)rO   keyrD   r,   r,   r-   headers  s   zOldMessage.headersc                 C   s
   |  dS )Nzcontent-typer   ra   r,   r,   r-   
typeheader  s   
zOldMessage.typeheaderrK   )	rG   rH   rI   rM   r   propertyr   r   __classcell__r,   r,   r   r-   r     s    

r   c                 G   s8   z
t j| td}W |S  t jy   t }d|_Y |S w )N)_classzLine too long)r   parse_headersr   LineTooLongr   )fpargsretr,   r,   r-   headers_factory  s   r   c                   @   s  e Zd ZdZdZdd ZdZdZdZdZ	dZ
dZdZdZdZdZdZdZdZdZdZdZdZdZdZee ZdZdZdZd:dd	Zd
d Z dd Z!dd Z"e#e$j%Z&dd Z'dd Z(dd Z)dd Z*dd Z+dd Z,e-fddZ.e/Z0dd Z1d d! Z2d:d"d#Z3d$d% Z4d&d' Z5d(d) Z6d*d+ Z7e8j9e8j:fZ;ze;e8j<f7 Z;W n	 e=y   Y nw d,d- Z>d.d/ Z?d0d1 Z@d2d3 ZAd4d5 ZBd6d7 ZCd8d9 ZDdS );r   a/  
    Handles HTTP requests from a socket, creates the WSGI environment, and
    interacts with the WSGI application.

    This is the default value of :attr:`WSGIServer.handler_class`.
    This class may be subclassed carefully, and that class set on a
    :class:`WSGIServer` instance through a keyword argument at
    construction time.

    Instances are constructed with the same arguments as passed to the
    server's :meth:`WSGIServer.handle` method followed by the server
    itself. The application and environment are obtained from the server.

    HTTP/1.1c                 G   s   t | S rK   )r   )rO   r   r,   r,   r-   MessageClass     zWSGIHandler.MessageClassNFr   c                 C   s6   || _ || _|| _|d u r|dd| _d S || _d S )NrbrY   )r   client_addressservermakefilerS   )rO   sockaddressr   rS   r,   r,   r-   rM   "  s   
zWSGIHandler.__init__c                 C   s  z~| j dur6t | _d| _|  }|du rn|du rq|\| _}| j | | jdkr1t | _|   	 W | j durht| j dd}z|rWz|	d W |
  n|
  w | j 
  W n
 t jyg   Y nw | jdd | jdd | jdd dS | j durt| j dd}z|rz|	d W |
  n|
  w | j 
  W n
 t jy   Y nw | jdd | jdd | jdd w )	a  
        The main request handling method, called by the server.

        This method runs a request handling loop, calling
        :meth:`handle_one_request` until all requests on the
        connection have been handled (that is, it implements
        keep-alive).
        Nr   T_sockr[   r   rS   
wsgi_input)r   r6   
time_starttime_finishhandle_one_requestr   r_   log_requestgetattrrecvr2   error__dict__pop)rO   r   response_bodyr   r,   r,   r-   handle0  sX   	






zWSGIHandler.handlec                 C   sX   | j }|ds
dS tdd |dd  dD }|d dk s(|d	k s(|d
kr*dS dS )NzHTTP/Fc                 s       | ]}t |V  qd S rK   )ry   )r*   xr,   r,   r-   r.   `      z2WSGIHandler._check_http_version.<locals>.<genexpr>   .rZ   r   )r   	   )   r   T)request_version
startswithtuplesplit)rO   version_strversionr,   r,   r-   _check_http_version\  s   
 zWSGIHandler._check_http_versionc                 C   s  |  | _| j }t|dkr$|\| _| _| _|  s#td|f n't|dkrD|\| _| _| jdkr@td| j| j|f d| _ntd|f | 	| j
d| _| jjr`td	| jjf | jd
d dkr{z| jd= W n	 tyz   Y nw | jd}|durt|}|dk rtd|f |r| jdv rtd|| _| jdkr| jdd }|dk| _dS | jdkr| jdd }|dk| _dS d| _dS )a+  
        Parse the incoming request.

        Parses various headers into ``self.headers`` using
        :attr:`MessageClass`. Other attributes that are set upon a successful
        return of this method include ``self.content_length`` and ``self.close_connection``.

        :param str raw_requestline: A native :class:`str` representing
           the request line. A processed version of this will be stored
           into ``self.requestline``.

        :raises ValueError: If the request is invalid. This error will
           not be logged as a traceback (because it's a client issue, not a server problem).
        :return: A boolean value indicating whether the request was successfully parsed.
           This method should either return a true value or have raised a ValueError
           with details about the parsing error.

        .. versionchanged:: 1.1b6
           Raise the previously documented :exc:`ValueError` in more cases instead of returning a
           false value; this allows subclasses more opportunity to customize behaviour.
           zInvalid http version: %rr   GETz4Expected GET method; Got command=%r; path=%r; raw=%rzHTTP/0.9zInvalid HTTP method: %rr   zInvalid headers status: %rztransfer-encodingr4   chunkedcontent-lengthNzInvalid Content-Length: %r)HEADzUnexpected Content-Lengthr   r1   r2   HTTP/1.0z
keep-aliveT)rstriprequestliner   rg   commandpathr   r   rJ   r   rS   r   r   r   lowerKeyErrorry   rT   close_connection)rO   raw_requestlinewordsrT   conntyper,   r,   r-   read_requeste  sT   







zWSGIHandler.read_requestc                 G   s   |s|}nz|| }W n t y   |   d||f }Y nw z	d| j|f }W n	 t y1   Y nw z| jj|d  W d S  t yL   |   Y d S w )Nz%r %rz%s: %s
)	Exception_print_unexpected_excr   r   	error_logrv   )rO   msgr   rP   r,   r,   r-   	log_error  s$   zWSGIHandler.log_errorc                 C   s   | j t}|d}|S )a$  
        Read and return the HTTP request line.

        Under both Python 2 and 3, this should return the native
        ``str`` type; under Python 3, this probably means the bytes read
        from the network need to be decoded (using the ISO-8859-1 charset, aka
        latin-1).
        r   )rS   re   ri   decoder   r,   r,   r-   read_requestline  s   	
zWSGIHandler.read_requestlinec              
   C   s   | j jrdS z|  | _t| jtr| jd| _W n tjy%   Y dS w | js+dS d| _	t
| jtkr9dtfS z| | jsEdtfW S W n ty] } z| |W  Y d}~S d}~ww |  | _| jj| _|   | jrqdS | j jrwdS dS )a  
        Handles one HTTP request using ``self.socket`` and ``self.rfile``.

        Each invocation of this method will do several things, including (but not limited to):

        - Read the request line using :meth:`read_requestline`;
        - Read the rest of the request, including headers, with :meth:`read_request`;
        - Construct a new WSGI environment in ``self.environ`` using :meth:`get_environ`;
        - Store the application in ``self.application``, retrieving it from the server;
        - Handle the remainder of the request, including invoking the application,
          with :meth:`handle_one_response`

        There are several possible return values to indicate the state
        of the client connection:

        - ``None``
            The client connection is already closed or should
            be closed because the WSGI application or client set the
            ``Connection: close`` header. The request handling
            loop should terminate and perform cleanup steps.
        - (status, body)
            An HTTP status and body tuple. The request was in error,
            as detailed by the status and body. The request handling
            loop should terminate, close the connection, and perform
            cleanup steps. Note that the ``body`` is the complete contents
            to send to the client, including all headers and the initial
            status line.
        - ``True``
            The literal ``True`` value. The request was successfully handled
            and the response sent to the client by :meth:`handle_one_response`.
            The connection remains open to process more requests and the connection
            handling loop should call this method again. This is the typical return
            value.

        .. seealso:: :meth:`handle`

        .. versionchanged:: 1.1b6
           Funnel exceptions having to do with invalid HTTP requests through
           :meth:`_handle_client_error` to allow subclasses to customize. Note that
           this is experimental and may change in the future.
        Nr   r   414400T)rS   closedr   r   
isinstancebytesr   r   r   response_lengthrg   ri   _REQUEST_TOO_LONG_RESPONSEr   _BAD_REQUEST_RESPONSEr   _handle_client_errorget_environenvironr   applicationhandle_one_responser   rO   exr,   r,   r-   r     s>   +



zWSGIHandler.handle_one_requestc                 C   s8   | j dd dkrdS | j dd dkrdS dS )Nr1   r4   upgradeTUpgrade	websocketF)r   r   r   ra   r,   r,   r-   _connection_upgrade_requested.  s
   z)WSGIHandler._connection_upgrade_requestedc                 C   s   | j d u r| jdtt f | jdk| _| jdvrY| jd u r[t| j	drDt
dd | j	D }t|}|d}| jd|f d S | j oL| jd	k| _| jr]| jd
 d S d S d S d S )Ns   Datee   i0     __len__c                 s   r   rK   )rg   )r*   chunkr,   r,   r-   r.   ?  r   z/WSGIHandler.finalize_headers.<locals>.<genexpr>r   s   Content-Lengthr   )s   Transfer-Encodings   chunked)provided_dateresponse_headersr   rE   r6   codeconnection_upgradedprovided_content_lengthhasattrr   sumstrr(   r   response_use_chunked)rO   	total_lentotal_len_strr,   r,   r-   finalize_headers5  s$   



zWSGIHandler.finalize_headersc              
   C   sb   z| j | W n t jy% } zd| | _| jdkr | j | _ d }~ww |  jt|7  _d S )Nzsocket error: %sr   )r   r_   r   r   r  r   rg   )rO   r   r  r,   r,   r-   _sendallK  s   


zWSGIHandler._sendallc                 C   sN   |sd S | j r dt| }||}||7 }|d7 }| | d S | | d S )Ns   %x
   
)r  rg   r  )rO   r   
_bytearray
header_strtowriter,   r,   r-   _writeU  s   zWSGIHandler._writec                 C   sP   | j dv r|r| d| j  | jr| | d S | js!| d| | d S )Nr	  z!The %s response must have no bodyz-The application did not call start_response())r  ApplicationErrorheaders_sentr  r   _write_with_headersrO   r   r,   r,   r-   rv   k  s   
zWSGIHandler.writec                 C   sx   d| _ |   td}|| j7 }|d7 }| jD ]\}}||7 }|d7 }||7 }|d7 }q|d7 }| | | | d S )NTs	   HTTP/1.1 r  s   : )r   r  	bytearrayr   r  r  r  )rO   r   r  headerrD   r,   r,   r-   r!  z  s   


zWSGIHandler._write_with_headersc                 C   s  |rz| j r
t|  W d}nd}w g }d}d}zF|D ]A\}}t|ts)td||t|ts4td||d|v s<d|v rAtd|d|v sId|v rNtd|||d|df qW n tyn   td	t	|t	|w t|tsxtd
d|v sd|v rtd|t
|ddd }|d| _|| _|| _|| _d}d| _d| _|D ]\}}| }|dkr|}q|dkr|| _q|dkr|| _q| jdkr|du r| jrdnd}	|d|	f n|dkrd| _| jdv r
| jdur
| jdkr
d| j| jf }
|
d}
| |
| jS )a  
         .. versionchanged:: 1.2a1
            Avoid HTTP header injection by raising a :exc:`ValueError`
            if *status* or any *header* name or value contains a carriage
            return or newline.
         .. versionchanged:: 1.1b5
            Pro-actively handle checking the encoding of the status line
            and headers during this method. On Python 2, avoid some
            extra encodings.
        Nz"The header must be a native stringz!The value must be a native stringr   z)carriage return or newline in header namez*carriage return or newline in header valuer   zNon-latin1 headerz)The status string must be a native stringz$carriage return or newline in status rZ   r   
connectiondater   r   s   closes
   keep-alives
   Connectionr2   Tr	  0zCInvalid Content-Length for %s response: %r (must be absent or zero))r   r	   r   r  UnicodeErrorrL   r   r(   UnicodeEncodeErrorreprry   r   r   _orig_statusr  r  r  r  r   r   r   r  rv   )rO   r   r   exc_infor  r$  rD   r  provided_connectionr   r   r,   r,   r-   start_response  st   







zWSGIHandler.start_responsec                 C   s   | j j|  d  d S )Nr   )r   logrv   format_requestra   r,   r,   r-   r     s   zWSGIHandler.log_requestc                 C   s   t  jdd}| jpd}| jrd| j| j  }nd}t| jtr&| jd n| j}d|p-d|| j	p2d| j
p9| jp9d d ||f S )Nr   )microsecond-z%.6fz%s - - [%s] "%s" %s %s %sr4   000)r   nowreplacer   r   r   r   r   r   r   r-  r   r   )rO   r6  rk   deltar   r,   r,   r-   r2    s   
zWSGIHandler.format_requestc                 C   sH   | j D ]	}|r| | q| jr| js| d | jr"| d d S d S )Nrc   s   0

)r   rv   r   r   r  r  r"  r,   r,   r-   process_result  s   


zWSGIHandler.process_resultc                 C   s   | j d u sJ z3| | j| j| _ |   W t| j dd }z|d ur-|  W d }d | _ d S W d }d | _ d S d }d | _ w t| j dd }z|d urQ|  W d }d | _ w W d }d | _ w d }d | _ w )Nr2   )r   r   r   r0  r9  r   )rO   r2   r,   r,   r-   run_application  s4   


zWSGIHandler.run_applicationc                 C   s  t   | _d| _d| _d| _d| _d| _d| _zz:z|   W z| j	
  W n* ty.     tjy7   Y nw z| j	
  W w  tyG     tjyP   Y w w W nZ tyq } z| | d| _| d W Y d}~nLd}~w tjy } z|jd | jv rd| _n| jt   W Y d}~n3d}~w   | jt   Y W t   | _|   dS W t   | _|   dS W t   | _|   dS W t   | _|   dS t   | _|   w )z
        Invoke the application to produce one response.

        This is called by :meth:`handle_one_request` after all the
        state for the request has been established. It is responsible
        for error handling.
        NFr   Tr5   )r6   r   r   r   r   r  r  r   r:  r   r^   rF   r   r   r   r    _send_error_response_if_possibler   ignored_socket_errorshandle_errorsysr.  r   r   r  r,   r,   r-   r  @  sd   









zWSGIHandler.handle_one_responsec                 C   s`   | j rd| _d S t| \}}}z| ||d d   | | W d S  tjy/   d| _Y d S w )NT)r   r   _ERRORSr0  rv   r   r   )rO   
error_coder   r   bodyr,   r,   r-   r;  z  s   
z,WSGIHandler._send_error_response_if_possiblec                 C   sF   t |ts!| j}t|| jjs| j|}| jj|||| d S d S rK   )
issubclassr   r   r   r   secure_environ_classloopr=  )rO   tvtbcontextr,   r,   r-   
_log_error  s   
zWSGIHandler._log_errorc                 C   s(   |  ||| d  } }}| d d S )Nr3   )rI  r;  )rO   rE  rF  rG  r,   r,   r-   r=    s   zWSGIHandler.handle_errorc                 C   s^   t |ttfst  t |tr| d| j|j dtfS | d| jt	|p)|j
j dtfS )Nz(from %s) %szInvalid request (from %s): %sr   )r   rL   rF   	traceback	print_excrJ   r   r   rN   r  r   rG   r   r  r,   r,   r-   r     s   
z WSGIHandler._handle_client_errorc                 c   s    d }d }d}| j j D ]7}|d ur|d d dv r||7 }q||vr+d| | fV  |dd\}}d|v r:d }q|dd }q||vrRd| | fV  d S d S )N)NCONTENT_TYPECONTENT_LENGTHrZ   z 	HTTP_:_r4  )r   stripr   r7  upper)rO   r   rD   IGNORED_KEYSr$  r,   r,   r-   r     s"   zWSGIHandler._headersc                 C   s  | j  }| j|d< d|d< d| jv r| jddn| jdf\}}t||d< ||d< | jjdur7| jj|d	< | jd
}|rC||d< | j	|d< | j
}t|tr`t|d |d< t|d |d< |  D ]&\}}||v rd|v r{||  d| 7  < qd||  d| 7  < qd|||< qd|ddkr| jnd}|dd dk}	|   }
t| j| j||	d| _|
r| jn| j|d< |
|d< |S )a  
        Construct and return a new WSGI environment dictionary for a specific request.

        This should begin with asking the server for the base environment
        using :meth:`WSGIServer.get_environ`, and then proceed to add the
        request specific values.

        By the time this method is invoked the request line and request shall have
        been parsed and ``self.headers`` shall be populated.
        REQUEST_METHODr4   SCRIPT_NAME?rZ   	PATH_INFOQUERY_STRINGNrL  r   rM  SERVER_PROTOCOLr   REMOTE_ADDRREMOTE_PORTCOOKIEz; ,HTTP_EXPECTz100-continueHTTP_TRANSFER_ENCODINGr   )r   rV   z
wsgi.inputzwsgi.input_terminated)r   r   r   r   r   unquote_latin1r   r   r   r   r   r   r   r  r   r   r   r   r  rQ   rS   rT   r   )rO   envr   queryrk   r   r   rD   r   r   handling_readsr,   r,   r-   r     s:   

&



zWSGIHandler.get_environrK   )ErG   rH   rI   __doc__protocol_versionr   r   r-  r  r  r  r  r   r   r   r   r  r  r   r   r   r   r   r   rT   r   r   r   r   r   r   rM   r   r   r   staticmethodrJ  rK  r   r   r   r   r  r  r  r#  r  AssertionErrorr  rv   r!  r0  r   r2  r9  r:  errnoEPIPE
ECONNRESETr<  WSAECONNABORTEDAttributeErrorr  r;  rI  r=  r   r   r   r,   r,   r,   r-   r     sz    

,	
I[

h :	r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )_NoopLogc                 O      d S rK   r,   rO   r   r   r,   r,   r-   rv     s   z_NoopLog.writec                 C   rn  rK   r,   ra   r,   r,   r-   flush  r   z_NoopLog.flushc                 O   rn  rK   r,   ro  r,   r,   r-   
writelines  r   z_NoopLog.writelinesN)rG   rH   rI   rv   rp  rq  r,   r,   r,   r-   rm    s    rm  c                   @   sN   e Zd ZdZdZdddZdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )r   ap  
    An adapter for :class:`logging.Logger` instances
    to let them be used with :class:`WSGIServer`.

    .. warning:: Unless the entire process is monkey-patched at a very
        early part of the lifecycle (before logging is configured),
        loggers are likely to not be gevent-cooperative. For example,
        the socket and syslog handlers use the socket module in a way
        that can block, and most handlers acquire threading locks.

    .. warning:: It *may* be possible for the logging functions to be
       called in the :class:`gevent.Hub` greenlet. Code running in the
       hub greenlet cannot use any gevent blocking functions without triggering
       a ``LoopExit``.

    .. versionadded:: 1.1a3

    .. versionchanged:: 1.1b6
       Attributes not present on this object are proxied to the underlying
       logger instance. This permits using custom :class:`~logging.Logger`
       subclasses (or indeed, even duck-typed objects).

    .. versionchanged:: 1.1
       Strip trailing newline characters on the message passed to :meth:`write`
       because log handlers will usually add one themselves.
    _logger_level   c                 C   s   || _ || _dS )z[
        Write information to the *logger* at the given *level* (default to INFO).
        Nrr  )rO   loggerlevelr,   r,   r-   rM   ;  s   
zLoggingLogAdapter.__init__c                 C   s.   |r| dr|d d }| j| j| d S )Nr   rY   )rh   rs  r1  rt  )rO   r   r,   r,   r-   rv   B  s   zLoggingLogAdapter.writec                 C   s   dS )z(No-op; required to be a file-like objectNr,   ra   r,   r,   r-   rp  G  s    zLoggingLogAdapter.flushc                 C   s   |D ]}|  | qd S rK   )rv   )rO   linesr   r,   r,   r-   rq  J  s   zLoggingLogAdapter.writelinesc                 C   s   t | j|S rK   )r   rs  rO   r   r,   r,   r-   __getattr__N  r   zLoggingLogAdapter.__getattr__c                 C   s.   |t jvrt| j|| d S t| || d S rK   )r   r   setattrrs  object__setattr__)rO   r   rD   r,   r,   r-   r}  Q  s   
zLoggingLogAdapter.__setattr__c                 C   s   t | j| d S rK   )delattrrs  ry  r,   r,   r-   __delattr__W  s   zLoggingLogAdapter.__delattr__Nru  )rG   rH   rI   rd  r   rM   rv   rp  rq  rz  r}  r  r,   r,   r,   r-   r     s    
r   c                   @   s6   e Zd ZdZdZdd Zeedsdd Zdd	 Z	d
S )r   zx
    A base class that can be used for WSGI environment objects.

    Provisional API.

    .. versionadded:: 1.2a1
    r,   c                 C   s
   |  | S rK   r   ra   r,   r,   r-   copyw  s   
zEnviron.copy	iteritemsc                 C   s   |   S rK   )itemsra   r,   r,   r-   r  |  r   zEnviron.iteritemsc                 C   s   t dd d t|  fS )Nr,   )dictiterr  )rO   protor,   r,   r-   __reduce_ex__  s   zEnviron.__reduce_ex__N)
rG   rH   rI   rd  r   r  r  r  r  r  r,   r,   r,   r-   r   l  s    
r   c                   @   s4   e Zd ZdZdZdZdZdZdd Zdd Z	e	Z
d	S )
r   a  
    An environment that does not print its keys and values
    by default.

    Provisional API.

    This is intended to keep potentially sensitive information like
    HTTP authorization and cookies from being inadvertently printed
    or logged.

    For debugging, each instance can have its *secure_repr* attribute
    set to ``False``, which will cause it to print like a normal dict.

    When *secure_repr* is ``True`` (the default), then the value of
    the *whitelist_keys* attribute is consulted; if this value is
    true-ish, it should be a container (something that responds to
    ``in``) of key names (typically a list or set). Keys and values in
    this dictionary that are in *whitelist_keys* will then be printed,
    while all other values will be masked. These values may be
    customized on the class by setting the *default_secure_repr* and
    *default_whitelist_keys*, respectively::

        >>> environ = SecureEnviron(key='value')
        >>> environ # doctest: +ELLIPSIS
        <pywsgi.SecureEnviron dict (keys: 1) at ...

    If we whitelist the key, it gets printed::

        >>> environ.whitelist_keys = {'key'}
        >>> environ
        {'key': 'value'}

    A non-whitelisted key (*only*, to avoid doctest issues) is masked::

        >>> environ['secure'] = 'secret'; del environ['key']
        >>> environ
        {'secure': '<MASKED>'}

    We can turn it off entirely for the instance::

        >>> environ.secure_repr = False
        >>> environ
        {'secure': 'secret'}

    We can also customize it at the class level (here we use a new
    class to be explicit and to avoid polluting the true default
    values; we would set this class to be the ``environ_class`` of the
    server)::

        >>> class MyEnviron(SecureEnviron):
        ...    default_whitelist_keys = ('key',)
        ...
        >>> environ = MyEnviron({'key': 'value'})
        >>> environ
        {'key': 'value'}

    .. versionadded:: 1.2a1
    Tr,   )secure_reprwhitelist_keysprint_masked_keysc                 C   s$   |t jv rtt| d| S t|)Ndefault_)r   r   r   typerl  ry  r,   r,   r-   rz    s   
zSecureEnviron.__getattr__c                    s   j r@jj r6 fddD }t|} s4t|tkr4|d d dtt|   }|S dttf S tS )Nc                    s.   i | ]}|v s
 r||v r| nd qS )z<MASKED>r,   )r*   kprint_maskedrO   	whitelistr,   r-   
<dictcomp>  s
    z*SecureEnviron.__repr__.<locals>.<dictcomp>rY   z, (hidden keys: %d)}z,<pywsgi.SecureEnviron dict (keys: %d) at %s>)r  r  r  r,  rg   idr   __repr__)rO   safe	safe_reprr,   r  r-   r    s    
zSecureEnviron.__repr__N)rG   rH   rI   rd  default_secure_reprdefault_whitelist_keysdefault_print_masked_keysr   rz  r  __str__r,   r,   r,   r-   r     s    ;r   c                   @   s   e Zd ZdZdZdZdS )r   a  
    Specializes the default list of whitelisted keys to a few
    common WSGI variables.

    Example::

       >>> environ = WSGISecureEnviron(REMOTE_ADDR='::1', HTTP_AUTHORIZATION='secret')
       >>> environ
       {'REMOTE_ADDR': '::1', (hidden keys: 1)}
       >>> import pprint
       >>> pprint.pprint(environ)
       {'REMOTE_ADDR': '::1', (hidden keys: 1)}
       >>> print(pprint.pformat(environ))
       {'REMOTE_ADDR': '::1', (hidden keys: 1)}
    )rZ  r[  	HTTP_HOSTFN)rG   rH   rI   rd  r  r  r,   r,   r,   r-   r     s    r   c                   @   s   e Zd ZdZeZdZdZeZ	e
Zddejdd ejdd   dddd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S )r   a  
    A WSGI server based on :class:`StreamServer` that supports HTTPS.


    :keyword log: If given, an object with a ``write`` method to which
        request (access) logs will be written. If not given, defaults
        to :obj:`sys.stderr`. You may pass ``None`` to disable request
        logging. You may use a wrapper, around e.g., :mod:`logging`,
        to support objects that don't implement a ``write`` method.
        (If you pass a :class:`~logging.Logger` instance, or in
        general something that provides a ``log`` method but not a
        ``write`` method, such a wrapper will automatically be created
        and it will be logged to at the :data:`~logging.INFO` level.)

    :keyword error_log: If given, a file-like object with ``write``,
        ``writelines`` and ``flush`` methods to which error logs will
        be written. If not given, defaults to :obj:`sys.stderr`. You
        may pass ``None`` to disable error logging (not recommended).
        You may use a wrapper, around e.g., :mod:`logging`, to support
        objects that don't implement the proper methods. This
        parameter will become the value for ``wsgi.errors`` in the
        WSGI environment (if not already set). (As with *log*,
        wrappers for :class:`~logging.Logger` instances and the like
        will be created automatically and logged to at the :data:`~logging.ERROR`
        level.)

    .. seealso::

        :class:`LoggingLogAdapter`
            See important warnings before attempting to use :mod:`logging`.

    .. versionchanged:: 1.1a3
        Added the ``error_log`` parameter, and set ``wsgi.errors`` in the WSGI
        environment to this value.
    .. versionchanged:: 1.1a3
        Add support for passing :class:`logging.Logger` objects to the ``log`` and
        ``error_log`` arguments.
    .. versionchanged:: 20.6.0
        Passing a ``handle`` kwarg to the constructor is now officially deprecated.
    NzCGI/1.1zgevent/%d.%d Python/%d.%dr   r4   )rZ   r   F)GATEWAY_INTERFACESERVER_SOFTWARErU  zwsgi.versionzwsgi.multithreadwsgi.multiprocesszwsgi.run_oncer   c	                 K   s   d|	v rdd l }
|
jdtdd tj| |f||d|	 |d ur$|| _|d ur+|| _ddd	}||| _||d
| _| 	| | 
  d S )Nr   r   zMPassing 'handle' kwarg to WSGIServer is deprecated. Did you mean application?r   )
stacklevel)backlogspawnru  c                 S   s>   | dkrt jS | d u rt S t| dst| drt| |S | S )Nr   rv   r1  )r>  stderrrm  r  r   )lrw  r,   r,   r-   	_make_log_  s   
z&WSGIServer.__init__.<locals>._make_log(   r  )warningswarnDeprecationWarningr   rM   r   handler_classr1  r   set_environset_max_accept)rO   listenerr   r  r  r1  r   r  r   ssl_argsr  r  r,   r,   r-   rM   E  s   	


zWSGIServer.__init__c                 C   s|   |d ur|| _ t| dd }| | j| _ | jrd| j d< nd| j d< |d ur,| j | | j dd u r<| j| j d< d S d S )Nr   httpszwsgi.url_schemehttpzwsgi.errors)r   r   environ_classbase_envssl_enabledupdater   r   )rO   r   environ_updater,   r,   r-   r  m  s   
zWSGIServer.set_environc                 C   s   | j drd| _d S d S )Nr  rZ   )r   r   
max_acceptra   r,   r,   r-   r  |  s   
zWSGIServer.set_max_acceptc                 C   s   |  | jS rK   )r  r   ra   r,   r,   r-   r     r   zWSGIServer.get_environc                 C   s   t |  |   d S rK   )r   init_socketupdate_environra   r,   r,   r-   r    s   
zWSGIServer.init_socketc                 C   s   | j }t|trCd| jvr6z	t|d }W n tjy&   t|d }Y nw t|ts1|d}|| jd< | j	dt|d  dS | j	dd | j	dd dS )z
        Called before the first request is handled to fill in WSGI environment values.

        This includes getting the correct server name and port.
        SERVER_NAMEr   r&   SERVER_PORTrZ   r4   N)
r   r   r   r   r   getfqdnr   r  r   
setdefault)rO   r   r   r,   r,   r-   r    s   




zWSGIServer.update_environc                 C   s   |  ||| }|  dS )z
        Create an instance of :attr:`handler_class` to handle the request.

        This method blocks until the handler returns.
        N)r  r   )rO   r   r   handlerr,   r,   r-   r     s   zWSGIServer.handle)NNr   r   r   NNrK   )rG   rH   rI   rd  r   r  r1  r   r  r  r   rC  geventversion_infor>  r  rM   r  r  r   r  r  r   r,   r,   r,   r-   r     s4    1	

(r   c                  C   s   ddl m}  |   dd l}dd l}| }|jddd |jdddd	d
 | }|j	d\}}|
|}t||}|j}	t|	|}
|
  d S )Nr   )monkeyappz2dotted name of WSGI app callable [module:callable])helpz-bz--bindzThe socket to bindz:8080)r  r   rO  )r  r  	patch_allargparse	importlibArgumentParseradd_argument
parse_argsr  r   import_moduler   bindr   serve_forever)r  r  r  parserr   module_nameapp_namemoduler  r  r   r,   r,   r-   _main  s    


r  __main__)Hrd  
__future__r   rh  ior   stringr>  r6   rJ  r   urllib.parser   r  r   gevent.serverr   
gevent.hubr   gevent._compatr	   	functoolsr
   r`  _no_undoc_members__all__ri   r8   r9   	hexdigitsr(   ru   	frozensetascii_lettersr   r?  _INTERNAL_ERROR_STATUS_INTERNAL_ERROR_BODYr  rg   _INTERNAL_ERROR_HEADERS_BAD_REQUEST_STATUS_BAD_REQUEST_BODY_BAD_REQUEST_HEADERSr   r   r`   rE   rj   rF   rL   rJ   r|  rQ   	mimetoolsMessager   ImportErrorr  r   r   r   r   rm  r   r  r   r   r   r   r  rG   r,   r,   r,   r-   <module>   s   


  5
      &R\ 5

