Source code for ginsfsm.protocols.wsgi.server.c_wsgi_server

# -*- encoding: utf-8 -*-
"""
GObj :class:`GWsgiServer`
=========================

WSGI server.

It uses :class:`ginsfsm.protocols.http.server.c_http_server.GHttpServer`.

.. autoclass:: GWsgiServer
    :members:

"""

from ginsfsm.gobj import GObj
from ginsfsm.compat import string_types
from ginsfsm.globals import get_global_app
from ginsfsm.protocols.http.server.c_http_server import GHttpServer
from ginsfsm.protocols.wsgi.common.wsgi_response import WsgiResponse
from ginsfsm.protocols.http.server.c_http_server import GHTTPSERVER_GCONFIG


def ac_channel_opened(self, event):
    """ New client opened.
    """


def ac_channel_closed(self, event):
    """ Client closed.
    """


def ac_request(self, event):
    # quiza es mejor generalizar este nivel.
    # elegir el tipo de aplicación:
    # si es un GObj enviarle el evento, sino, por defecto, sería una wsgi.
    # el evento de desconexión lo tengo solucionado: un subscribe al channel.

    channel = event.channel
    request = event.request
    application = self.select_app(request)
    response = WsgiResponse(request, self, application)
    self.send_event(channel, 'EV_HTTP_RESPONSE', response=response)


GWSGISERVER_FSM = {
    'event_list': (
        'EV_HTTP_CHANNEL_OPENED: bottom input',
        'EV_HTTP_CHANNEL_CLOSED: bottom input',
        'EV_HTTP_REQUEST: bottom input',
    ),
    'state_list': ('ST_IDLE',),
    'machine': {
        'ST_IDLE':
        (
            ('EV_HTTP_CHANNEL_OPENED',  ac_channel_opened,  None),
            ('EV_HTTP_CHANNEL_CLOSED',  ac_channel_closed,  None),
            ('EV_HTTP_REQUEST',         ac_request,         None),
        ),
    }
}

GWSGISERVER_GCONFIG = GHTTPSERVER_GCONFIG.copy()
GWSGISERVER_GCONFIG.update({
    'application': [None, None, 0, None, "wsgi application"],
})


[docs]class GWsgiServer(GObj): """ WSGI Server gobj. .. ginsfsm:: :fsm: GWSGISERVER_FSM :gconfig: GWSGISERVER_GCONFIG *Bottom Input-Events:* * :attr:`'EV_HTTP_CHANNEL_OPENED'`: new http client. Event attributes: * ``channel``: http channel. * :attr:`'EV_HTTP_CHANNEL_CLOSED'`: http client closed. Event attributes: * ``channel``: http channel. * :attr:`'EV_HTTP_REQUEST'`: new http request. Event attributes: * ``channel``: http channel. * ``request``: http request. See :class:`ginsfsm.protocols.http.server.c_http_clisrv.GHttpCliSrv`. """ def __init__(self): GObj.__init__(self, GWSGISERVER_FSM, GWSGISERVER_GCONFIG) self._n_connected_clisrv = 0
[docs] def start_up(self): self.ghttpserver = self.create_gobj( self.name if self.name else 'http-server', GHttpServer, self, subscriber=self, host=self.config.host, port=self.config.port, origins=self.config.origins, inactivity_timeout=self.config.inactivity_timeout, responseless_timeout=self.config.responseless_timeout, maximum_simultaneous_requests= self.config.maximum_simultaneous_requests, ) self.serversock = self.ghttpserver.gserversock.socket # Used in environ self.effective_host, self.effective_port = self.getsockname() self.server_name = self._get_server_name(self.config.host)
def select_app(self, request): # Starting from ini file, the application references is a string # because the wsgi-apps are loaded later than main gaplic. if isinstance(self.config.application, string_types): self.config.application = get_global_app(self.config.application) return self.config.application def _get_server_name(self, ip): """Given an IP or hostname, try to determine the server name.""" if ip: srv_name = str(ip) else: srv_name = str(self.serversock.socketmod.gethostname()) # Convert to a host name if necessary. for c in srv_name: if c != '.' and not c.isdigit(): return srv_name try: if srv_name == '0.0.0.0': return 'localhost' srv_name = self.serversock.socketmod.gethostbyaddr(srv_name)[0] except: pass return srv_name def getsockname(self): return self.serversock.getsockname()