Merge master with dev

This commit is contained in:
Иван Солнцев 2024-07-03 14:15:22 +03:00
commit c7413887cc
7 changed files with 91 additions and 56 deletions

View file

@ -1,17 +1,27 @@
from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL
from server.urlhandler import path
import os
import logging
from server.urlhandler import path
import testmod
SETUP = {
"setup": {
"log_level": DEBUG
"log_to_file": False,
"log_level": logging.DEBUG
},
"server": {
"port": 8080,
}
}
if SETUP["setup"]["log_to_file"]:
logging.basicConfig(filename=os.path.join(os.getcwd(), "log", "main.log"), filemode="a", encoding="UTF-8",
level=SETUP["setup"]["log_level"],
format="[%(name)s][%(asctime)s][%(levelname)s] %(message)s")
else:
logging.basicConfig(encoding="UTF-8", level=SETUP["setup"]["log_level"],
format="[%(name)s][%(asctime)s][%(levelname)s] %(message)s")
urls = [
path("/", "static-file", "index.html"),
path("/func", "function", testmod.work)

View file

@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CatNet static file</title>
</head>
<body>

22
main.py
View file

@ -1,13 +1,31 @@
#!/usr/bin/python3
import os
import logging
from server.main import start
from server.main import start_http_server
import config
log = logging.getLogger(__name__)
if __name__ == "__main__":
try:
os.mkdir(os.path.join(os.getcwd(), "log"))
except OSError:
pass #print("dir is exists")
start()
project_logotype = """
________ _ _ _______ _______ ______ _ _
| ______ | | |_ | | | _____ | | _____| | ___ | | | | |
| | |_| | | | | | | |_| | | | | | | |_| |_|
| | | ||_| | | |_|___ | |___ | |___| | | | | |
| | | | |_| | | |___|_ | ___| | ____| |_| |_|
| | _ | | |_|| | _ | | | | | |_|_ | | | |
| |______| | | | |_ | | |_____| | | |_____ | | |_|_ |_|_|_|
|________| |_| |_| |_______| |_______| | | |_| |_|
============================== Start HTTP server ==============================="""
log.info(project_logotype)
start_http_server()

View file

@ -1,10 +1,21 @@
import logging
log = logging.getLogger(__name__)
def fileiter(filename):
log.debug("Open file %s to byte-read" % filename)
with open(filename, "rb") as f:
while True:
file_data = f.read(1024)
if len(file_data) >= 1024:
log.debug("File size greeter 1024 bytes, yield data")
yield file_data
log.debug("Continue")
else:
log.debug("File size lower 1024 bytes, yield data")
yield file_data
log.debug("Break")
break

View file

@ -11,6 +11,8 @@ from .response import Response
MAX_REQLINE = 64 * 1024
log = logging.getLogger(__name__)
class HTTPHandler:
def __init__(self, conn, addr):
@ -36,7 +38,7 @@ class HTTPHandler:
raw = self.read_fb.readline(MAX_REQLINE + 1)
if len(raw) > MAX_REQLINE:
logging.debug("Request line too long")
log.debug("Request line too long")
self.conn.send(b"")
self.conn.close()
return
@ -46,14 +48,15 @@ class HTTPHandler:
if len(req_line_splited) != 3:
if len(req_line_splited) > 3:
logging.debug("Request head too long")
log.debug("Request head too long")
else:
logging.debug("Request head too small")
log.debug("Request head too small")
self.conn.send(b"")
self.conn.close()
return
if req_line_splited[2] == "HTTP/1.0" or req_line_splited[2] == "HTTP/1.1":
if (req_line_splited[2] == "HTTP/1.0" or
req_line_splited[2] == "HTTP/1.1"):
self.http_type = req_line_splited[0]
else:
self.conn.send(b"")
@ -87,7 +90,7 @@ class HTTPHandler:
raw = self.read_fb.readline(MAX_REQLINE + 1)
if len(raw) > MAX_REQLINE:
logging.debug("Request header line too long")
log.debug("Request header line too long")
self.conn.send(b"")
self.conn.close()
return
@ -103,14 +106,18 @@ class HTTPHandler:
else:
decoded_data = raw.decode("UTF-8").rstrip("\r\n")
decoded_data_split = decoded_data.split(":", 1)
self.http_headers.update({decoded_data_split[0]: decoded_data_split[1].strip(" ")})
self.http_headers.update(
{
decoded_data_split[0]: decoded_data_split[1].strip(" ")
})
def http_data_handle(self):
"""
Chain of receive data partitions HTTP request
"""
# TODO: Get from headers Content-Length and get body of request, else receive 1024 bytes
# TODO: Get from headers Content-Length and get body of request, else
# receive 1024 bytes
"""
raw = self.read_fb.readline(1024)
@ -124,11 +131,11 @@ class HTTPHandler:
raw = self.read_fb.readline(1024)
"""
logging.debug(self.http_type)
logging.debug(self.http_address)
logging.debug(self.http_headers)
logging.debug(self.http_get_request)
logging.debug(self.data)
log.debug("Type of request: %s" % self.http_type)
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()
@ -169,7 +176,7 @@ class HTTPHandler:
self.write_fb.flush()
else:
logging.warning("Address configured on server, but type not allowed URL type in URLs list")
log.warning("Address configured on server, but type not allowed URL type in URLs list")
r = Response(status_code=404, data=b"Address configured on server, but type not allowed URL type in URLs list")
for i in r:
@ -188,39 +195,7 @@ class HTTPHandler:
self.conn.close()
def start():
logging.basicConfig(
filename=os.path.join(os.getcwd(), "log", "main.log"),
filemode="a",
encoding="UTF-8",
level=config.SETUP["setup"]["log_level"],
format="[%(asctime)s][%(levelname)s] %(message)s"
)
project_logotype = """
___________ _____ _____________
/ _______ / _/ /_ /_____ _____/
/ / /_/ _/ __ /_ / /
/ / / _/ /_ / / /
/ / / _/____/_ / / /
/ / __ / _______ / / /
/ /_______/ / / / / / / /
/___________/ /_/ /_/ /_/
___ __ ___________ _____________
/ _ | / / / _________/ /_____ _____/
/ / || / / / / / /
/ / || / / / /___ / /
/ / || / / / ____/ / /
/ / || / / / / / /
/ / ||/ / / /_________ / /
/_/ |__/ /___________/ /_/
====================================================
=== Server start separator ===
===================================================="""
logging.info(project_logotype)
def start_http_server():
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as main_server_socket:
main_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
@ -229,11 +204,11 @@ def start():
while True:
conn, addr = main_server_socket.accept()
logging.info("Accept connection from %s", addr[0])
log.info("Accept connection from %s", addr[0])
thr_serv_conn = threading.Thread(target=HTTPHandler, args=(conn, addr,))
thr_serv_conn.run()
except KeyboardInterrupt:
logging.info("Server get keyboard interrupt. Initialize server to stop")
logging.info("==================== End of log ====================")
log.info("Server get keyboard interrupt. Initialize server to stop")
log.info("==================== End of log ====================")

View file

@ -1,9 +1,14 @@
STATUS_CODE = {
import logging
log = logging.getLogger(__name__)
STATUS_BY_CODE = {
200: "OK",
404: "Not Found",
500: "Internal Server Error",
}
class Response:
def __iter__(self):
return self
@ -16,6 +21,8 @@ class Response:
def __next__(self):
if self.first:
log.debug("First packet generation of response")
resp = "HTTP/1.1 {} {}\r\n"
resp += "Server: cnserv\r\n"
resp += "Connection: close\r\n"
@ -23,13 +30,14 @@ class Response:
resp += "{}: {}\r\n".format(key, val)
resp += "\r\n"
resp = resp.format(self.status_code, STATUS_CODE[self.status_code])
resp = resp.format(self.status_code, STATUS_BY_CODE[self.status_code])
resp = resp.encode("UTF-8")
if type(self.data) == bytes:
resp += self.data
self.first = False
return resp
else:
@ -37,6 +45,7 @@ class Response:
raise StopIteration
elif hasattr(self.data, "__iter__"):
log.debug("Data is iterator, just generate next part")
try:
return next(self.data)
except StopIteration:

View file

@ -1,18 +1,29 @@
import os
import logging
log = logging.getLogger(__name__)
def path(path="/", _type="static-file", link="index.html", methods=("GET",)):
log.debug("Start generate path for %s address" % path)
if _type == "static-file":
log.info("Path %s is %s and linked %s for methods %s" % (path, _type, link, methods))
return {
path: (methods, _type, os.path.join(os.getcwd(), link))
}
elif _type == "redirect":
log.info("Path %s is %s and linked %s for methods %s" % (path, _type, link, methods))
return {
path: (methods, _type, link)
}
elif _type == "function":
log.info("Path %s is %s and linked %s for methods %s" % (path, _type, link, methods))
return {
path: (methods, _type, link)
}
else:
log.error("Path %s is %s but it type is unknown" % (path, _type))