From 887e8da01b22346e8327d7aca1f320584acd85c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=A1=D0=BE=D0=BB=D0=BD=D1=86?= =?UTF-8?q?=D0=B5=D0=B2?= Date: Sun, 25 Feb 2024 01:42:17 +0300 Subject: [PATCH] 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 --- __init__.py | 0 config.py | 8 ++++ main.py | 7 +++ server/file_read.py | 10 +++++ __main__.py => server/main.py | 81 ++++++++++++++++++++++++----------- server/url.py | 6 +++ static/index.html | 10 +++++ template/index.html | 10 +++++ 8 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 __init__.py create mode 100755 main.py create mode 100644 server/file_read.py rename __main__.py => server/main.py (65%) mode change 100755 => 100644 create mode 100644 server/url.py create mode 100644 static/index.html create mode 100644 template/index.html diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/config.py b/config.py index 1a473d3..874c35c 100644 --- a/config.py +++ b/config.py @@ -1,5 +1,13 @@ +from server.url import path + + SETUP = { "server": { "port": 8080, } } + +urls = [ + path("/", "static-file", "index.html"), + path("/template", "template", "index.html") +] diff --git a/main.py b/main.py new file mode 100755 index 0000000..0a5b796 --- /dev/null +++ b/main.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 + +from server.main import start + + +if __name__ == "__main__": + start() diff --git a/server/file_read.py b/server/file_read.py new file mode 100644 index 0000000..8e07b43 --- /dev/null +++ b/server/file_read.py @@ -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 diff --git a/__main__.py b/server/main.py old mode 100755 new mode 100644 similarity index 65% rename from __main__.py rename to server/main.py index 415030f..b7eaf46 --- a/__main__.py +++ b/server/main.py @@ -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") diff --git a/server/url.py b/server/url.py new file mode 100644 index 0000000..a139b6c --- /dev/null +++ b/server/url.py @@ -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))} diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..3fdbdb1 --- /dev/null +++ b/static/index.html @@ -0,0 +1,10 @@ + + + + CatNet static file + + +

Static file has been loaded

+

Static data

+ + diff --git a/template/index.html b/template/index.html new file mode 100644 index 0000000..6f9937e --- /dev/null +++ b/template/index.html @@ -0,0 +1,10 @@ + + + + CatNet Template + + +

Template has been loaded

+

{template_data}

+ +