3
e              .   @   sZ  d Z ddlZddlZddlZddlZddl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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 yddlZW n* ek
r   G dd dZe ZY nX dZejdkr@ye d W n ek
r>   dZY nX e!edZ"e"rXej#Z#nG dd dZ#y
ej$Z%W n e&k
r   dZ%Y nX dZ'ej( dk oe!edZ)e	j*e	j+de	j,e-e	j*e- f df  Z.e	j/rddl0Z1ddl2m3Z3 ddl2m4Z4 ddl5m6Z6 dd l7m8Z8 G d!d" d"ej9Z:G d#d$ d$eZ;e-e-e-d%d&d'Z<dXe	j*e- e	j,dY d*d+d,Z=dZe-e	j*e- e	j*e- e	j,e-e-f d-d.d/Z>dd0d1d2Z?d[e-e	j*e- e	j*e@ dd3d4d5ZAd\e	j*eB eCd6d7d8ZDe-e@ejEd9d:d;ZFe-e@ejEe	j+e	j,e-e@f e-f d<d=d>ZGejEe-d?d@dAZHG dBdC dCeZIG dDdE dEejJeIZKG dFdG dGe#eIZLd]e-e@dHeCe@e	j*e	jMe;  eCe	j*e. e	j*e@ eIdI
dJdKZNeCd0dLdMZOd^e-e@dHeCeCeCe	j*e	jPe-  e	j*e	jPe-  e@e-eCe@e	j*e	jMe;  e	j*e	jQe-e	j+e-e	j,e-e-f f f  eCe	j*e. ddOdPdQZRe	jSe	jSddRdSdTZTdd0dUdVZUeVdWkrVeU  dS )_a  A WSGI and HTTP server for use **during development only**. This
server is convenient to use, but is not designed to be particularly
stable, secure, or efficient. Use a dedicate WSGI server and HTTP
server when deploying to production.

It provides features like interactive debugging and code reloading. Use
``run_simple`` to start the server. Put this in a ``run.py`` script:

.. code-block:: python

    from myapp import create_app
    from werkzeug import run_simple
    N)datetime)	timedelta)timezone)BaseHTTPRequestHandler)
