B
    iSIZ|                 @   sb  d 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ZeedZ	yddl
Z
W n ek
rf   dZ
Y nX yddlZW n* ek
r   G dd deZe ZY nX dd ZyddlZdd	lmZmZ W n, ek
r   ddlZdd	lmZmZ Y nX ejZe	rejZnG d
d deZddlZddlmZ ddlmZmZmZmZ ddl m!Z!m"Z" ddl#m$Z$ dZ%e oreedZ&G dd dej'Z(G dd deeZ)e)Z*d;ddZ+d<ddZ,dd Z-d=ddZ.G dd deZ/d>d d!Z0d"d# Z1d$d% Z2G d&d' d'eeZ3G d(d) d)ee3Z4G d*d+ d+ee3Z5d?d.d/Z6d0d1 Z7d@d4d5Z8d6d7 Z9d8d9 Z:e;d:kr^e:  dS )Aa}  
    werkzeug.serving
    ~~~~~~~~~~~~~~~~

    There are many ways to serve a WSGI application.  While you're developing
    it you usually don't want a full blown webserver like Apache but a simple
    standalone one.  From Python 2.5 onwards there is the `wsgiref`_ server in
    the standard library.  If you're using older versions of Python you can
    download the package from the cheeseshop.

    However there are some caveats. Sourcecode won't reload itself when
    changed and each time you kill the server using ``^C`` you get an
    `KeyboardInterrupt` error.  While the latter is easy to solve the first
    one can be a pain in the ass in some situations.

    The easiest way is creating a small ``start-myproject.py`` that runs the
    application::

        #!/usr/bin/env python
        # -*- coding: utf-8 -*-
        from myproject import make_app
        from werkzeug.serving import run_simple

        app = make_app(...)
        run_simple('localhost', 8080, app, use_reloader=True)

    You can also pass it a `extra_files` keyword argument with a list of
    additional files (like configuration files) you want to observe.

    For bigger applications you should consider using `click`
    (http://click.pocoo.org) instead of a simple start file.


    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
    )with_statementNforkc               @   s   e Zd Zdd ZdS )	_SslDummyc             C   s   t dd S )NzSSL support unavailable)RuntimeError)selfname r   /lib/python3.7/site-packages/werkzeug/serving.py__getattr__;   s    z_SslDummy.__getattr__N)__name__
__module____qualname__r
   r   r   r   r	   r   :   s   r   c              C   s6   yddl m}  W n tk
r,   tdY nX | S d S )Nr   )cryptoz9Using ad-hoc certificates requires the pyOpenSSL library.)OpenSSLr   ImportError	TypeError)r   r   r   r	   _get_openssl_crypto_module@   s
    r   )
HTTPServerBaseHTTPRequestHandlerc               @   s   e Zd ZdS )ForkingMixInN)r   r   r   r   r   r   r	   r   V   s   r   )_log)PY2WINreraisewsgi_encoding_dance)	url_parseurl_unquote)InternalServerError   fromfdc               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )DechunkedInputz8An input stream that handles Transfer-Encoding 'chunked'c             C   s   || _ d| _d| _d S )NFr   )_rfile_done_len)r   rfiler   r   r	   __init__h   s    zDechunkedInput.__init__c             C   s   dS )NTr   )r   r   r   r	   readablem   s    zDechunkedInput.readablec             C   sT   y"| j  d}t| d}W n tk
r>   tdY nX |dk rPtd|S )Nlatin1   zInvalid chunk headerr   z!Negative chunk length not allowed)r!   readlinedecodeintstrip
ValueErrorIOError)r   liner#   r   r   r	   read_chunk_lenp   s    zDechunkedInput.read_chunk_lenc             C   s   d}x| j s|t|k r| jdkr,|  | _| jdkr<d| _ | jdkrtt|| j}| j||||| < |  j|8  _||7 }| jdkr| j }|dkrtdqW |S )Nr   T)   
s   
   z!Missing chunk terminating newline)	r"   lenr#   r0   minr!   readr)   r.   )r   Zbufr5   n
terminatorr   r   r	   readintoz   s     





zDechunkedInput.readintoN)r   r   r   __doc__r%   r&   r0   r8   r   r   r   r	   r    e   s
   
