Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

88 wiersze
3.7KB

  1. import os
  2. from engineio.static_files import get_static_file
  3. class WSGIApp(object):
  4. """WSGI application middleware for Engine.IO.
  5. This middleware dispatches traffic to an Engine.IO application. It can
  6. also serve a list of static files to the client, or forward unrelated
  7. HTTP traffic to another WSGI application.
  8. :param engineio_app: The Engine.IO server. Must be an instance of the
  9. ``engineio.Server`` class.
  10. :param wsgi_app: The WSGI app that receives all other traffic.
  11. :param static_files: A dictionary with static file mapping rules. See the
  12. documentation for details on this argument.
  13. :param engineio_path: The endpoint where the Engine.IO application should
  14. be installed. The default value is appropriate for
  15. most cases.
  16. Example usage::
  17. import engineio
  18. import eventlet
  19. eio = engineio.Server()
  20. app = engineio.WSGIApp(eio, static_files={
  21. '/': {'content_type': 'text/html', 'filename': 'index.html'},
  22. '/index.html': {'content_type': 'text/html',
  23. 'filename': 'index.html'},
  24. })
  25. eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
  26. """
  27. def __init__(self, engineio_app, wsgi_app=None, static_files=None,
  28. engineio_path='engine.io'):
  29. self.engineio_app = engineio_app
  30. self.wsgi_app = wsgi_app
  31. self.engineio_path = engineio_path.strip('/')
  32. self.static_files = static_files or {}
  33. def __call__(self, environ, start_response):
  34. if 'gunicorn.socket' in environ:
  35. # gunicorn saves the socket under environ['gunicorn.socket'], while
  36. # eventlet saves it under environ['eventlet.input']. Eventlet also
  37. # stores the socket inside a wrapper class, while gunicon writes it
  38. # directly into the environment. To give eventlet's WebSocket
  39. # module access to this socket when running under gunicorn, here we
  40. # copy the socket to the eventlet format.
  41. class Input(object):
  42. def __init__(self, socket):
  43. self.socket = socket
  44. def get_socket(self):
  45. return self.socket
  46. environ['eventlet.input'] = Input(environ['gunicorn.socket'])
  47. path = environ['PATH_INFO']
  48. if path is not None and \
  49. path.startswith('/{0}/'.format(self.engineio_path)):
  50. return self.engineio_app.handle_request(environ, start_response)
  51. else:
  52. static_file = get_static_file(path, self.static_files) \
  53. if self.static_files else None
  54. if static_file:
  55. if os.path.exists(static_file['filename']):
  56. start_response(
  57. '200 OK',
  58. [('Content-Type', static_file['content_type'])])
  59. with open(static_file['filename'], 'rb') as f:
  60. return [f.read()]
  61. else:
  62. return self.not_found(start_response)
  63. elif self.wsgi_app is not None:
  64. return self.wsgi_app(environ, start_response)
  65. return self.not_found(start_response)
  66. def not_found(self, start_response):
  67. start_response("404 Not Found", [('Content-Type', 'text/plain')])
  68. return [b'Not Found']
  69. class Middleware(WSGIApp):
  70. """This class has been renamed to ``WSGIApp`` and is now deprecated."""
  71. def __init__(self, engineio_app, wsgi_app=None,
  72. engineio_path='engine.io'):
  73. super(Middleware, self).__init__(engineio_app, wsgi_app,
  74. engineio_path=engineio_path)