ó
Xé?_c           @   s¿   d  Z  d d l Z d d l Z d d l Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d	 e f d
 „  ƒ  YZ d „  Z	 d d „ Z
 d Z d Z d d „ Z d d „ Z d S(   s)  
Starting in CherryPy 3.1, cherrypy.server is implemented as an
:ref:`Engine Plugin<plugins>`. It's an instance of
:class:`cherrypy._cpserver.Server`, which is a subclass of
:class:`cherrypy.process.servers.ServerAdapter`. The ``ServerAdapter`` class
is designed to control other servers, as well.

Multiple servers/ports
======================

If you need to start more than one HTTP server (to serve on multiple ports, or
protocols, etc.), you can manually register each one and then start them all
with engine.start::

    s1 = ServerAdapter(cherrypy.engine, MyWSGIServer(host='0.0.0.0', port=80))
    s2 = ServerAdapter(cherrypy.engine,
                       another.HTTPServer(host='127.0.0.1',
                       SSL=True))
    s1.subscribe()
    s2.subscribe()
    cherrypy.engine.start()

.. index:: SCGI

FastCGI/SCGI
============

There are also Flup\ **F**\ CGIServer and Flup\ **S**\ CGIServer classes in
:mod:`cherrypy.process.servers`. To start an fcgi server, for example,
wrap an instance of it in a ServerAdapter::

    addr = ('0.0.0.0', 4000)
    f = servers.FlupFCGIServer(application=cherrypy.tree, bindAddress=addr)
    s = servers.ServerAdapter(cherrypy.engine, httpserver=f, bind_addr=addr)
    s.subscribe()

The :doc:`cherryd</deployguide/cherryd>` startup script will do the above for
you via its `-f` flag.
Note that you need to download and install `flup <http://trac.saddi.com/flup>`_
yourself, whether you use ``cherryd`` or not.

.. _fastcgi:
.. index:: FastCGI

FastCGI
-------

A very simple setup lets your cherry run with FastCGI.
You just need the flup library,
plus a running Apache server (with ``mod_fastcgi``) or lighttpd server.

CherryPy code
^^^^^^^^^^^^^

hello.py::

    #!/usr/bin/python
    import cherrypy

    class HelloWorld:
        """Sample request handler class."""
        def index(self):
            return "Hello world!"
        index.exposed = True

    cherrypy.tree.mount(HelloWorld())
    # CherryPy autoreload must be disabled for the flup server to work
    cherrypy.config.update({'engine.autoreload.on':False})

Then run :doc:`/deployguide/cherryd` with the '-f' arg::

    cherryd -c <myconfig> -d -f -i hello.py

Apache
^^^^^^

At the top level in httpd.conf::

    FastCgiIpcDir /tmp
    FastCgiServer /path/to/cherry.fcgi -idle-timeout 120 -processes 4

And inside the relevant VirtualHost section::

    # FastCGI config
    AddHandler fastcgi-script .fcgi
    ScriptAliasMatch (.*$) /path/to/cherry.fcgi$1

Lighttpd
^^^^^^^^

For `Lighttpd <http://www.lighttpd.net/>`_ you can follow these
instructions. Within ``lighttpd.conf`` make sure ``mod_fastcgi`` is
active within ``server.modules``. Then, within your ``$HTTP["host"]``
directive, configure your fastcgi script like the following::

    $HTTP["url"] =~ "" {
      fastcgi.server = (
        "/" => (
          "script.fcgi" => (
            "bin-path" => "/path/to/your/script.fcgi",
            "socket"          => "/tmp/script.sock",
            "check-local"     => "disable",
            "disable-time"    => 1,
            "min-procs"       => 1,
            "max-procs"       => 1, # adjust as needed
          ),
        ),
      )
    } # end of $HTTP["url"] =~ "^/"