r    c               @   s   e Zd ZdZedd Zdd Zdd Zdd	 Zd
d Z	d"ddZ
dd Zd#ddZdd Zdd Zdd Zd$ddZdd Zdd Zd d! ZdS )%WSGIRequestHandlerz3A request handler that implements WSGI dispatching.c             C   s
   dt j S )Nz	Werkzeug/)werkzeug__version__)r   r   r   r	   server_version   s    z!WSGIRequestHandler.server_versionc                s&  t  j} fdd} jjd kr&dp(d}t|j}d| jtj jj jj	d| j
 jdt|t|j     jjd t jjd	  jd
}x> j D ]0\}}| dd}|dkrd| }|||< qW |dd  dkrd|d< t|d |d< |jr"|jr"|j|d< |S )Nc                  s   d j _d S )NT)servershutdown_signalr   )r   r   r	   shutdown_server   s    z8WSGIRequestHandler.make_environ.<locals>.shutdown_serverhttphttps)   r   F r   rC   )zwsgi.versionzwsgi.url_schemez
wsgi.inputzwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_oncezwerkzeug.server.shutdownZSERVER_SOFTWAREREQUEST_METHODZSCRIPT_NAMEZ	PATH_INFOZQUERY_STRINGREMOTE_ADDRZREMOTE_PORTZSERVER_NAMEZSERVER_PORTZSERVER_PROTOCOL-_)ZCONTENT_TYPEZCONTENT_LENGTHZHTTP_ZHTTP_TRANSFER_ENCODINGZchunkedTzwsgi.input_terminatedz
wsgi.inputZ	HTTP_HOST)r   pathr>   ssl_contextr   r$   sysstderrmultithreadmultiprocessr=   Zcommandr   Zqueryaddress_stringport_integerserver_addressstrrequest_versionheadersitemsupperreplacegetr,   lowerr    ZschemeZnetloc)r   Zrequest_urlr@   Z
url_schemeZ	path_infoenvironkeyvaluer   )r   r	   make_environ   sB    




zWSGIRequestHandler.make_environc                s8  j dd  dkr&jd   _ g g  fdddfdd	 fd	d
}y|jj	 W n t
jt
jfk
r } z|  W d d }~X Y n| tk
r2   jjr҂ ddlm} |dd}ysd d = |t  W n tk
r   Y nX jdd|j Y nX d S )NZExpectrD   z100-continues   HTTP/1.1 100 Continue

c                sB  st ds \}}d d < y|d d\}}W n tk
rX   |d }}Y nX t|}|| t }x.|D ]&\}}|| | }|| qzW d|ksڈ d dks|dk s|dksd	_	d
d d|krd
  d|krd    t| ts(t dj|  j  d S )Nzwrite() before start_responserC   rD   zcontent-lengthrE   ZHEAD   )   i0  TZ
Connectioncloser>   ZServerZdateZDatezapplications must write bytes)AssertionErrorsplitr-   r+   send_responsesetZsend_headerrY   addclose_connectionversion_stringZdate_time_stringZend_headers
isinstancebyteswfilewriteflush)datastatusresponse_headerscodemsgZheader_keysr[   r\   )rZ   headers_sentheaders_setr   r   r	   rk      s6    
z*WSGIRequestHandler.run_wsgi.<locals>.writec                s>   |rz rt |  W d d }X nr*td| |gd d < S )NzHeaders already set)r   ra   )rn   ro   exc_info)rr   rs   rk   r   r	   start_response   s    z3WSGIRequestHandler.run_wsgi.<locals>.start_responsec          	      sN   |  }z&x|D ]}| qW s.d W d t |drD|  d }X d S )N    r`   )hasattrr`   )appZapplication_iterrm   )rZ   rr   ru   rk   r   r	   execute  s    


z,WSGIRequestHandler.run_wsgi.<locals>.executer   )get_current_tracebackT)Zignore_system_exceptionserrorzError on request:
%s)N)rT   rX   rY   r,   rj   rk   r]   rZ   r>   rx   socketr{   timeoutconnection_dropped	Exceptionpassthrough_errorsZwerkzeug.debug.tbtoolsrz   r   logZ	plaintext)r   ry   erz   	tracebackr   )rZ   rr   rs   r   ru   rk   r	   run_wsgi   s2    


zWSGIRequestHandler.run_wsgic          
   C   s   d}yt | }W nZ tjtjfk
