def __init__(self, host, port, root, whitelist): """Create a server that serves from root on host:port. Only paths in the root directory that are also present in the whitelist will be served. The whitelist paths are absolute, so they must begin with a slash. The paths '/', '/index.html', and '/404.html' must be included for the website to work properly. """ self.httpd = pywsgi.WSGIServer((host, port), self.handle_request) self.url = "http://{}:{}".format(host, port) self.root = root.rstrip('/') self.whitelist = whitelist self.running = False self.controller = Controller()
class Server(object): """A very simple web server.""" def __init__(self, host, port, root, whitelist): """Create a server that serves from root on host:port. Only paths in the root directory that are also present in the whitelist will be served. The whitelist paths are absolute, so they must begin with a slash. The paths '/', '/index.html', and '/404.html' must be included for the website to work properly. """ self.httpd = pywsgi.WSGIServer((host, port), self.handle_request) self.url = "http://{}:{}".format(host, port) self.root = root.rstrip('/') self.whitelist = whitelist self.running = False self.controller = Controller() def start(self, open_browser=True, verbose=True): """Starts the server if it is not already running. Unless False arguments are passed, prints a message to standard output and opens the browser to the served page.""" if self.running: return self.httpd.start() if verbose: print("Serving on {}...".format(self.url)) if open_browser: webbrowser.open(self.url) self.running = True def stop(self): """Stops the program and the server. Does nothing if already stopped.""" if self.running: self.controller.stop() self.httpd.stop() def stay_alive(self): """Prevents the program from ending by never returning. Only exits when a keyboard interrupt is detected. The server must already be running.""" assert self.running try: self.httpd.serve_forever() except KeyboardInterrupt: exit() def handle_request(self, env, start_response): """Handles all server requests.""" method = env['REQUEST_METHOD'] if method == 'GET': return self.handle_get(env['PATH_INFO'], start_response) elif method == 'POST': return self.handle_post(extract_data(env), start_response) def handle_get(self, path_info, start_response): """Handles a GET request, which is used for getting resources.""" path = self.path(path_info) head = headers(get_mime(path), os.path.getsize(path)) start_response(get_status(path), head) return open(path) def handle_post(self, data, start_response): """Handles a POST request, which is used for AJAX communication.""" msg = self.controller(data) head = headers(get_mime(), len(msg)) start_response(get_status(), head) yield msg def path(self, path_info): """Returns the relative path that should be followed for the request. The root will go to index file. Anything not present in the server's whitelist will cause a 404.""" if path_info in self.whitelist: if path_info == '/': path_info = PATH_INDEX else: path_info = PATH_404 return self.root + path_info
class Server(object): """A very simple web server.""" def __init__(self, host, port, root, whitelist): """Create a server that serves from root on host:port. Only paths in the root directory that are also present in the whitelist will be served. The whitelist paths are absolute, so they must begin with a slash. The paths '/', '/index.html', and '/404.html' must be included for the website to work properly. """ self.httpd = pywsgi.WSGIServer((host, port), self.handle_request) self.url = "http://{}:{}".format(host, port) self.root = root.rstrip('/') self.whitelist = whitelist self.running = False self.controller = Controller() def start(self, open_browser=True, verbose=True): """Starts the server if it is not already running. Unless False arguments are passed, prints a message to standard output and opens the browser to the served page.""" if self.running: return self.httpd.start() if verbose: print("Serving on {}...".format(self.url)) if open_browser: webbrowser.open(self.url) self.running = True def stop(self): """Stops the program and the server. Does nothing if already stopped.""" if self.running: self.controller.stop() self.httpd.stop() def stay_alive(self): """Prevents the program from ending by never returning. Only exits when a keyboard interrupt is detected. The server must already be running.""" assert self.running try: self.httpd.serve_forever() except KeyboardInterrupt: exit() def handle_request(self, env, start_response): """Handles all server requests.""" method = env['REQUEST_METHOD'] if method == 'GET': return self.handle_get(env['PATH_INFO'], start_response) elif method == 'POST': return self.handle_post(extract_data(env), start_response) def handle_get(self, path_info, start_response): """Handles a GET request, which is used for getting resources.""" path = self.path(path_info) head = headers(get_mime(path), os.path.getsize(path)) start_response(get_status(path), head) return open(path) def handle_post(self, data, start_response): """Handles a POST request, which is used for AJAX communication.""" msg = self.controller(data) if msg == None: head = headers(get_mime(), 0) start_response(STATUS_204, head) return [None] head = headers(get_mime(), len(msg)) start_response(get_status(), head) return [msg] def path(self, path_info): """Returns the relative path that should be followed for the request. The root will go to index file. Anything not present in the server's whitelist will cause a 404.""" if path_info in self.whitelist: if path_info == '/': path_info = PATH_INDEX else: path_info = PATH_404 return self.root + path_info