Please see `Lighttpd FastCGI Docs
<http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI>`_ for
an explanation of the possible configuration options.
iÿÿÿÿNt   ServerAdapterc           B   sw   e  Z d  Z d d d „ Z d „  Z d „  Z d „  Z d e _ d „  Z	 d „  Z
 d „  Z d	 „  Z d
 e _ d „  Z RS(   s´  Adapter for an HTTP server.

    If you need to start more than one HTTP server (to serve on multiple
    ports, or protocols, etc.), you can manually register each one and then
    start them all with bus.start::

        s1 = ServerAdapter(bus, MyWSGIServer(host='0.0.0.0', port=80))
        s2 = ServerAdapter(bus, another.HTTPServer(host='127.0.0.1', SSL=True))
        s1.subscribe()
        s2.subscribe()
        bus.start()
    c         C   s1   | |  _  | |  _ | |  _ d  |  _ t |  _ d  S(   N(   t   bust
   httpservert	   bind_addrt   Nonet	   interruptt   Falset   running(   t   selfR   R   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyt   __init__ˆ   s
    				c         C   s0   |  j  j d |  j ƒ |  j  j d |  j ƒ d  S(   Nt   startt   stop(   R   t	   subscribeR
   R   (   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR      s    c         C   s0   |  j  j d |  j ƒ |  j  j d |  j ƒ d  S(   NR
   R   (   R   t   unsubscribeR
   R   (   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR   “   s    c         C   s  |  j  d k r d } n. t |  j  t ƒ r9 |  j ƒ  } n d |  j  } |  j rg |  j j d | ƒ d Sd |  _ |  j	 sˆ t
 d ƒ ‚ n  t |  j  t ƒ rª t |  j  Œ  n  d d l } | j d |  j ƒ } | j d | j ƒ  ƒ | j ƒ  |  j ƒ  t |  _ |  j j d	 | ƒ d S(
   s   Start the HTTP server.s   unknown interface (dynamic?)s   socket file: %ss   Already serving on %sNs    No HTTP server has been created.iÿÿÿÿt   targets   HTTPServer s   Serving on %s(   R   R   t
   isinstancet   tuplet	   _get_baseR   R   t   logR   R   t
   ValueErrort   wait_for_free_portt	   threadingt   Threadt   _start_http_threadt   setNamet   getNameR
   t   waitt   True(   R   t   on_whatR   t   t(    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR
   —   s(    				

	iK   c         C   s   |  j  s d S|  j \ } } t |  j  d d  ƒ sF t |  j  d d  ƒ rl d } | d k r | d | 7} q n# d } | d k r | d | 7} n  d	 | | f S(
   Nt    t   ssl_certificatet   ssl_adaptert   httpsi»  s   :%st   httpiP   s   %s://%s(   R   R   t   getattrR   (   R   t   hostt   portt   scheme(    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR   ¶   s    	c         C   sá   y |  j  j ƒ  WnÉ t k
 rT |  j j d ƒ t j ƒ  d |  _ |  j j ƒ  n‰ t	 k
 r— |  j j d ƒ t j ƒ  d |  _ |  j j ƒ  ‚  nF t j ƒ  d |  _ |  j j d d t
 d d ƒ|  j j ƒ  ‚  n Xd S(	   s  HTTP servers MUST be running in new threads, so that the
        main thread persists to receive KeyboardInterrupt's. If an
        exception is raised in the httpserver's thread then it's
        trapped here, and the bus (and therefore our httpserver)
        are shut down.
        s'   <Ctrl-C> hit: shutting down HTTP serveri   s,   SystemExit raised: shutting down HTTP servers#   Error in HTTP server: shutting downt	   tracebackt   leveli(   N(   R   R
   t   KeyboardInterruptR   R   t   syst   exc_infoR   t   exitt
   SystemExitR   (   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR   Æ   s"    c         C   ss   x; t  |  j d t ƒ s= |  j r- |  j ‚ n  t j d ƒ q Wt |  j t ƒ ro |  j \ } } t	 | | ƒ n  d S(   s8   Wait until the HTTP server is ready to receive requests.t   readygš™™™™™¹?N(
   R#   R   R   R   t   timet   sleepR   R   R   t   wait_for_occupied_port(   R   R$   R%   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR   ß   s    	c         C   sv   |  j  r[ |  j j ƒ  t |  j t ƒ r8 t |  j Œ  n  t |  _  |  j j	 d |  j ƒ n |  j j	 d |  j ƒ d S(   s   Stop the HTTP server.s   HTTP Server %s shut downs    HTTP Server %s already shut downN(
   R   R   R   R   R   R   R   R   R   R   (   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR   ë   s    		i   c         C   s   |  j  ƒ  |  j ƒ  d S(   s   Restart the HTTP server.N(   R   R
   (   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyt   restartù   s    
N(   t   __name__t
   __module__t   __doc__R   R	   R   R   R
   t   priorityR   R   R   R   R2   (    (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR    y   s   									t   FlupCGIServerc           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   s)   Adapter for a flup.server.cgi.WSGIServer.c         O   s   | |  _  | |  _ t |  _ d  S(   N(   t   argst   kwargsR   R.   (   R   R8   R9   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR	     s    		c         C   sB   d d l  m } | |  j |  j Ž  |  _ t |  _ |  j j ƒ  d S(   s   Start the CGI server.iÿÿÿÿ(   t
   WSGIServerN(   t   flup.server.cgiR:   R8   R9   t	   cgiserverR   R.   t   run(   R   R:   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR
     s    	c         C   s   t  |  _ d S(   s   Stop the HTTP server.N(   R   R.   (   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR     s    (   R3   R4   R5   R	   R
   R   (    (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR7   ÿ   s   		
t   FlupFCGIServerc           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   s*   Adapter for a flup.server.fcgi.WSGIServer.c         O   sd   | j  d d  ƒ d  k rE d d  l } t | d ƒ sE t d ƒ ‚ qE n  | |  _ | |  _ t |  _ d  S(   Nt   bindAddressiÿÿÿÿt   fromfds{   Dynamic FCGI server not available on this platform. You must use a static or external one by providing a legal bindAddress.(	   t   getR   t   sockett   hasattrR   R8   R9   R   R.   (   R   R8   R9   RB   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR	     s    		c         C   s]   d d l  m } | |  j |  j Ž  |  _ d „  |  j _ g  |  j _ t |  _ |  j j	 ƒ  d S(   s   Start the FCGI server.iÿÿÿÿ(   R:   c           S   s   d  S(   N(   R   (    (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyt   <lambda>6  s    N(
   t   flup.server.fcgiR:   R8   R9   t
   fcgiservert   _installSignalHandlerst   _oldSIGsR   R.   R=   (   R   R:   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR
   '  s    
	c         C   s1   t  |  j _ |  j j j |  j j _ t  |  _ d S(   s   Stop the HTTP server.N(   R   RF   t
   _keepGoingt   _threadPoolt
   _idleCountt   maxSpareR.   (   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR   ;  s    (   R3   R4   R5   R	   R
   R   (    (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR>     s   		t   FlupSCGIServerc           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   s*   Adapter for a flup.server.scgi.WSGIServer.c         O   s   | |  _  | |  _ t |  _ d  S(   N(   R8   R9   R   R.   (   R   R8   R9   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR	   I  s    		c         C   s]   d d l  m } | |  j |  j Ž  |  _ d „  |  j _ g  |  j _ t |  _ |  j j	 ƒ  d S(   s   Start the SCGI server.iÿÿÿÿ(   R:   c           S   s   d  S(   N(   R   (    (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyRD   ]  s    N(
   t   flup.server.scgiR:   R8   R9   t
   scgiserverRG   RH   R   R.   R=   (   R   R:   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR
   N  s    
	c         C   s(   t  |  _ t  |  j _ d |  j j _ d S(   s   Stop the HTTP server.i    N(   R   R.   RO   RI   RJ   RL   (   R   (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR   b  s    	(   R3   R4   R5   R	   R
   R   (    (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyRM   E  s   		c         C   s$   |  d k r d S|  d k r  d S|  S(   sD   Return the host on which a client can connect to the given listener.s   0.0.0.0s	   127.0.0.1s   ::s   ::0s	   ::0.0.0.0s   ::1(   s   ::s   ::0s	   ::0.0.0.0(    (   t   server_host(    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyt   client_hostk  s
    g      ð?c         C   sŽ  |  s t  d ƒ ‚ n  t |  ƒ }  t | ƒ } d d l } y" | j |  | | j | j ƒ } Wnq | j k
 rÎ d |  k r§ | j | j d d |  | d d f f g } qÏ | j	 | j d d |  | f f g } n Xx¸ | D]° } | \ } } } }	 }
 d } yC | j | | | ƒ } | j | ƒ | j |  | f ƒ | j ƒ  Wn' | j k
 rc| r†| j ƒ  q†qÖ Xt d t | ƒ t |  ƒ f ƒ ‚ qÖ Wd S(   s?   Raise an error if the given port is not free on the given host.s*   Host values of '' or None are not allowed.iÿÿÿÿNt   :i    R   sT   Port %s is in use on %s; perhaps the previous httpserver did not shut down properly.(   R   RQ   t   intRB   t   getaddrinfot	   AF_UNSPECt   SOCK_STREAMt   gaierrort   AF_INET6t   AF_INETR   t
   settimeoutt   connectt   closet   errort   IOErrort   repr(   R$   R%   t   timeoutRB   t   infot   rest   aft   socktypet   protot	   canonnamet   sat   s(    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyt
   check_portx  s2    -(gš™™™™™¹?c         C   s—   |  s t  d ƒ ‚ n  | d k r* t } n  xP t d ƒ D]B } y t |  | d | ƒWn t k
 rt t j | ƒ q7 Xd Sq7 Wt d | |  f ƒ ‚ d S(   s;   Wait for the specified port to become free (drop requests).s*   Host values of '' or None are not allowed.i2   R`   Ns   Port %r not free on %r(   R   R   t   free_port_timeoutt   rangeRi   R^   R/   R0   (   R$   R%   R`   t   trial(    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR   ¦  s    	c         C   sÀ   |  s t  d ƒ ‚ n  | d k r* t } n  xM t d ƒ D]? } y t |  | d | ƒWn t k
 rh d SXt j | ƒ q7 W|  t |  ƒ k r¥ t d | |  f ƒ ‚ n  d | } t	 j
 | ƒ d S(   s@   Wait for the specified port to become active (receive requests).s*   Host values of '' or None are not allowed.i2   R`   Ns   Port %r not bound on %rs/   Unable to verify that the server is bound on %r(   R   R   t   occupied_port_timeoutRk   Ri   R^   R/   R0   RQ   t   warningst   warn(   R$   R%   R`   Rl   t   msg(    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyR1   º  s    	
(   R5   R*   R/   Rn   t   objectR    R7   R>   RM   RQ   Ri   Rj   Rm   R   R   R1   (    (    (    s   /local/mnt/workspace/CRMBuilds/Saipan.LA.2.0-00145-STD.PROD-1_20200821_083004/b/common/sectools/ext/cherrypy/process/servers.pyt   <module>r   s   †.&	*