rF } z| | W dd}~X Y n( tk
rl   | jjdksft	 sh Y nX | jj
r~|   |S )z/Handles a request ignoring dropped connections.N)r   handler|   r{   r}   r~   r   r>   rJ   is_ssl_errorr?   initiate_shutdown)r   rvr   r   r   r	   r   !  s    zWSGIRequestHandler.handlec             C   sB   t tdtj}tjddkr.tt | d| j_	d| j_
dS )zpA horrible, horrible way to kill the server for Python 2.6 and
        later.  It's the best we can do.
        SIGKILLWERKZEUG_RUN_MAINtrueTFN)getattrsignalSIGTERMosrZ   rX   killgetpidr>   Z_BaseServer__shutdown_requestZ_BaseServer__serving)r   Zsigr   r   r	   r   /  s
    z$WSGIRequestHandler.initiate_shutdownNc             C   s   dS )z`Called if the connection was closed by the client.  By default
        nothing happens.
        Nr   )r   r{   rZ   r   r   r	   r~   =  s    z%WSGIRequestHandler.connection_droppedc             C   s.   | j  | _| jsd| _n|  r*|  S dS )zHandle a single HTTP request.rC   N)r$   r)   Zraw_requestlinerf   Zparse_requestr   )r   r   r   r	   handle_one_requestB  s
    z%WSGIRequestHandler.handle_one_requestc             C   s^   |  | |dkr.|| jkr*| j| d p,d}| jdkrZd| j||f }| j|d dS )z3Send the response header and log the response code.Nr   rD   zHTTP/0.9z
%s %d %s
ascii)log_requestZ	responsesrS   Zprotocol_versionrj   rk   encode)r   rp   messageZhdrr   r   r	   rc   J  s    

z WSGIRequestHandler.send_responsec             C   s   t |  S )N)r   rg   r,   )r   r   r   r	   rg   S  s    z!WSGIRequestHandler.version_stringc             C   s$   t | dd r| jd S | jd S d S )NrZ   rF   r   )r   rZ   client_address)r   r   r   r	   rO   V  s    
z!WSGIRequestHandler.address_stringc             C   s
   | j d S )NrC   )r   )r   r   r   r	   rP   \  s    zWSGIRequestHandler.port_integerrG   c             C   s   | j }t|}trtj}|d dkr4||dgd}n|d dkrN||dd}nt|dkrd||d	d}n^|d d
kr~||dd}nD|dkr||dd}n.|d dkr||ddgd}n||ddgd}| dd||| d S )Nr   1Zbold)attrs2Zwhite)colorZ304Zcyan3ZgreenZ404Zyellow4Zred)r   r   Zmagentainfoz
"%s" %s %s)ZrequestlinerR   	termcolorZcoloredr   )r   rp   sizerq   r   r   r   r	   r   _  s$    zWSGIRequestHandler.log_requestc             G   s   | j d|  d S )Nr{   )r{   )r   )r   argsr   r   r	   	log_errorw  s    zWSGIRequestHandler.log_errorc             G   s   | j d|f|  d S )Nr   )r   )r   formatr   r   r   r	   log_messagez  s    zWSGIRequestHandler.log_messagec             G   s$   t |d|  |  || f  d S )Nz%s - - [%s] %s
)r   rO   Zlog_date_time_string)r   typer   r   r   r   r	   r   }  s    zWSGIRequestHandler.log)N)N)rG   rG   )r   r   r   r9   propertyr=   r]   r   r   r   r~   r   rc   rg   rO   rP   r   r   r   r   r   r   r   r	   r:      s    -R

	
r:   c             C   s   ddl m } t }| d krd} | }|t| tj  |d |d |	 }| |_
d|_| }d|_
d|_| }||jd || ||d	 ||fS )
Nr   )random*i3zDummy CertificatezUntrusted AuthorityzSelf-Signedi   Zsha256)r   r   ZX509Zset_serial_numberr+   rK   maxsizeZgmtime_adj_notBeforeZgmtime_adj_notAfterZget_subjectZCNOZ
get_issuerZPKeyZgenerate_keyZTYPE_RSAZ
set_pubkeyZsign)cnr   r   certZsubjectZissuerpkeyr   r   r	   generate_adhoc_ssl_pair  s&    


r   c       	   	   C   s   ddl m} |dk	r d||f }t|d\}}| d }| d }t|d}|||j| W dQ R X t|d}|||j| W dQ R X ||fS )	a  Creates an SSL key for development.  This should be used instead of
    the ``'adhoc'`` key which generates a new cert on each server start.
    It accepts a path for where it should store the key and cert and
    either a host or CN.  If a host is given it will use the CN
    ``*.host/CN=host``.

    For more information see :func:`run_simple`.

    .. versionadded:: 0.9

    :param base_path: the path to the certificate and key.  The extension
                      ``.crt`` is added for the certificate, ``.key`` is
                      added for the key.
    :param host: the name of the host.  This can be used as an alternative
                 for the `cn`.
    :param cn: the `CN` to use.
    r   )r   Nz
*.%s/CN=%s)r   z.crtz.keywb)r   r   r   openrk   dump_certificateFILETYPE_PEMdump_privatekey)		base_pathhostr   r   r   r   	cert_file	pkey_filefr   r   r	   make_ssl_devcert  s    r   c        
      C   s   t  } ddl}ddl}t \}}| \}}| \}}|tj| |tj| t|| 	| j
| t|| | j
| t| t| t||}	|	S )z:Generates an adhoc SSL context for the development server.r   N)r   tempfileatexitr   Zmkstempregisterr   removerk   r   r   r   r`   load_ssl_context)
r   r   r   r   r   Zcert_handler   Zpkey_handler   ctxr   r   r	   generate_adhoc_ssl_context  s    



