Support keep alive

Improvements:
  - Response return Content-Length header;
  - HTTP handler run recursive after call;
  - File iterator when call before yield file size.
This commit is contained in:
Иван Солнцев 2024-10-08 13:54:15 +03:00
parent 0fb84420fe
commit eabd85f68b
Signed by: johnsol
GPG key ID: C56B337609C9821E
4 changed files with 30 additions and 10 deletions

View file

@ -18,11 +18,16 @@
# #
import logging import logging
import os
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def fileiter(filename): def fileiter(filename):
log.debug("Calc file %s size" % filename)
yield os.path.getsize(filename)
log.debug("Open file %s to byte-read" % filename) log.debug("Open file %s to byte-read" % filename)
with open(filename, "rb") as f: with open(filename, "rb") as f:

View file

@ -48,16 +48,25 @@ class HTTPHandler:
def __write_data(self, data_iter): def __write_data(self, data_iter):
for chunk in data_iter: for chunk in data_iter:
self.write_fd.write(chunk) try:
self.write_fd.flush() self.write_fd.write(chunk)
self.write_fd.flush()
except BrokenPipeError:
pass
def __read_data(self, size=MAX_REQUEST_LINE_SIZE+1): 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): def __close(self):
self.write_fd.close() try:
self.read_fd.close() self.write_fd.close()
self.conn.close() self.read_fd.close()
self.conn.close()
except BrokenPipeError:
pass
def __handle_connection(self): def __handle_connection(self):
""" """
@ -258,4 +267,4 @@ class HTTPHandler:
r = Response(status_code=404, data=b"Not found!") r = Response(status_code=404, data=b"Not found!")
self.__write_data(r) self.__write_data(r)
self.__close() self.__handle_connection()

View file

@ -27,7 +27,7 @@ def init_server_socket(server_handler):
log.info("Accepted connection from %s", addr[0]) log.info("Accepted connection from %s", addr[0])
thr_serv_conn = threading.Thread(target=server_handler, args=(conn, addr,), daemon=True) thr_serv_conn = threading.Thread(target=server_handler, args=(conn, addr,), daemon=True)
thr_serv_conn.run() thr_serv_conn.start()
except KeyboardInterrupt: except KeyboardInterrupt:
log.info("Server get keyboard interrupt, bye!") log.info("Server get keyboard interrupt, bye!")

View file

@ -51,11 +51,17 @@ class Response:
resp = "HTTP/1.1 {} {}\r\n" resp = "HTTP/1.1 {} {}\r\n"
resp += "Server: cnserv\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(): for key, val in self.additional_headers.items():
resp += "{}: {}\r\n".format(key, val) 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.format(self.status_code, STATUS_BY_CODE[self.status_code])
resp = resp.encode("UTF-8") resp = resp.encode("UTF-8")