HTTPServer   )_log)_wsgi_encoding_dance)InternalServerError)
uri_to_iri)	url_parse)url_unquotec               @   s   e Zd ZeejdddZdS )	_SslDummy)namereturnc             C   s   t dd S )NzUSSL is unavailable because this Python runtime was not compiled with SSL/TLS support.)RuntimeError)selfr    r   4/tmp/pip-build-3irwxpxt/Werkzeug/werkzeug/serving.py__getattr__)   s    z_SslDummy.__getattr__N)__name__
__module____qualname__strtAnyr   r   r   r   r   r   (   s   r   TntcoloramaFforkc               @   s   e Zd ZdS )ForkingMixInN)r   r   r   r   r   r   r   r   ?   s   r      Windowsfromfdzssl.SSLContextzte.Literal['adhoc'])WSGIApplication)WSGIEnvironment)RSAPrivateKeyWithSerialization)Certificatec               @   sR   e Zd ZdZeje ddddZedddZ	e
dd	d
Zee
dddZdS )DechunkedInputz8An input stream that handles Transfer-Encoding 'chunked'N)rfiler   c             C   s   || _ d| _d| _d S )NFr   )_rfile_done_len)r   r(   r   r   r   __init__\   s    zDechunkedInput.__init__)r   c             C   s   dS )NTr   )r   r   r   r   readablea   s    zDechunkedInput.readablec             C   sd   y"| j j jd}t|j d}W n, tk
rN } ztd|W Y d d }~X nX |dk r`td|S )Nlatin1   zInvalid chunk headerr   z!Negative chunk length not allowed)r)   readlinedecodeintstrip
ValueErrorOSError)r   liner+   er   r   r   read_chunk_lend   s    zDechunkedInput.read_chunk_len)bufr   c             C   s   d}x| j  r|t|k r| jdkr.| j | _| jdkr>d| _ | jdkrtt|| j}|| t|kr| jjt|| ||d < |  jt|| 8  _t|}n.| jj||||| < |  j|8  _||7 }| jdkr| jj }|dkrtdqW |S )Nr   T   
   
   z!Missing chunk terminating newline)r:   r;   r<   )	r*   lenr+   r8   minr)   readr0   r5   )r   r9   r?   n
terminatorr   r   r   readinton   s(    






zDechunkedInput.readinto)r   r   r   __doc__r   ZIObytesr,   boolr-   r2   r8   	bytearrayrB   r   r   r   r   r'   Y   s
   
r'   c                   s:  e Zd ZU dZdeedddZddddZd	dd
dZ	d	dddZ
d	dddZd*eejd d	dddZd	dddZd+eeje d	dddZed fddZedddZedddZd,ejeef ejeef d	dd d!Zeejd	d"d#d$Zeejd	d"d%d&Zeeejd	d'd(d)Z  ZS )-WSGIRequestHandlerz3A request handler that implements WSGI dispatching.BaseWSGIServer)r   c             C   s   ddl m} d| S )Nr   )__version__z	Werkzeug/) rI   )r   rI   r   r   r   server_version   s    z!WSGIRequestHandler.server_versionr$   c       	         s  t  j}d d fdd} jjd kr,dnd} js>d _nt jtrV jdf _|j rx|jrxd|j |j }n|j}t	|}d| j
tj jj jjd
| j j jdt|t|jt jt j j  j  jjd t jjd	  jd}xl jj D ]^\}}|j jdd}|jdd}|d kr\d| }||kr\||  d| }|||< qW |jddj j dkrd|d< t|d |d< |jr|jr|j|d< y* jj dd}|d k	rt!j"||d< W n8 t#k
r    jj$dd Y n t%k
r   Y nX |S )!N)r   c                  s   t jddd d j_d S )NzeThe 'environ['werkzeug.server.shutdown']' function is deprecated and will be removed in Werkzeug 2.1.   )
stacklevelT)warningswarnservershutdown_signalr   )r   r   r   shutdown_server   s    z8WSGIRequestHandler.make_environ.<locals>.shutdown_serverhttphttps<local>r   /r   FrJ   )zwsgi.versionzwsgi.url_schemez
wsgi.inputzwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_oncezwerkzeug.server.shutdownzwerkzeug.socketZSERVER_SOFTWAREREQUEST_METHODZSCRIPT_NAMEZ	PATH_INFOQUERY_STRINGZREQUEST_URIZRAW_URIREMOTE_ADDRZREMOTE_PORTZSERVER_NAMEZSERVER_PORTZSERVER_PROTOCOL-_z
CONTENT_TYPECONTENT_LENGTHZHTTP_,ZHTTP_TRANSFER_ENCODINGchunkedTzwsgi.input_terminatedz
wsgi.inputZ	HTTP_HOST)binary_formZSSL_CLIENT_CERTerrorz&Cannot fetch SSL peer certificate info)rU   r   )r   r   )r\   r]   )&r   pathrP   ssl_contextclient_address
isinstancer   schemenetlocr   r(   sysstderrmultithreadmultiprocess
connectionrK   commandr	   queryaddress_stringport_integerserver_addressrequest_versionheadersitemsupperreplacegetr3   lowerr'   getpeercertsslDER_cert_to_PEM_certr4   logAttributeError)	r   request_urlrR   Z
url_schemeZ	path_infoenvironkeyvalueZ	peer_certr   )r   r   make_environ   sn    







zWSGIRequestHandler.make_environNc                sX  j jddj j dkr&jjd j  _ d d d d td d fdddfdd		d
d d fdd}y|j	j
 W n ttjfk
r } zj|  W Y d d }~X n tk
rR   j	jr ddlm} |dd}y d krd d |t  W n tk
r:   Y nX j	jdd|j Y nX d S )NZExpectrJ   z100-continues   HTTP/1.1 100 Continue

)datar   c                sP  d k	st dd k	s t dd kr"yjd d\}}W n tk
rd   d }}Y nX t|}j|| t }x.D ]&\}}j|| |j }|j| qW d|kp҈ d dkp|dk p|dksd
_	jdd d|kr jdj
  d|krjdj  j  t| ts6t djj|  jj  d S )Nzwrite() before start_responser   rJ   zcontent-lengthrW   HEAD      0  T
ConnectioncloserP   ServerdateDatezapplications must write bytes)r   r   )AssertionErrorsplitr4   r2   send_responsesetZsend_headerrx   addclose_connectionversion_stringZdate_time_stringZend_headersre   rD   wfilewriteflush)r   Zcode_strmsgcodeZheader_keysr   r   )r   headers_sentheaders_setr   status_sent
status_setr   r   r     s<    


z*WSGIRequestHandler.run_wsgi.<locals>.writec          
      s@   |r(z r|d j |d W d d }X nr4td| |S )Nr   rL   zHeaders already set)with_tracebackr   )statusrs   exc_info)r   r   r   r   r   r   start_response*  s    z3WSGIRequestHandler.run_wsgi.<locals>.start_responser#   )appr   c                sJ   |  }z&x|D ]}| qW s.d W d t |drD|j  X d S )N    r   )hasattrr   )r   Zapplication_iterr   )r   r   r   r   r   r   execute8  s    


z,WSGIRequestHandler.run_wsgi.<locals>.executer   )get_current_tracebackT)Zignore_system_exceptionsra   zError on request:
%s)N)rs   rw   rx   r3   r   r   r   r   rD   rP   r   ConnectionErrorsockettimeoutconnection_dropped	Exceptionpassthrough_errorsZdebug.tbtoolsr   r
   r|   	plaintext)r   r   r7   r   	tracebackr   )r   r   r   r   r   r   r   r   r   run_wsgi   s6    $

zWSGIRequestHandler.run_wsgic             C   s   yt j|  W nv ttjfk
r@ } z| j| W Y dd}~X nF tk
r } z*| jjdk	rrt	|rr| j
d| n W Y dd}~X nX | jjr| j  dS )z/Handles a request ignoring dropped connections.NzSSL error occurred: %s)r   handler   r   r   r   r   rP   rc   is_ssl_error	log_errorrQ   initiate_shutdown)r   r7   r   r   r   r   X  s    zWSGIRequestHandler.handlec             C   s0   t  r$ttdtj}tjtj | d| j_d S )NSIGKILLT)	is_running_from_reloadergetattrsignalSIGTERMoskillgetpidrP   _BaseServer__shutdown_request)r   sigr   r   r   r   f  s    z$WSGIRequestHandler.initiate_shutdown)ra   r   r   c             C   s   dS )z`Called if the connection was closed by the client.  By default
        nothing happens.
        Nr   )r   ra   r   r   r   r   r   n  s    z%WSGIRequestHandler.connection_droppedc             C   s.   | j j | _| jsd| _n| j r*| j  dS )zHandle a single HTTP request.TN)r(   r0   Zraw_requestliner   Zparse_requestr   )r   r   r   r   handle_one_requestu  s
    z%WSGIRequestHandler.handle_one_request)r   messager   c             C   sf   | j | |dkr.|| jkr*| j| d nd}| jdkrb| j d| d| d}| jj|jd dS )z3Send the response header and log the response code.Nr   rJ   zHTTP/0.9 z
