Merge master with dev
This commit is contained in:
commit
c7413887cc
7 changed files with 91 additions and 56 deletions
16
config.py
16
config.py
|
@ -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)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>CatNet static file</title>
|
||||
</head>
|
||||
<body>
|
||||
|
|
22
main.py
22
main.py
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ====================")
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in a new issue