"""HTTP Server This module contains a HTTP server """ from configparser import SafeConfigParser import threading import socket from composer import ResponseComposer from parser import RequestParser import weblogging as logging class ConnectionHandler(threading.Thread): """Connection Handler for HTTP Server""" def __init__(self, conn_socket, addr, timeout): """Initialize the HTTP Connection Handler Args: conn_socket (socket): socket used for connection with client addr (str): ip address of client timeout (int): seconds until timeout """ super(ConnectionHandler, self).__init__() self.daemon = True self.conn_socket = conn_socket self.addr = addr self.timeout = timeout def handle_connection(self): """Handle a new connection""" rp = RequestParser() rc = ResponseComposer(timeout=self.timeout) while True: data = self.conn_socket.recv(4096) if len(data) == 0: break for req in rp.parse_requests(data): logging.info("<-- %s" % req.startline()) resp = rc.compose_response(req) logging.info("--> %s" % resp.startline()) sent = self.conn_socket.send(str(resp)) if sent == 0: raise RuntimeError('Socket broken') self.conn_socket.close() def run(self): """Run the thread of the connection handler""" try: self.handle_connection() except socket.error, e: print('ERR ' + str(e)) class Server: """HTTP Server""" def __init__(self, config, **kwargs): """Initialize the HTTP server Args: hostname (str): hostname of the server server_port (int): port that the server is listening on timeout (int): seconds until timeout """ self.read_config(config, **kwargs) self.done = False def read_config(self, config, **kwargs): self.cp = SafeConfigParser() self.cp.read(config) if not self.cp.has_section('webhttp'): self.cp.add_section('webhttp') for (name, val) in self.cp.items('webhttp') + kwargs.items(): setattr(self, name, val) def run(self): """Run the HTTP Server and start listening""" serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.bind((self.hostname, self.port)) serversocket.listen(5) while not self.done: (clientsocket, addr) = serversocket.accept() ch = ConnectionHandler(clientsocket, addr, self.timeout) ch.run() def shutdown(self): """Safely shut down the HTTP server""" self.done = True