ascii)log_request	responsesrr   Zprotocol_versionr   r   encode)r   r   r   hdrr   r   r   r   }  s    

z WSGIRequestHandler.send_responsec                s   t  j j S )N)superr   r3   )r   )	__class__r   r   r     s    z!WSGIRequestHandler.version_stringc             C   s*   t | dd r| jd S | js dS | jd S )Nr   rY   z<local>r   )r   r   rd   )r   r   r   r   ro     s
    
z!WSGIRequestHandler.address_stringc             C   s
   | j d S )Nr   )rd   )r   r   r   r   rp     s    zWSGIRequestHandler.port_integerrZ   )r   sizer   c             C   s   y&t | j}| j d| d| j }W n tk
r@   | j}Y nX t|}tr|d dkrft|d}np|dkrpnf|dkrt|d}nR|d dkrt|d	}n:|d
krt|d}n&|d dkrt|dd}nt|dd}| j	dd||| d S )Nr   r   1boldZ200Z304cyan3greenZ404yellow4redmagentainfoz
"%s" %s %s)
r   rb   rm   rr   r}   Zrequestliner   _log_add_style_ansi_styler|   )r   r   r   rb   r   r   r   r   r     s*    
zWSGIRequestHandler.log_request)formatargsr   c             G   s   | j d|f|  d S )Nra   )r|   )r   r   r   r   r   r   r     s    zWSGIRequestHandler.log_errorc             G   s   | j d|f|  d S )Nr   )r|   )r   r   r   r   r   r   log_message  s    zWSGIRequestHandler.log_message)typer   r   r   c             G   s.   t || j  d| j  d| df|  d S )Nz - - [z] 
)r   ro   Zlog_date_time_string)r   r   r   r   r   r   r   r|     s    zWSGIRequestHandler.log)N)N)rZ   rZ   )r   r   r   rC   rP   propertyr   rK   r   r   r   r   BaseExceptionr   Optionalr   r   r2   r   r   ro   rp   Unionr   r   r   r   r|   __classcell__r   r   )r   r   rG      s(   
Z\			rG   )r   stylesr   c             G   s>   ddddddd}x |D ]}d||  d	|  } qW |  d
S )Nr          !   #   $   )r   r   r   r   r   r   z[mz[0mr   )r   r   codesstyler   r   r   r     s    
r   r&   r%   )cnr   c       
      C   s:  y@ddl m} ddlm} ddlm} ddlm} ddlm	} W n t
