Add more debug messages
- Move log initialization to config file; - Add meta tag for charset to index file.
This commit is contained in:
parent
f7d2a675fb
commit
a4f7411e10
8 changed files with 95 additions and 64 deletions
17
config.py
17
config.py
|
@ -1,19 +1,26 @@
|
||||||
from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL
|
import logging
|
||||||
|
|
||||||
import testmod
|
|
||||||
|
|
||||||
from server.urlhandler import path
|
from server.urlhandler import path
|
||||||
|
import testmod
|
||||||
|
|
||||||
SETUP = {
|
SETUP = {
|
||||||
"setup": {
|
"setup": {
|
||||||
"log_level": DEBUG
|
"log_to_file": False,
|
||||||
|
"log_level": logging.DEBUG
|
||||||
},
|
},
|
||||||
"server": {
|
"server": {
|
||||||
"port": 8080,
|
"port": 8080,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if SETUP["setup"]["log_to_file"]:
|
||||||
|
logging.basicConfig(filename="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 = [
|
urls = [
|
||||||
path("/", "static-file", "index.html"),
|
path("/", "static-file", "index.html"),
|
||||||
path("/func", "function", testmod.work)
|
path("/func", "function", testmod.work)
|
||||||
|
|
22
main.py
22
main.py
|
@ -1,7 +1,25 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
import logging
|
||||||
|
|
||||||
from server.main import start
|
from server.main import start_http_server
|
||||||
|
import config
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
start()
|
project_logotype = """
|
||||||
|
________ _ _ _______ _______ ______ _ _
|
||||||
|
| ______ | | |_ | | | _____ | | _____| | ___ | | | | |
|
||||||
|
| | |_| | | | | | | |_| | | | | | | |_| |_|
|
||||||
|
| | | ||_| | | |_|___ | |___ | |___| | | | | |
|
||||||
|
| | | | |_| | | |___|_ | ___| | ____| |_| |_|
|
||||||
|
| | _ | | |_|| | _ | | | | | |_|_ | | | |
|
||||||
|
| |______| | | | |_ | | |_____| | | |_____ | | |_|_ |_|_|_|
|
||||||
|
|________| |_| |_| |_______| |_______| | | |_| |_|
|
||||||
|
|
||||||
|
============================== Start HTTP server ==============================="""
|
||||||
|
|
||||||
|
log.info(project_logotype)
|
||||||
|
|
||||||
|
start_http_server()
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def fileiter(filename):
|
def fileiter(filename):
|
||||||
|
log.debug("Open file %s to byte-read" % filename)
|
||||||
|
|
||||||
with open(filename, "rb") as f:
|
with open(filename, "rb") as f:
|
||||||
while True:
|
while True:
|
||||||
file_data = f.read(1024)
|
file_data = f.read(1024)
|
||||||
|
|
||||||
if len(file_data) >= 1024:
|
if len(file_data) >= 1024:
|
||||||
|
log.debug("File size greeter 1024 bytes, yield data")
|
||||||
yield file_data
|
yield file_data
|
||||||
|
log.debug("Continue")
|
||||||
else:
|
else:
|
||||||
|
log.debug("File size lower 1024 bytes, yield data")
|
||||||
yield file_data
|
yield file_data
|
||||||
|
log.debug("Break")
|
||||||
break
|
break
|
||||||
|
|
|
@ -10,6 +10,8 @@ from .response import Response
|
||||||
|
|
||||||
MAX_REQLINE = 64 * 1024
|
MAX_REQLINE = 64 * 1024
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class HTTPHandler:
|
class HTTPHandler:
|
||||||
def __init__(self, conn, addr):
|
def __init__(self, conn, addr):
|
||||||
|
@ -35,7 +37,7 @@ class HTTPHandler:
|
||||||
raw = self.read_fb.readline(MAX_REQLINE + 1)
|
raw = self.read_fb.readline(MAX_REQLINE + 1)
|
||||||
|
|
||||||
if len(raw) > MAX_REQLINE:
|
if len(raw) > MAX_REQLINE:
|
||||||
logging.debug("Request line too long")
|
log.debug("Request line too long")
|
||||||
self.conn.send(b"")
|
self.conn.send(b"")
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
return
|
return
|
||||||
|
@ -45,14 +47,15 @@ class HTTPHandler:
|
||||||
|
|
||||||
if len(req_line_splited) != 3:
|
if len(req_line_splited) != 3:
|
||||||
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:
|
else:
|
||||||
logging.debug("Request head too small")
|
log.debug("Request head too small")
|
||||||
self.conn.send(b"")
|
self.conn.send(b"")
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
return
|
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]
|
self.http_type = req_line_splited[0]
|
||||||
else:
|
else:
|
||||||
self.conn.send(b"")
|
self.conn.send(b"")
|
||||||
|
@ -86,7 +89,7 @@ class HTTPHandler:
|
||||||
raw = self.read_fb.readline(MAX_REQLINE + 1)
|
raw = self.read_fb.readline(MAX_REQLINE + 1)
|
||||||
|
|
||||||
if len(raw) > MAX_REQLINE:
|
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.send(b"")
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
return
|
return
|
||||||
|
@ -102,14 +105,18 @@ class HTTPHandler:
|
||||||
else:
|
else:
|
||||||
decoded_data = raw.decode("UTF-8").rstrip("\r\n")
|
decoded_data = raw.decode("UTF-8").rstrip("\r\n")
|
||||||
decoded_data_split = decoded_data.split(":", 1)
|
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):
|
def http_data_handle(self):
|
||||||
"""
|
"""
|
||||||
Chain of receive data partitions HTTP request
|
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)
|
raw = self.read_fb.readline(1024)
|
||||||
|
|
||||||
|
@ -123,11 +130,11 @@ class HTTPHandler:
|
||||||
raw = self.read_fb.readline(1024)
|
raw = self.read_fb.readline(1024)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logging.debug(self.http_type)
|
log.debug("Type of request: %s" % self.http_type)
|
||||||
logging.debug(self.http_address)
|
log.debug("Requested address: %s" % self.http_address)
|
||||||
logging.debug(self.http_headers)
|
log.debug("Request headers: %s" % self.http_headers)
|
||||||
logging.debug(self.http_get_request)
|
log.debug("Request in GET after ?: %s" % self.http_get_request)
|
||||||
logging.debug(self.data)
|
log.debug("Data: %s" % self.data)
|
||||||
|
|
||||||
self.send_form_data()
|
self.send_form_data()
|
||||||
|
|
||||||
|
@ -168,7 +175,7 @@ class HTTPHandler:
|
||||||
self.write_fb.flush()
|
self.write_fb.flush()
|
||||||
|
|
||||||
else:
|
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")
|
r = Response(status_code=404, data=b"Address configured on server, but type not allowed URL type in URLs list")
|
||||||
|
|
||||||
for i in r:
|
for i in r:
|
||||||
|
@ -187,34 +194,7 @@ class HTTPHandler:
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
|
|
||||||
|
|
||||||
def start():
|
def start_http_server():
|
||||||
logging.basicConfig(filename="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)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as main_server_socket:
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as main_server_socket:
|
||||||
main_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
|
main_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
|
||||||
|
@ -223,11 +203,11 @@ def start():
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
conn, addr = main_server_socket.accept()
|
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 = threading.Thread(target=HTTPHandler, args=(conn, addr,))
|
||||||
thr_serv_conn.run()
|
thr_serv_conn.run()
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
logging.info("Server get keyboard interrupt. Initialize server to stop")
|
log.info("Server get keyboard interrupt. Initialize server to stop")
|
||||||
logging.info("==================== End of log ====================")
|
log.info("==================== End of log ====================")
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
STATUS_CODE = {
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
STATUS_BY_CODE = {
|
||||||
200: "OK",
|
200: "OK",
|
||||||
404: "Not Found",
|
404: "Not Found",
|
||||||
500: "Internal Server Error",
|
500: "Internal Server Error",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Response:
|
class Response:
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self
|
return self
|
||||||
|
@ -16,6 +21,8 @@ class Response:
|
||||||
|
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
if self.first:
|
if self.first:
|
||||||
|
log.debug("First packet generation of 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: close\r\n"
|
||||||
|
@ -23,13 +30,14 @@ class Response:
|
||||||
resp += "{}: {}\r\n".format(key, val)
|
resp += "{}: {}\r\n".format(key, val)
|
||||||
resp += "\r\n"
|
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")
|
resp = resp.encode("UTF-8")
|
||||||
|
|
||||||
if type(self.data) == bytes:
|
if type(self.data) == bytes:
|
||||||
resp += self.data
|
resp += self.data
|
||||||
|
|
||||||
self.first = False
|
self.first = False
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -37,6 +45,7 @@ class Response:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
elif hasattr(self.data, "__iter__"):
|
elif hasattr(self.data, "__iter__"):
|
||||||
|
log.debug("Data is iterator, just generate next part")
|
||||||
try:
|
try:
|
||||||
return next(self.data)
|
return next(self.data)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
|
|
@ -1,7 +1,22 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def path(path="/", _type="static-file", link="index.html", methods=("GET",)):
|
def path(path="/", _type="static-file", link="index.html", methods=("GET",)):
|
||||||
|
log.debug("Start generate path for %s address" % path)
|
||||||
|
|
||||||
if _type == "static-file":
|
if _type == "static-file":
|
||||||
|
log.info("Path %s is %s and linked %s for methods %s" % (path, _type, link, methods))
|
||||||
return {path: (methods, _type, "static/{}".format(link))}
|
return {path: (methods, _type, "static/{}".format(link))}
|
||||||
if _type == "redirect":
|
|
||||||
|
elif _type == "redirect":
|
||||||
|
log.info("Path %s is %s and linked %s for methods %s" % (path, _type, link, methods))
|
||||||
return {path: (methods, _type, link)}
|
return {path: (methods, _type, link)}
|
||||||
|
|
||||||
elif _type == "function":
|
elif _type == "function":
|
||||||
|
log.info("Path %s is %s and linked %s for methods %s" % (path, _type, link, methods))
|
||||||
return {path: (methods, _type, link)}
|
return {path: (methods, _type, link)}
|
||||||
|
else:
|
||||||
|
log.error("Path %s is %s but it type is unknown" % (path, _type))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
<title>CatNet static file</title>
|
<title>CatNet static file</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>CatNet Template</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Template has been loaded</h1>
|
|
||||||
<p>{template_data}</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in a new issue