diff --git a/server/file_read.py b/server/file_read.py index e4764b9..8e2da58 100644 --- a/server/file_read.py +++ b/server/file_read.py @@ -18,13 +18,20 @@ # import logging +import os log = logging.getLogger(__name__) -def fileiter(filename): - log.debug("Open file %s to byte-read" % filename) +def file_iterator(filename): + log.debug("Try access to file \"%s\"", filename) + if not os.path.isfile(filename): + raise FileNotFoundError("File \"%s\" not found", filename) + log.debug("Get size of file \"%s\"", filename) + yield os.path.getsize(filename) + + log.debug("Open file \"%s\" to byte-read", filename) with open(filename, "rb") as f: while True: file_data = f.read(1024) diff --git a/server/http_handler.py b/server/http_handler.py index 5a8c4d9..18d2cd3 100644 --- a/server/http_handler.py +++ b/server/http_handler.py @@ -22,7 +22,7 @@ import logging import config from .common import MAX_REQUEST_LINE_SIZE, HandlerType, HTTPMethod -from .file_read import fileiter +from .file_read import file_iterator from .response import Response @@ -44,10 +44,13 @@ class HTTPHandler: self.data = b"" - self.__handle_connection() + try: + self.__handle_connection() + except BrokenPipeError: + log.info("Conenction pipe broken, close thread") - def __write_data(self, data_iter): - for chunk in data_iter: + def __write_data(self, response): + for chunk in response: self.write_fd.write(chunk) self.write_fd.flush() @@ -202,14 +205,14 @@ class HTTPHandler: self.__close() return - log.debug("Want to receive {} bytes from client".format(bytes_to_receive)) + log.debug("Want to receive %s bytes from client", bytes_to_receive) self.data = self.read_fd.read(bytes_to_receive) - log.debug("Request method: %s" % self.http_method) - log.debug("Requested address: %s" % self.http_address) - log.debug("Request headers: %s" % self.http_headers) - log.debug("Request in GET after ?: %s" % self.http_get_request) - log.debug("Data: %s" % self.data) + log.debug("Request method: %s", self.http_method) + log.debug("Requested address: %s", self.http_address) + log.debug("Request headers: %s", self.http_headers) + log.debug("Request in GET after ?: %s", self.http_get_request) + log.debug("Data: %s", self.data) self.__send_form_data() @@ -225,8 +228,8 @@ class HTTPHandler: found = True if path.handler_type == HandlerType.STATIC_FILE: - log.debug("Address associated with static file on path {}".format(path.link)) - r = Response(data=fileiter(path.link)) + log.debug("Address associated with static file on path %s", path.link) + r = Response(data=file_iterator(path.link)) self.__write_data(r) elif path.handler_type == HandlerType.FUNCTION: @@ -258,4 +261,4 @@ class HTTPHandler: r = Response(status_code=404, data=b"Not found!") self.__write_data(r) - self.__close() + self.__handle_connection() diff --git a/server/main.py b/server/main.py index 3325429..6a4a25c 100644 --- a/server/main.py +++ b/server/main.py @@ -16,18 +16,21 @@ def init_server_socket(server_handler): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as main_server_socket: + log.debug("Set socket option REUSEADDR to True") main_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) - log.debug("Attempt to bind socket to 0.0.0.0:{}".format(config.SETUP["server"]["port"])) + + log.info("Attempt to bind socket to 0.0.0.0:%d", config.SETUP["server"]["port"]) main_server_socket.bind(("0.0.0.0", config.SETUP["server"]["port"])) - log.debug("Make socket is listen") + + log.debug("Make socket to listen") main_server_socket.listen() while True: conn, addr = main_server_socket.accept() - log.info("Accepted connection from %s", addr[0]) + log.info("Accept connection from %s", addr[0]) thr_serv_conn = threading.Thread(target=server_handler, args=(conn, addr,), daemon=True) - thr_serv_conn.run() + thr_serv_conn.start() except KeyboardInterrupt: log.info("Server get keyboard interrupt, bye!") diff --git a/server/response.py b/server/response.py index ec2ecf3..7cf4c17 100644 --- a/server/response.py +++ b/server/response.py @@ -51,11 +51,17 @@ class Response: resp = "HTTP/1.1 {} {}\r\n" resp += "Server: cnserv\r\n" - resp += "Connection: close\r\n" + resp += "Connection: keep-alive\r\n" + for key, val in self.additional_headers.items(): resp += "{}: {}\r\n".format(key, val) - resp += "\r\n" + if type(self.data) == bytes: + resp += "Content-Length: {}\r\n".format(len(self.data)) + elif hasattr(self.data, "__iter__"): + resp += "Content-Length: {}\r\n".format(next(self.data)) + + resp += "\r\n" resp = resp.format(self.status_code, STATUS_BY_CODE[self.status_code]) resp = resp.encode("UTF-8")