U
    
W[v&                     @   s   d Z ddlmZmZ ddlZddlZddlZddlmZm	Z	 ddl
mZmZ ddlmZmZmZmZ ddlmZ ddlmZ dd	lmZmZmZmZmZmZ dd
lmZ G dd dejZdd ZG dd dejZ dd Z!dS )z9
Support for creating a service which runs a web server.
    )absolute_importdivisionN)servicestrports)
interfacesreactor)usagereflect
threadpool	deprecate)pb)distrib)resourceserverstaticscriptdemowsgi)twcgic                   @   s  e Zd ZdZdZddddgddd	d
gddd	dggZdddggZedddej	j
f d g ejedededddZdZdd Zdd ZeZdd Zd d! Zd"d# ZeZd$d% ZeZd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 ZeZd2d3 Z d4d5 Z!d6d7 Z"d8d9 Z#dS ):OptionszB
    Define the options accepted by the I{twistd web} plugin.
    z[web options]logfilelNz/Path to web CLF (Combined Log Format) log file.certificatecz
server.pemz=(DEPRECATED: use --listen) SSL certificate to use for HTTPS. privkeykz<(DEPRECATED: use --listen) SSL certificate to use for HTTPS.notracebacksnzcDo not display tracebacks in broken web pages. Displaying tracebacks to users may be security risk!personal zvInstead of generating a webserver, generate a ResourcePublisher which listens on  the port given by --listen, or ~/%s zif --listen is not specified.z*.logz*.pem)r   r   r   )Z
optActionszThis starts a webserver.  If you specify no arguments, it will be a
demo webserver that has the Test class from twisted.web.demo in it.c                 C   s@   t j|  g | d< d | d< g | d< g | d< d  | d< | d< d S )NindexesrootextraHeadersportsporthttps)r   r   __init__self r)   1/usr/lib/python3/dist-packages/twisted/web/tap.pyr&   ?   s    zOptions.__init__c              	   C   s6   t | jtdddd}tj|tdd || d< dS )	zh
        (DEPRECATED: use --listen)
        Strports description of port to start the server on
        Twisted      r      category
stacklevelr$   N)r   getDeprecationWarningStringopt_portincrementalVersionwarningswarnDeprecationWarningr(   r$   msgr)   r)   r*   r3   H   s     zOptions.opt_portc              	   C   s6   t | jtdddd}tj|tdd || d< dS )	zW
        (DEPRECATED: use --listen)
        Port to listen on for Secure HTTP.
        r+   r,   r-   r   r.   r/   r%   N)r   r2   	opt_httpsr4   r5   r6   r7   r8   r9   r)   r)   r*   r;   T   s     zOptions.opt_httpsc                 C   s   | d  | dS )zi
        Add an strports description of port to start the server on.
        [default: tcp:8080]
        r#   Nappend)r(   r$   r)   r)   r*   
opt_listen_   s    zOptions.opt_listenc                 C   s   | d  | dS )zr
        Add the name of a file used to check for directory indexes.
        [default: index, index.html]
        r    Nr<   )r(   Z	indexNamer)   r)   r*   	opt_indexg   s    zOptions.opt_indexc                 C   s   t  | d< dS )zc
        Makes a server with ~/public_html and ~/.twistd-web-pb support for
        users.
        r!   N)r   UserDirectoryr'   r)   r)   r*   opt_userq   s    zOptions.opt_userc                 C   s>   t tj|| d< tjtjd| d _t	j
| d jd< dS )z
        <path> is either a specific file or a directory to be set as the root
        of the web server. Use this if you have a directory full of HTML, cgi,
        epy, or rpy files or any other files that you want to be served up raw.
        r!   )z.epyz.rpyz.cgiN)r   Fileospathabspathr   ZPythonScriptZResourceScript