k
r^   tdd Y nX | }|jdd	|d
}| d krd} |j|j|jd|j|j| g}| }|j j|j|j|j j|j jtjtjjtjtjtdd j|j|j gddj|j!|j"| gddj#||j$ |}	|	|fS )Nr   )x509)NameOID)default_backend)hashes)rsaz<Using ad-hoc certificates requires the cryptography library.i  i   )Zpublic_exponentZkey_sizebackend*zDummy Certificateim  )daysF)critical)%Zcryptographyr   Zcryptography.x509.oidr   Zcryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   Z)cryptography.hazmat.primitives.asymmetricr   ImportError	TypeErrorZgenerate_private_keyNameZNameAttributeZORGANIZATION_NAMEZCOMMON_NAMEZCertificateBuilderZsubject_nameZissuer_nameZ
public_keyZserial_numberZrandom_serial_numberZnot_valid_beforedtnowr   utcZnot_valid_afterr   add_extensionZExtendedKeyUsageZOID_SERVER_AUTHZSubjectAlternativeNameZDNSNamesignSHA256)
r   r   r   r   r   r   r   pkeysubjectcertr   r   r   generate_adhoc_ssl_pair  s<    


r   )	base_pathhostr   r   c       	      C   s   |dk	rd| d| }t |d\}}ddlm} |  d}|  d}t|d	}|j|j|jj W dQ R X t|d	(}|j|j|jj|j	j
|j d
 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.
    Nz*.z/CN=)r   r   )serializationz.crtz.keywb)encodingr   encryption_algorithm)r   r   r  openr   public_bytesEncodingPEMprivate_bytesPrivateFormatTraditionalOpenSSLNoEncryption)	r   r   r   r   r   r  	cert_file	pkey_filefr   r   r   make_ssl_devcert  s    

r  )r   c        
      C   s   ddl } ddl}t \}}ddlm} | j \}}| j \}}|jtj| |jtj| tj	||j
|jj tj	||j|jj|jj|j d tj| tj| t||}	|	S )z:Generates an adhoc SSL context for the development server.r   N)r  )r  r   r  )tempfileatexitr   r   r  mkstempregisterr   remover   r  r  r  r	  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  )r  r  protocolr   c             C   s(   |dkrt j}t j|}|j| | |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: A ``PROTOCOL`` constant from the :mod:`ssl` module.
        Defaults to :data:`ssl.PROTOCOL_TLS_SERVER`.
    N)rz   PROTOCOL_TLS_SERVER
SSLContextload_cert_chain)r  r  r  r  r   r   r   r  I  s
    
r  )ra   r   c             C   s(   | dkrt jttj d } t| tjS )z?Checks if the given error (or the current one) is an SSL error.Nr   )r   castr   rh   r   re   rz   SSLError)ra   r   r   r   r   ^  s    r   )r   portr   c             C   s.   | j drtjS d| kr(ttdr(tjS tjS )zUReturn ``AF_INET4``, ``AF_INET6``, or ``AF_UNIX`` depending on
    the host and port.zunix://:AF_INET6)
startswithr   AF_UNIXr   r!  AF_INET)r   r  r   r   r   select_address_familye  s
    
r%  )r   r  familyr   c             C   sZ   |t kr| jddd S ytj| ||tjtj}W n tjk
rL   | |fS X |d d S )zVReturn a fully qualified socket address that can be passed to
    :func:`socket.bind`.z://r   r      )af_unixr   r   getaddrinfoSOCK_STREAMIPPROTO_TCPgaierror)r   r  r&  resr   r   r   get_sockaddro  s    
r.  )r&  r   c             C   sn   | t jkrdnd}t j | t jD}y|j|df W n" tk
rV   | t jkrRdS dS X |j d S Q R X dS )zGet the IP address of an external interface. Used when binding to
    0.0.0.0 or ::1 to show a more useful URL.

    :meta private:
    zfd31:f903:5ab5:1::1z10.253.155.219i2  z::1z	127.0.0.1r   N)r   r!  
