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:
parent
742d62aa71
commit
887e8da01b
8 changed files with 107 additions and 25 deletions
0
__init__.py
Normal file
0
__init__.py
Normal file
|
@ -1,5 +1,13 @@
|
||||||
|
from server.url import path
|
||||||
|
|
||||||
|
|
||||||
SETUP = {
|
SETUP = {
|
||||||
"server": {
|
"server": {
|
||||||
"port": 8080,
|
"port": 8080,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
path("/", "static-file", "index.html"),
|
||||||
|
path("/template", "template", "index.html")
|
||||||
|
]
|
||||||
|
|
7
main.py
Executable file
7
main.py
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from server.main import start
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
start()
|
10
server/file_read.py
Normal file
10
server/file_read.py
Normal 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
81
__main__.py → server/main.py
Executable file → Normal file
|
@ -1,11 +1,11 @@
|
||||||
#!/usr/bin/python3.12
|
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import socket
|
import socket
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import config
|
import config
|
||||||
|
|
||||||
|
from .file_read import fileiter
|
||||||
|
|
||||||
|
|
||||||
MAX_REQLINE = 64 * 1024
|
MAX_REQLINE = 64 * 1024
|
||||||
|
|
||||||
|
@ -17,24 +17,42 @@ STATUS_CODE = {
|
||||||
|
|
||||||
|
|
||||||
class Response:
|
class Response:
|
||||||
|
def __iter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
def __init__(self, status_code=200, additional_headers={}, data=None):
|
def __init__(self, status_code=200, additional_headers={}, data=None):
|
||||||
self.status_code = status_code
|
self.status_code = status_code
|
||||||
self.additional_headers = additional_headers
|
self.additional_headers = additional_headers
|
||||||
self.data = data
|
self.data = data
|
||||||
|
self.first = True
|
||||||
|
|
||||||
def get(self):
|
def __next__(self):
|
||||||
resp = f"HTTP/1.1 {self.status_code} {STATUS_CODE[self.status_code]}\r\n"
|
if self.first:
|
||||||
resp += "Server: cnserv\r\n"
|
resp = "HTTP/1.1 {} {}\r\n"
|
||||||
resp += "Connection: close\r\n"
|
resp += "Server: cnserv\r\n"
|
||||||
resp += "\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:
|
if type(self.data) == bytes:
|
||||||
resp += self.data
|
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:
|
class HTTPHandler:
|
||||||
http_type = ""
|
http_type = ""
|
||||||
|
@ -124,29 +142,42 @@ class HTTPHandler:
|
||||||
self.send_form_data()
|
self.send_form_data()
|
||||||
|
|
||||||
def send_form_data(self):
|
def send_form_data(self):
|
||||||
if self.http_type == "GET":
|
found = False
|
||||||
if self.http_address == "/":
|
|
||||||
r = Response(data=b"Tested!")
|
|
||||||
self.write_fb.write(r.get())
|
|
||||||
|
|
||||||
elif self.http_address == "/server-status":
|
for elem in config.urls:
|
||||||
form_data = "{\"server-name\": \"cnserv\", \"state\": \"running\"}"
|
if self.http_address in elem.keys():
|
||||||
r = Response(data=form_data.encode("UTF-8"))
|
url_metadata = elem[self.http_address]
|
||||||
self.write_fb.write(r.get())
|
|
||||||
|
|
||||||
else:
|
if self.http_type in url_metadata[0]:
|
||||||
form_data = "Not found!"
|
found = True
|
||||||
r = Response(status_code=404, data=form_data.encode("UTF-8"))
|
|
||||||
self.write_fb.write(r.get())
|
|
||||||
|
|
||||||
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.write_fb.close()
|
||||||
self.read_fb.close()
|
self.read_fb.close()
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def start():
|
||||||
logging.basicConfig(filename="main.log", filemode="a", encoding="UTF-8",
|
logging.basicConfig(filename="main.log", filemode="a", encoding="UTF-8",
|
||||||
level=logging.DEBUG, format="[%(asctime)s][%(levelname)s] %(message)s")
|
level=logging.DEBUG, format="[%(asctime)s][%(levelname)s] %(message)s")
|
||||||
|
|
6
server/url.py
Normal file
6
server/url.py
Normal 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
10
static/index.html
Normal 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
10
template/index.html
Normal 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>
|
Loading…
Reference in a new issue