File: middleware.py

package info (click to toggle)
python-engineio 3.0.0%2Bdfsg-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 468 kB
  • sloc: python: 4,688; makefile: 15
file content (74 lines) | stat: -rw-r--r-- 3,294 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class WSGIApp(object):
    """WSGI application middleware for Engine.IO.

    This middleware dispatches traffic to an Engine.IO application, and
    optionally forwards regular HTTP traffic to a WSGI application, or serve
    a list of predefined static files to clients.

    :param engineio_app: The Engine.IO server.
    :param wsgi_app: The WSGI app that receives all other traffic.
    :param static_files: A dictionary where the keys are URLs that should be
                         served as static files. For each URL, the value is
                         a dictionary with ``content_type`` and ``filename``
                         keys. This option is intended to be used for serving
                         client files during development.
    :param engineio_path: The endpoint where the Engine.IO application should
                          be installed. The default value is appropriate for
                          most cases.

    Example usage::

        import engineio
        import eventlet

        eio = engineio.Server()
        app = engineio.WSGIApp(eio, static_files={
            '/': {'content_type': 'text/html', 'filename': 'index.html'},
            '/index.html': {'content_type': 'text/html',
                            'filename': 'index.html'},
        })
        eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
    """
    def __init__(self, engineio_app, wsgi_app=None, static_files=None,
                 engineio_path='engine.io'):
        self.engineio_app = engineio_app
        self.wsgi_app = wsgi_app
        self.engineio_path = engineio_path.strip('/')
        self.static_files = static_files or {}

    def __call__(self, environ, start_response):
        if 'gunicorn.socket' in environ:
            # gunicorn saves the socket under environ['gunicorn.socket'], while
            # eventlet saves it under environ['eventlet.input']. Eventlet also
            # stores the socket inside a wrapper class, while gunicon writes it
            # directly into the environment. To give eventlet's WebSocket
            # module access to this socket when running under gunicorn, here we
            # copy the socket to the eventlet format.
            class Input(object):
                def __init__(self, socket):
                    self.socket = socket

                def get_socket(self):
                    return self.socket

            environ['eventlet.input'] = Input(environ['gunicorn.socket'])
        path = environ['PATH_INFO']
        if path is not None and \
                path.startswith('/{0}/'.format(self.engineio_path)):
            return self.engineio_app.handle_request(environ, start_response)
        elif path in self.static_files:
            start_response(
                '200 OK',
                [('Content-Type', self.static_files[path]['content_type'])])
            with open(self.static_files[path]['filename'], 'rb') as f:
                return [f.read()]
        elif self.wsgi_app is not None:
            return self.wsgi_app(environ, start_response)
        else:
            start_response("404 Not Found", [('Content-type', 'text/plain')])
            return ['Not Found']


class Middleware(WSGIApp):
    """This class has been renamed to WSGIApp and is now deprecated."""
    pass