Source code for pywb.utils.geventserver

import logging
import traceback

from gevent import spawn
from gevent.pywsgi import WSGIHandler, WSGIServer


# ============================================================================
[docs]class GeventServer(object): """Class for optionally running a WSGI application in a greenlet""" def __init__(self, app, port=0, hostname='localhost', handler_class=None, direct=False): """Initialize a new GeventServer instance :param app: The WSGI application instance to be used :param int port: The port the server is to listen on :param str hostname: The hostname the server is to use :param handler_class: The class to be used for handling WSGI requests :param bool direct: T/F indicating if the server should be run in a greenlet or in current thread """ self.port = port self.server = None self.ge = None self.make_server(app, port, hostname, handler_class, direct=direct)
[docs] def stop(self): """Stops the running server if it was started""" if self.server: logging.debug('stopping server on ' + str(self.port)) self.server.stop()
def _run(self, server, port): """Start running the server forever :param server: The server to be run :param int port: The port the server is to listen on """ logging.debug('starting server on ' + str(port)) try: server.serve_forever() except Exception as e: logging.debug('server failed to start on ' + str(port)) traceback.print_exc()
[docs] def make_server(self, app, port, hostname, handler_class, direct=False): """Creates and starts the server. If direct is true the server is run in the current thread otherwise in a greenlet. :param app: The WSGI application instance to be used :param int port: The port the server is to listen on :param str hostname: The hostname the server is to use :param handler_class: The class to be used for handling WSGI requests :param bool direct: T/F indicating if the server should be run in a greenlet or in current thread """ server = WSGIServer((hostname, port), app, handler_class=handler_class) server.init_socket() self.port = server.address[1] self.server = server if direct: self.ge = None self._run(server, self.port) else: self.ge = spawn(self._run, server, self.port)
[docs] def join(self): """Joins the greenlet spawned for running the server if it was started in non-direct mode""" if self.ge: self.ge.join()
# ============================================================================
[docs]class RequestURIWSGIHandler(WSGIHandler): """A specific WSGIHandler subclass that adds `REQUEST_URI` to the environ dictionary for every request """
[docs] def get_environ(self): """Returns the WSGI environ dictionary with the `REQUEST_URI` added to it :return: The WSGI environ dictionary for the request :rtype: dict """ environ = super(RequestURIWSGIHandler, self).get_environ() environ['REQUEST_URI'] = self.path return environ