processorsr   Z	CGIScript)r(   rD   r)   r)   r*   opt_path{   s
    zOptions.opt_pathc                 C   sB   t | d tjstd|dd\}}t|| d j|< dS )zh
        `ext=class' where `class' is added as a Processor for files ending
        with `ext'.
        r!   z*You can only use --processor after --path.=   N)	
isinstancer   rB   r   
UsageErrorsplitr	   
namedClassrF   )r(   procextklassr)   r)   r*   opt_processor   s    zOptions.opt_processorc                 C   s   t |}| | d< dS )zN
        Create a Resource subclass with a zero-argument constructor.
        r!   N)r	   rM   )r(   Z	classNameZclassObjr)   r)   r*   	opt_class   s    
zOptions.opt_classc                 C   s   t || d< dS )zP
        An .rpy file to be used as the root resource of the webserver.
        r!   N)r   ZResourceScriptWrapper)r(   namer)   r)   r*   opt_resource_script   s    zOptions.opt_resource_scriptc              	   C   sr   zt |}W n( ttfk
r6   td|f Y nX t }t	|j
 tdd|j tt||| d< dS )zo
        The FQPN of a WSGI application object to serve as the root resource of
        the webserver.
        zNo such WSGI application: %rZafterZshutdownr!   N)r	   ZnamedAnyAttributeError
ValueErrorr   rK   r
   Z
ThreadPoolr   ZcallWhenRunningstartZaddSystemEventTriggerstopr   ZWSGIResource)r(   rS   ZapplicationZpoolr)   r)   r*   opt_wsgi   s    zOptions.opt_wsgic                 C   s(   t | d tjstd|| d _dS )zA
        Specify the default mime-type for static files.
        r!   z*You can only use --mime_type after --path.N)rJ   r   rB   r   rK   defaultType)r(   rZ   r)   r)   r*   opt_mime_type   s
    zOptions.opt_mime_typec                 C   s,   t | d tjstd| d d dS )zT
        Specify whether or not a request for 'foo' should return 'foo.ext'
        r!   z1You can only use --allow_ignore_ext after --path.*NrJ   r   rB   r   rK   Z	ignoreExtr'   r)   r)   r*   opt_allow_ignore_ext   s    
zOptions.opt_allow_ignore_extc                 C   s,   t | d tjstd| d | dS )zT
        Specify an extension to ignore.  These will be processed in order.
        r!   z+You can only use --ignore_ext after --path.Nr]   )r(   rO   r)   r)   r*   opt_ignore_ext   s    
zOptions.opt_ignore_extc                 C   s.   | dd\}}| d | | f dS )z
        Specify an additional header to be included in all responses. Specified
        as "HeaderName: HeaderValue".
        :rI   r"   N)rL   r=   strip)r(   headerrS   valuer)   r)   r*   opt_add_header   s    zOptions.opt_add_headerc                 C   s   | d dk	r| d  | d  | d dk	rztd W n tk
rV   tdY nX d| d | d | d	 }| d  | t| d d
kr| d rtj	
tj	dtjj}| d  d|  n| d  d dS )a@  
        Set up conditional defaults and check for dependencies.

        If SSL is not available but an HTTPS server was configured, raise a
        L{UsageError} indicating that this is not possible.

        If no server port was supplied, select a default appropriate for the
        other options supplied.
        r$   Nr#   r%   zOpenSSL.SSLzSSL support not installedz$ssl:port={}:privateKey={}:certKey={}r   r   r   r   ~zunix:ztcp:8080)r=   r	   ZnamedModuleImportErrorr   rK   formatlenrC   rD   
expanduserjoinr   r@   userSocketName)r(   Z
sslStrportrD   r)   r)   r*   postOptions   s(    
zOptions.postOptions)$__name__
__module____qualname____doc__ZsynopsisZoptParametersZoptFlagsr=   r   r@   rk   r   ZCompletionsZCompleteFilesZcompDataZlongdescr&   r3   Zopt_pr;   r>   r?   Zopt_irA   Zopt_urG   rQ   rR   rT   rY   r[   Zopt_mr^   r_   rd   rl   r)   r)   r)   r*   r      sh    	


	r   c                 C   s   t t| S )z
    Create and return a factory which will respond to I{distrib} requests
    against the given site.

    @type site: L{twisted.web.server.Site}
    @rtype: L{twisted.internet.protocol.Factory}
    )r   ZPBServerFactoryr   ZResourcePublisher)siter)   r)   r*   makePersonalServerFactory   s    rr   c                   @   s   e Zd Zdd Zdd ZdS )_AddHeadersResourcec                 C   s   || _ || _d S N)_originalResource_headers)r(   ZoriginalResourceZheadersr)   r)   r*   r&   	  s    z_AddHeadersResource.__init__c                 C   s,   | j D ]\}}|j|| q| j||S rt   )rv   ZresponseHeadersZaddRawHeaderru   getChildWithDefault)r(   rS   Zrequestr   vr)   r)   r*   rw     s    z'_AddHeadersResource.getChildWithDefaultN)rm   rn   ro   r&   rw   r)   r)   r)   r*   rs     s   rs   c                 C   s   t  }| d r0| d }| d r8| d | d _nt }t|tjrT|j	t
j| | d rjt|| d }| d rtj|| d d}n
t|}| d  |_| d rt|}| d D ]}t ||}|| q|S )	Nr!   r    r"   r   )ZlogPathr   r   r#   )r   ZMultiServiceZ
indexNamesr   ZTestrJ   r   rB   registryZsetComponentr   ZIServiceCollectionrs   r   ZSiteZdisplayTracebacksrr   r   ZsetServiceParent)Zconfigsr!   rq   r$   Zsvcr)   r)   r*   makeService  s(    
r{   )"rp   Z
__future__r   r   rC   r6   r4   Ztwisted.applicationr   r   Ztwisted.internetr   r   Ztwisted.pythonr   r	   r
   r   Ztwisted.spreadr   Ztwisted.webr   r   r   r   r   r   r   r   r   rr   ZResourcers   r{   r)   r)   r)   r*   <module>   s      e