SOCK_DGRAMconnectr5   getsockname)r&  r   sr   r   r   get_interface_ip  s    r3  c            
       s   e Zd ZdZdZdZeZdee	de
je
je  ee
je e
je	 dd fddZeee
jddd	d
Zdedd fddZe
je
je
jee	f ef dd fddZ  ZS )rH   z3Simple single-threaded, single-process WSGI server.FNr#   )r   r  r   handlerr   rc   fdr   c       
         s  |d krt }t||| _|d k	r6tj|| jtj}d}t|t|| j}	| jtkrtt	j
t|	}	tjj|	rttj|	 t j|	| || _|| _d| _|| _| jj d | _|d k	r| jj  || _| jj | _|d k	rt|trt| }|dkrt }|j| jdd| _|| _nd | _d S )Nr   Fr   ZadhocT)server_side) rG   r%  address_familyr   r"   r*  r.  r2   r(  r   r  r   r   rb   existsunlinkr   r,   r   r   rQ   r   r1  r  r   rq   re   tupler  r  wrap_socketrc   )
r   r   r  r   r4  r   rc   r5  Z	real_sockrq   )r   r   r   r,     s:    





zBaseWSGIServer.__init__)r   r   r   r   c             G   s   t ||f|  d S )N)r   )r   r   r   r   r   r   r   r|     s    zBaseWSGIServer.log      ?)poll_intervalr   c                sB   d| _ z,yt j|d W n tk
r.   Y nX W d | j  X d S )NF)r=  )rQ   r   serve_foreverKeyboardInterruptserver_close)r   r=  )r   r   r   r>    s    
zBaseWSGIServer.serve_forever)requestrd   r   c                s   | j r t j||S )N)r   r   handle_error)r   rA  rd   )r   r   r   rB    s    zBaseWSGIServer.handle_error)NFNN)r<  )r   r   r   rC   rj   rk   LISTEN_QUEUErequest_queue_sizer   r2   r   r   TyperG   rE   _TSSLContextArgr,   r   r|   floatr>  r   TuplerB  r   r   r   )r   r   rH     s      (,
rH   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   rC   rj   daemon_threadsr   r   r   r   rI    s   rI  c               @   sL   e Zd ZdZdZd
eedeejej	e
  eeje eje dd	dd	ZdS )ForkingWSGIServerz A WSGI server that does forking.T(   NFr#   )	r   r  r   	processesr4  r   rc   r5  r   c	       	   	   C   s.   t stdtj| ||||||| || _d S )Nz'Your platform does not support forking.)can_forkr4   rH   r,   max_children)	r   r   r  r   rM  r4  r   rc   r5  r   r   r   r,     s
    zForkingWSGIServer.__init__)rL  NFNN)r   r   r   rC   rk   r   r2   r   r   rE  rG   rE   rF  r,   r   r   r   r   rK    s       *rK  r#   )
r   r  r   threadedrM  request_handlerr   rc   r5  r   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.
    r   z5cannot have a multithreaded and multi process server.)r5  N)r4   rI  rK  rH   )	r   r  r   rP  rM  rQ  r   rc   r5  r   r   r   make_server  s"    
rR  c               C   s   t jjddkS )zwChecks if the application is running from within the Werkzeug
    reloader subprocess.

    .. versionadded:: 0.10
    ZWERKZEUG_RUN_MAINtrue)r   r   rw   r   r   r   r   r   )  s    r   auto)hostnamer  applicationuse_reloaderuse_debugger
use_evalexextra_filesexclude_patternsreloader_intervalreloader_typerP  rM  rQ  static_filesr   rc   r   c          
      sx  t tstd|r,ddlm} | | |rFddlm} | | tjddfdddd	 f	d
d}|rnt sNdkrt	 rt
dt}t|}tj|tj}|jtjtjd |j| |jd t	rt|j tjd< |jt | n4|j  |tkrNtjt|}tdd| tj| ddlm } ||||||	d 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

    .. versionchanged:: 2.0
        Added ``exclude_patterns`` parameter.

    .. 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.

    .. versionchanged:: 0.15
        Bind to a Unix socket by passing a path that starts with
        ``unix://`` as the ``hostname``.

    :param hostname: The host to bind to, for example ``'localhost'``.
        If the value is a path that starts with ``unix://`` it will bind
        to a Unix socket instead of a TCP socket..
    :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 exclude_patterns: List of :mod:`fnmatch` patterns to ignore
        when running the reloader. For example, ignore cache files that
        shouldn't reload when updated.
    :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)SharedDataMiddlewareN)sockr   c                s   d}| j tkrtdd  nx dkr:td| ttj}n" dkrXtd| ttj}n }d|krpd| d	}tdd
