3
¥Yði�•  ã            .   @   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 �o¨e!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-8om4l6ph/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rÒt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�rœd|d< t|d ƒ|d< |j�r¶|j�r¶|j|d< y*ˆ jj dd�}|d k	�rÞt!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|ƒ q†W d|kpÒˆ d dkpÒ|dk pÒ|dksæd
ˆ_	ˆ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r„t|dƒ}nR|d dkrœt|d	ƒ}n:|d
kr°t|dƒ}n&|d dkrÊt|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r‚d} |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 )zˆGet 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ƒrêt|Ž }|dkrøtƒ }|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r¤t	 r¤t
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r‚d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 )zŸRun 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	|p dt
|p¨dƒ||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 :/
