From eabd85f68b636493277cd9a2880040d2e2a59e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=A1=D0=BE=D0=BB=D0=BD=D1=86?= =?UTF-8?q?=D0=B5=D0=B2?= Date: Tue, 8 Oct 2024 13:54:15 +0300 Subject: [PATCH] Support keep alive Improvements: - Response return Content-Length header; - HTTP handler run recursive after call; - File iterator when call before yield file size. --- server/file_read.py | 5 +++++ server/http_handler.py | 23 ++++++++++++++++------- server/main.py | 2 +- server/response.py | 10 ++++++++-- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/server/file_read.py b/server/file_read.py index e4764b9..394e310 100644 --- a/server/file_read.py +++ b/server/file_read.py @@ -18,11 +18,16 @@ # import logging +import os log = logging.getLogger(__name__) def fileiter(filename): + log.debug("Calc file %s size" % filename) + + yield os.path.getsize(filename) + log.debug("Open file %s to byte-read" % filename) with open(filename, "rb") as f: diff --git a/server/http_handler.py b/server/http_handler.py index 5a8c4d9..c573ac2 100644 --- a/server/http_handler.py +++ b/server/http_handler.py @@ -48,16 +48,25 @@ class HTTPHandler: def __write_data(self, data_iter): for chunk in data_iter: - self.write_fd.write(chunk) - self.write_fd.flush() + try: + self.write_fd.write(chunk) + self.write_fd.flush() + except BrokenPipeError: + pass def __read_data(self, size=MAX_REQUEST_LINE_SIZE+1): - return self.read_fd.readline(size) + try: + return self.read_fd.readline(size) + except BrokenPipeError: + pass def __close(self): - self.write_fd.close() - self.read_fd.close() - self.conn.close() + try: + self.write_fd.close() + self.read_fd.close() + self.conn.close() + except BrokenPipeError: + pass def __handle_connection(self): """ @@ -258,4 +267,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..b63b15b 100644 --- a/server/main.py +++ b/server/main.py @@ -27,7 +27,7 @@ def init_server_socket(server_handler): log.info("Accepted 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")