r   c             C   s&   |dkrt j}t|}|| | |S )a  Loads SSL context from cert/private key files and optional protocol.
    Many parameters are directly taken from the API of
    :py:class:`ssl.SSLContext`.

    :param cert_file: Path of the certificate to use.
    :param pkey_file: Path of the private key to use. If not given, the key
                      will be obtained from the certificate file.
    :param protocol: One of the ``PROTOCOL_*`` constants in the stdlib ``ssl``
                     module. Defaults to ``PROTOCOL_SSLv23``.
    N)sslZPROTOCOL_SSLv23_SSLContextload_cert_chain)r   r   protocolr   r   r   r	   r     s
    r   c               @   s*   e Zd ZdZdd Zd	ddZdd ZdS )
r   zuA dummy class with a small subset of Python3's ``ssl.SSLContext``, only
    intended to be used with and by Werkzeug.c             C   s   || _ d | _d | _d | _d S )N)	_protocol	_certfile_keyfile	_password)r   r   r   r   r	   r%     s    z_SSLContext.__init__Nc             C   s   || _ |p|| _|| _d S )N)r   r   r   )r   certfilekeyfileZpasswordr   r   r	   r     s    
z_SSLContext.load_cert_chainc             K   s    t j|f| j| j| jd|S )N)r   r   Zssl_version)r   wrap_socketr   r   r   )r   sockkwargsr   r   r	   r     s    z_SSLContext.wrap_socket)NN)r   r   r   r9   r%   r   r   r   r   r   r	   r     s   
r   c             C   sV   t jf}yddlm} ||f7 }W n tk
r6   Y nX | dkrLt d } t| |S )z?Checks if the given error (or the current one) is an SSL error.r   )ErrorNrC   )r   ZSSLErrorZOpenSSL.SSLr   r   rK   rt   rh   )r{   Z	exc_typesr   r   r   r	   r     s    r   c             C   s   d| krt tdrtjS tjS )z>Returns AF_INET4 or AF_INET6 depending on where to connect to.:AF_INET6)rw   r|   r   ZAF_INET)r   portr   r   r	   select_ip_version  s    r   c             C   sB   yt | ||t jt j}W n t jk
r4   | |fS X |d d S )zSReturns a fully qualified socket address, that can properly used by
    socket.bindr      )r|   ZgetaddrinfoSOCK_STREAMZSOL_TCPZgaierror)r   r   familyZresr   r   r	   get_sockaddr#  s    

r   c               @   sF   e Zd ZdZdZdZeZdddZdd Z	dd	 Z
d
d Zdd ZdS )BaseWSGIServerz3Simple single-threaded, single-process WSGI server.FNc       
      C   s  |d krt }t||| _|d k	r6t|| jtj}d}t| t|t	|| j| || _
