Add functional to send static files

Add
- internal project file iterator function
- path function to locate user files (first allocate as static-files)
- primitive HTML page files for demonstrate server functional

Change
- Response class as iterator
- code for send response to client
This commit is contained in:
Иван Солнцев 2024-02-25 01:42:17 +03:00
parent 742d62aa71
commit 887e8da01b
8 changed files with 107 additions and 25 deletions

0
__init__.py Normal file
View file

View file

@ -1,5 +1,13 @@
from server.url import path
SETUP = {
"server": {
"port": 8080,
}
}
urls = [
path("/", "static-file", "index.html"),
path("/template", "template", "index.html")
]

7
main.py Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/python3
from server.main import start
if __name__ == "__main__":
start()

10
server/file_read.py Normal file
View file

@ -0,0 +1,10 @@
def fileiter(filename):
with open(filename, "rb") as f:
while True:
file_data = f.read(1024)
if len(file_data) >= 1024:
yield file_data
else:
yield file_data
break

81
__main__.py → server/main.py Executable file → Normal file
View file

@ -1,11 +1,11 @@
#!/usr/bin/python3.12
import threading
import socket
import logging
import config
from .file_read import fileiter
MAX_REQLINE = 64 * 1024
@ -17,24 +17,42 @@ STATUS_CODE = {
class Response:
def __iter__(self):
return self
def __init__(self, status_code=200, additional_headers={}, data=None):
self.status_code = status_code
self.additional_headers = additional_headers
self.data = data
self.first = True
def get(self):
resp = f"HTTP/1.1 {self.status_code} {STATUS_CODE[self.status_code]}\r\n"
resp += "Server: cnserv\r\n"
resp += "Connection: close\r\n"
resp += "\r\n"
def __next__(self):
if self.first:
resp = "HTTP/1.1 {} {}\r\n"
resp += "Server: cnserv\r\n"
resp += "Connection: close\r\n"
for key, val in self.additional_headers.items():
resp += "{}: {}\r\n".format(key, val)
resp += "\r\n"
resp = resp.encode("UTF-8")
resp = resp.format(self.status_code, STATUS_CODE[self.status_code])
resp = resp.encode("UTF-8")
if self.data:
resp += self.data
if type(self.data) == bytes:
resp += self.data
return resp
self.first = False
return resp
else:
if type(self.data) == bytes:
raise StopIteration
elif hasattr(self.data, "__iter__"):
try:
return next(self.data)
except StopIteration:
raise StopIteration
class HTTPHandler:
http_type = ""
@ -124,29 +142,42 @@ class HTTPHandler:
self.send_form_data()
def send_form_data(self):
if self.http_type == "GET":
if self.http_address == "/":
r = Response(data=b"Tested!")
self.write_fb.write(r.get())
found = False
elif self.http_address == "/server-status":
form_data = "{\"server-name\": \"cnserv\", \"state\": \"running\"}"
r = Response(data=form_data.encode("UTF-8"))
self.write_fb.write(r.get())
for elem in config.urls:
if self.http_address in elem.keys():
url_metadata = elem[self.http_address]
else:
form_data = "Not found!"
r = Response(status_code=404, data=form_data.encode("UTF-8"))
self.write_fb.write(r.get())
if self.http_type in url_metadata[0]:
found = True
self.write_fb.flush()
if url_metadata[1] == "static-file":
r = Response(data=fileiter(url_metadata[2]))
for i in r:
self.write_fb.write(i)
self.write_fb.flush()
else:
logging.warning("Address configured on server, but not allowed URL type in URLs list")
r = Response(status_code=404, data=b"Address configured on server, but not allowed URL type in URLs list")
for i in r:
self.write_fb.write(i)
self.write_fb.flush()
if not found:
r = Response(status_code=404, data=b"Not found!")
for i in r:
self.write_fb.write(i)
self.write_fb.flush()
self.write_fb.close()
self.read_fb.close()
self.conn.close()
if __name__ == "__main__":
def start():
logging.basicConfig(filename="main.log", filemode="a", encoding="UTF-8",
level=logging.DEBUG, format="[%(asctime)s][%(levelname)s] %(message)s")

6
server/url.py Normal file
View file

@ -0,0 +1,6 @@
def path(path="/", _type="static-file", _file="index.html", methods=("GET",)):
if _type == "static-file":
return {path: (methods, _type, "static/{}".format(_file))}
elif _type == "template":
return {path: (methods, _type, "template/{}".format(_file))}

10
static/index.html Normal file
View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>CatNet static file</title>
</head>
<body>
<h1>Static file has been loaded</h1>
<p>Static data</p>
</body>
</html>

10
template/index.html Normal file
View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>CatNet Template</title>
</head>
<body>
<h1>Template has been loaded</h1>
<p>{template_data}</p>
</body>
</html>