diff options
| -rw-r--r-- | main.py | 56 | ||||
| -rw-r--r-- | src/config.py | 7 |
2 files changed, 42 insertions, 21 deletions
diff --git a/main.py b/main.py index ff6f5c0..2bd9c9d 100644 --- a/main.py +++ b/main.py @@ -21,7 +21,7 @@ _usocket = socket.socket | ssl.SSLSocket # logging if not os.path.exists(f"{LOGGER_PATH}"): os.makedirs(f"{LOGGER_PATH}") -if os.path.isfile(f"{LOGGER_PATH}/latest.log"): +if os.path.isfile(f"{LOGGER_PATH}/latest.log") and os.path.getsize(f"{LOGGER_PATH}/latest.log") > 0: import gzip from datetime import datetime with open(f"{LOGGER_PATH}/latest.log", "rb") as file: @@ -173,7 +173,11 @@ class HTTPServer: # Remove self from thread list and close the connection self.client_threads.remove(threading.current_thread()) self.semaphore.release() - client.close() + + try: + client.close() + except (ssl.SSLError, OSError): + pass def _client_request_handler(self, client: _usocket, request: Request): """ @@ -224,7 +228,8 @@ class HTTPServer: buffer = bytearray() size = 0 - while not self.stop_event.is_set(): + timer = SOCKET_TIMER + while not self.stop_event.is_set() and timer > 0: try: buffer += client.recv(BUFFER_LENGTH) if buffer[-4:] == b'\r\n\r\n': @@ -235,7 +240,10 @@ class HTTPServer: break size = len(buffer) except (ssl.SSLWantReadError, BlockingIOError): - time.sleep(0.005) + time.sleep(SOCKET_ACK_INTERVAL) + except (ssl.SSLError, OSError): + break + timer -= 1 return None def _send_response(self, client: _usocket, response: Response) -> None: @@ -243,10 +251,6 @@ class HTTPServer: Send response to client """ - # make blocking socket - blk = client.getblocking() - client.setblocking(True) - # append connection status headers response.headers["Connection"] = "close" @@ -257,17 +261,28 @@ class HTTPServer: message += b'\r\n' # send message - client.sendall(message) + is_first = True for packet in response.get_data_stream(): - try: - client.sendall(packet) - except (ssl.SSLError, OSError): - break - if self.stop_event.is_set(): - break - - # return to previous state - client.setblocking(blk) + timer = SOCKET_TIMER + while timer > 0: + try: + # doesn't work with 'else' or if no 'print(is_first)' is present + # I have no clue as to why + if is_first: + client.sendall(message) + is_first = False + if not is_first: + client.sendall(packet) + break + except (ssl.SSLWantWriteError, BlockingIOError): + pass + except (ssl.SSLError, OSError): + return + time.sleep(SOCKET_ACK_INTERVAL) + timer -= 1 + print(timer) + if self.stop_event.is_set() or timer <= 0: + return def _accept(self) -> _usocket | None: """ @@ -278,10 +293,9 @@ class HTTPServer: try: if len(self.client_threads) < CLIENT_MAX_AMOUNT: return self.sock.accept()[0] - except (ssl.SSLError, OSError): + except (ssl.SSLError, OSError, BlockingIOError): pass - except BlockingIOError: - time.sleep(0.005) + time.sleep(SOCKET_ACK_INTERVAL) return None def fetch_file_headers(self, path: str) -> dict[str, Any] | None: diff --git a/src/config.py b/src/config.py index 077c9cc..2f9d4b0 100644 --- a/src/config.py +++ b/src/config.py @@ -2,9 +2,16 @@ LOGGER_PATH = "logs" BUFFER_LENGTH = 2**16 # 64 KiB BUFFER_MAX_SIZE = 2**30 * 0.5 # 512 MiB + +# threading CLIENT_MAX_AMOUNT = 2**15 # max requests at once, after which the connections are dropped CLIENT_MAX_PROCESS = 64 # max processing threads at once +# sockets +SOCKET_TIMEOUT = 10.0 +SOCKET_ACK_INTERVAL = 0.005 +SOCKET_TIMER = SOCKET_TIMEOUT / SOCKET_ACK_INTERVAL + # API API_FILE_RANDOM_MIN_SIZE_LIMIT = 1 # 1 byte API_FILE_RANDOM_MAX_SIZE_LIMIT = 2**30 * 5 # 5 GiB |