codekingpro/portable-devtools
114k
1import os2from engineio.static_files import get_static_file3 4 5class WSGIApp(object):6 """WSGI application middleware for Engine.IO.7 8 This middleware dispatches traffic to an Engine.IO application. It can9 also serve a list of static files to the client, or forward unrelated10 HTTP traffic to another WSGI application.11 12 :param engineio_app: The Engine.IO server. Must be an instance of the13 ``engineio.Server`` class.14 :param wsgi_app: The WSGI app that receives all other traffic.15 :param static_files: A dictionary with static file mapping rules. See the16 documentation for details on this argument.17 :param engineio_path: The endpoint where the Engine.IO application should18 be installed. The default value is appropriate for19 most cases.20 21 Example usage::22 23 import engineio24 import eventlet25 26 eio = engineio.Server()27 app = engineio.WSGIApp(eio, static_files={28 '/': {'content_type': 'text/html', 'filename': 'index.html'},29 '/index.html': {'content_type': 'text/html',30 'filename': 'index.html'},31 })32 eventlet.wsgi.server(eventlet.listen(('', 8000)), app)33 """34 def __init__(self, engineio_app, wsgi_app=None, static_files=None,35 engineio_path='engine.io'):36 self.engineio_app = engineio_app37 self.wsgi_app = wsgi_app38 self.engineio_path = engineio_path39 if not self.engineio_path.startswith('/'):40 self.engineio_path = '/' + self.engineio_path41 if not self.engineio_path.endswith('/'):42 self.engineio_path += '/'43 self.static_files = static_files or {}44 45 def __call__(self, environ, start_response):46 if 'gunicorn.socket' in environ:47 # gunicorn saves the socket under environ['gunicorn.socket'], while48 # eventlet saves it under environ['eventlet.input']. Eventlet also49 # stores the socket inside a wrapper class, while gunicon writes it50 # directly into the environment. To give eventlet's WebSocket51 # module access to this socket when running under gunicorn, here we52 # copy the socket to the eventlet format.53 class Input(object):54 def __init__(self, socket):55 self.socket = socket56 57 def get_socket(self):58 return self.socket59 60 environ['eventlet.input'] = Input(environ['gunicorn.socket'])61 path = environ['PATH_INFO']62 if path is not None and path.startswith(self.engineio_path):63 return self.engineio_app.handle_request(environ, start_response)64 else:65 static_file = get_static_file(path, self.static_files) \66 if self.static_files else None67 if static_file and os.path.exists(static_file['filename']):68 start_response(69 '200 OK',70 [('Content-Type', static_file['content_type'])])71 with open(static_file['filename'], 'rb') as f:72 return [f.read()]73 elif self.wsgi_app is not None:74 return self.wsgi_app(environ, start_response)75 return self.not_found(start_response)76 77 def not_found(self, start_response):78 start_response("404 Not Found", [('Content-Type', 'text/plain')])79 return [b'Not Found']80 81 82class Middleware(WSGIApp):83 """This class has been renamed to ``WSGIApp`` and is now deprecated."""84 def __init__(self, engineio_app, wsgi_app=None,85 engineio_path='engine.io'):86 super().__init__(engineio_app, wsgi_app, engineio_path=engineio_path)87 