|| _d| _|| _| j d | _|d k	r| j  || _| j | _|d k	rt|trt| }|dkrt }| j}	trt|	tjst|	j|	j|	j|	}	|j|	dd| _|| _nd | _d S )Nr   FrC   ZadhocT)Zserver_side)r:   r   address_familyr|   r   r   r   r%   r   r+   rx   r   r?   r   getsocknamer   r`   rQ   rh   tupler   r   r   r   r   protor   rJ   )
r   r   r   rx   handlerr   rJ   fdZ	real_sockr   r   r   r	   r%   5  s:    



zBaseWSGIServer.__init__c             G   s   t ||f|  d S )N)r   )r   r   r   r   r   r   r	   r   ^  s    zBaseWSGIServer.logc             C   s>   d| _ z(yt|  W n tk
r*   Y nX W d |   X d S )NF)r?   r   serve_foreverKeyboardInterruptZserver_close)r   r   r   r	   r   a  s    
zBaseWSGIServer.serve_foreverc             C   s   | j r t| ||S )N)r   r   handle_error)r   Zrequestr   r   r   r	   r   j  s    zBaseWSGIServer.handle_errorc             C   s   | j  \}}||fS )N)r|   Zaccept)r   Zconr   r   r   r	   get_requesto  s    zBaseWSGIServer.get_request)NFNN)r   r   r   r9   rM   rN   LISTEN_QUEUEZrequest_queue_sizer%   r   r   r   r   r   r   r   r	   r   .  s    
(	r   c               @   s   e Zd ZdZdZdZdS )ThreadedWSGIServerz"A WSGI server that does threading.TN)r   r   r   r9   rM   Zdaemon_threadsr   r   r   r	   r   t  s   r   c               @   s   e Zd ZdZdZdddZdS )	ForkingWSGIServerz A WSGI server that does forking.T(   NFc	       	   
   C   s.   t stdt| ||||||| || _d S )Nz'Your platform does not support forking.)can_forkr-   r   r%   Zmax_children)	r   r   r   rx   	processesr   r   rJ   r   r   r   r	   r%     s
    
zForkingWSGIServer.__init__)r   NFNN)r   r   r   r9   rN   r%   r   r   r   r	   r   {  s    r   FrC   c	       	   
   C   sj   |r|dkrt dnP|r0t| ||||||dS |dkrPt| |||||||dS t| ||||||dS dS )ztCreate a new server instance that is either threaded, or forks
    or just processes one request after another.
    rC   z5cannot have a multithreaded and multi process server.)r   N)r-   r   r   r   )	r   r   rx   threadedr   request_handlerr   rJ   r   r   r   r	   make_server  s    


r   c               C   s   t jddkS )zwChecks if the application is running from within the Werkzeug
    reloader subprocess.

    .. versionadded:: 0.10
    r   r   )r   rZ   rX   r   r   r   r	   is_running_from_reloader  s    r   Tautoc          	      sF  t tstd|r,ddlm} | | |rFddlm} | | fdd f	dd}|r<tj	d	d
kr dkrt
stdt}t|tj}|tjtjd |t| t|dr|d t
rt| tjd< |t | n|  ddlm} ||||| n|  dS )a  Start a WSGI application. Optional features include a reloader,
    multithreading and fork support.

    This function has a command-line interface too::

        python -m werkzeug.serving --help

    .. versionadded:: 0.5
       `static_files` was added to simplify serving of static files as well
       as `passthrough_errors`.

    .. versionadded:: 0.6
       support for SSL was added.

    .. versionadded:: 0.8
       Added support for automatically loading a SSL context from certificate
       file and private key.

    .. versionadded:: 0.9
       Added command-line interface.

    .. versionadded:: 0.10
       Improved the reloader and added support for changing the backend
       through the `reloader_type` parameter.  See :ref:`reloader`
       for more information.

    :param hostname: The host for the application.  eg: ``'localhost'``
    :param port: The port for the server.  eg: ``8080``
    :param application: the WSGI application to execute
    :param use_reloader: should the server automatically restart the python
                         process if modules were changed?
    :param use_debugger: should the werkzeug debugging system be used?
    :param use_evalex: should the exception evaluation feature be enabled?
    :param extra_files: a list of files the reloader should watch
                        additionally to the modules.  For example configuration
                        files.
    :param reloader_interval: the interval for the reloader in seconds.
    :param reloader_type: the type of reloader to use.  The default is
                          auto detection.  Valid values are ``'stat'`` and
                          ``'watchdog'``. See :ref:`reloader` for more
                          information.
    :param threaded: should the process handle each request in a separate
                     thread?
    :param processes: if greater than 1 then handle each request in a new process
                      up to this maximum number of concurrent processes.
    :param request_handler: optional parameter that can be used to replace
                            the default one.  You can use this to replace it
                            with a different
                            :class:`~BaseHTTPServer.BaseHTTPRequestHandler`
                            subclass.
    :param static_files: a list or dict of paths for static files.  This works
                         exactly like :class:`SharedDataMiddleware`, it's actually
                         just wrapping the application in that middleware before
                         serving.
    :param passthrough_errors: set this to `True` to disable the error catching.
                               This means that the server will die on errors but
                               it can be useful to hook debuggers in (pdb etc.)
    :param ssl_context: an SSL context for the connection. Either an
                        :class:`ssl.SSLContext`, a tuple in the form
                        ``(cert_file, pkey_file)``, the string ``'adhoc'`` if
                        the server should automatically create one, or ``None``
                        to disable SSL (which is the default).
    zport must be an integerr   )DebuggedApplication)SharedDataMiddlewarec                sR    dkr pd}d|kr d| }d}|   d }tddd krBd	pDd
||| d S )N)rD   r   Z	localhostr   z[%s]z(Press CTRL+C to quit)rC   r   z * Running on %s://%s:%d/ %srA   rB   )r   r   )r   Zdisplay_hostnameZquit_msgr   )hostnamerJ   r   r	   log_startup  s    zrun_simple.<locals>.log_startupc                 sh   yt tjd } W n ttfk
r.   d } Y nX t | d	}| d kr\|j |  d S )NWERKZEUG_SERVER_FD)r   )r+   r   rZ   LookupErrorr-   r   r|   r   )r   Zsrv)	applicationr   r   r   r   r   r   rJ   r   r   r	   inner  s    


zrun_simple.<locals>.innerr   r   zsCannot bind to a random port with enabled reloader if the Python interpreter does not support socket opening by fd.rC   set_inheritableTr   )run_with_reloaderN)rh   r+   r   Zwerkzeug.debugr   Zwerkzeug.wsgir   r   rZ   rX   can_open_by_fdr-   r   r|   r   Z
setsockoptZ
SOL_SOCKETZSO_REUSEADDRZbindr   rw   r   rR   filenoZlistenr   r`   werkzeug._reloaderr   )r   r   r   use_reloaderuse_debuggerZ
use_evalexZextra_filesZreloader_intervalZreloader_typer   r   r   Zstatic_filesr   rJ   r   r   r   r   sr   r   )	r   r   r   r   r   r   r   rJ   r   r	   
run_simple  s:    E