d krdnd|| j d  d S )Nzp * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.r   z' * Running on %s (Press CTRL+C to quit)z0.0.0.0warningz::r   []z0 * Running on %s://%s:%d/ (Press CTRL+C to quit)rS   rT   r   )r&  r(  r   r3  r   r$  r!  r1  )ra  Zall_addresses_messageZdisplay_hostname)rU  rc   r   r   log_startup  s$    


zrun_simple.<locals>.log_startup)r   c                 sh   yt tjd } W n ttfk
r.   d } Y nX t | d	}| d kr\|j |j  d S )NWERKZEUG_SERVER_FD)r5  )r2   r   r   LookupErrorr4   rR  r   r>  )r5  Zsrv)	rV  rU  re  r   r  rM  rQ  rc   rP  r   r   inner  s"    

zrun_simple.<locals>.innerr   zsCannot bind to a random port with enabled reloader if the Python interpreter does not support socket opening by fd.Trf  r   zUnlinking %s)run_with_reloader)rZ  r[  intervalr]  )!re   r2   r   debugr_  Zmiddleware.shared_datar`  r   r   can_open_by_fdr4   r%  r.  r*  
setsockopt
SOL_SOCKETSO_REUSEADDRbindset_inheritabler   filenor   r   listenrC  r   r(  r   r  r   r9  	_reloaderri  )rU  r  rV  rW  rX  rY  rZ  r[  r\  r]  rP  rM  rQ  r^  r   rc   r_  r`  rh  r7  rq   r2  _rwrr   )	rV  rU  re  r   r  rM  rQ  rc   rP  r   
run_simple2  sL    ]


"







rv  )r   kwargsr   c              O   s*   ddl m} tjdtdd || | dS )zRun a process with the reloader. This is not a public API, do
    not use this function.

    .. deprecated:: 2.0
        Will be removed in Werkzeug 2.1.
    r   )ri  zp'run_with_reloader' is a private API, it will no longer be accessible in Werkzeug 2.1. Use 'run_simple' instead.rL   )rM   N)rt  ri  rN   rO   DeprecationWarning)r   rw  ru  r   r   r   ri    s    ri  c              C   s   ddl } ddlm} tdd | jddd	}|jd
dddd |jddddd |jddddd |jddd |j }d\}}|jr|jjd\}}}t	|pdt
|pd||j|j|jd dS )z:A simple command-line interface for :py:func:`run_simple`.r   Nr   )import_stringrb  z:This CLI is deprecated and will be removed in version 2.1.z;Run the given WSGI application with the development server.F)descriptionallow_abbrevz-bz--bindaddressz+The hostname:port the app should listen on.)desthelpz-dz--debug
store_truez7Show the interactive debugger for unhandled exceptions.)actionr~  z-rz--reloadz%Reload the process if modules change.rV  z8Application to import and serve, in the form module:app.)r~  r   z	127.0.0.1i  )rU  r  rV  rW  rX  )NN)argparseutilsry  r   ArgumentParseradd_argument
parse_argsr|  	partitionrv  r2   rV  reloadrk  )r  ry  parserr   rU  r  r[   r   r   r   main  sB    


r  __main__)N)r&   r%   )NN)NN)N)Fr   NFNN)FFTNNr   rT  Fr   NNFN)WrC   ior   platformr   r   socketserverrh   typingr   rN   r   r   r   r   Zhttp.serverr   r   Z	_internalr   r	   
exceptionsr
   urlsr   r   r   rz   r   r   r   r   
__import__r   rN  r   r#  r(  r}   rC  systemrl  r   r   rH  r   rF  ZTYPE_CHECKINGZtyping_extensionsteZ_typeshed.wsgir#   r$   Z-cryptography.hazmat.primitives.asymmetric.rsar%   Zcryptography.x509r&   	RawIOBaser'   rG   r   r   r  r  r2   r  r   rE   r   AddressFamilyr%  r.  r3  rH   ThreadingMixInrI  rK  rE  rR  r   IterableDictrv  r   ri  r  r   r   r   r   r   <module>   s   



">  ,
-*"R     ,            p :/
