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
|