r   c              O   s   ddl m} || |S )Nr   )r   )r   r   )r   r   r   r   r   r	   r   1  s    r   c        	      C   s   ddl } ddlm} | jdd}|jdddd	d
 |jddddddd |jddddddd | \}}d\}}|jr|jd}|d }t|dkr|d }t|dkrt	j
d t	d ||d }t|pdt|pd||j|jd dS )z:A simple command-line interface for :py:func:`run_simple`.r   N)import_stringz,Usage: %prog [options] app_module:app_object)Zusagez-bz--bindaddressz+The hostname:port the app should listen on.)desthelpz-dz--debugr   
store_trueFzUse Werkzeug's debugger.)r   actiondefaultr  z-rz--reloadr   z(Reload Python process if modules change.)NNr   rC   z1No application supplied, or too much. See --help
z	127.0.0.1i  )r   r   r   r   r   )optparseZwerkzeug.utilsr   ZOptionParserZ
add_option
parse_argsr   rb   r3   rK   stdoutrk   exitr   r+   r   r   )	r  r   parserZoptionsr   r   r   r   rx   r   r   r	   main8  s6    



r
  __main__)N)NN)NN)N)	NNNFrC   NFNN)FFTNrC   r   FrC   NNFN)<r9   Z
__future__r   ior   r|   rK   r   rw   r   r   r   r   objectr   r   ZSocketServerZsocketserverZBaseHTTPServerr   r   Zhttp.serverZThreadingMixInr   r;   Zwerkzeug._internalr   Zwerkzeug._compatr   r   r   r   Zwerkzeug.urlsr   r   Zwerkzeug.exceptionsr   r   r   	RawIOBaser    r:   ZBaseRequestHandlerr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r
  r   r   r   r   r	   <module>%   s   


5 k

"

F  
	     
 %
