Compare commits
8 Commits
files.nata
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
9e4c8ba3df | ||
|
9669e09448 | ||
|
cf2fa1f0c0 | ||
|
2661e44e78 | ||
|
33807314f4 | ||
|
81429ec7cb | ||
|
e8d333e399 | ||
|
2793325c50 |
@ -11,7 +11,6 @@ pkgs.mkShell {
|
|||||||
pkgs.python312Packages.pygraphviz
|
pkgs.python312Packages.pygraphviz
|
||||||
pkgs.python312Packages.requests_toolbelt
|
pkgs.python312Packages.requests_toolbelt
|
||||||
pkgs.python312Packages.pyaml
|
pkgs.python312Packages.pyaml
|
||||||
pkgs.python312Packages.pillow
|
|
||||||
];
|
];
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
python src/main.py
|
python src/main.py
|
||||||
|
@ -8,11 +8,11 @@ class Headers:
|
|||||||
def has(self, key: str) -> bool:
|
def has(self, key: str) -> bool:
|
||||||
return key in self.headers.keys()
|
return key in self.headers.keys()
|
||||||
|
|
||||||
def get(self, key: str) -> str | None:
|
def get(self, key: str) -> str:
|
||||||
if self.has(key):
|
if self.has(key):
|
||||||
return self.headers[key]
|
return self.headers[key]
|
||||||
|
|
||||||
return None
|
return ''
|
||||||
|
|
||||||
def add(self, key, value) -> None:
|
def add(self, key, value) -> None:
|
||||||
self.headers[key] = value
|
self.headers[key] = value
|
||||||
|
@ -18,5 +18,5 @@ stream_logger.setFormatter(formatter)
|
|||||||
log.addHandler(file_logger)
|
log.addHandler(file_logger)
|
||||||
log.addHandler(stream_logger)
|
log.addHandler(stream_logger)
|
||||||
|
|
||||||
log.info('log initialized') if not __name__ == 'sludge.src.lib.logger' else ...
|
log.info('log initialized')
|
||||||
|
|
||||||
|
@ -2,7 +2,119 @@ from .response import Response
|
|||||||
|
|
||||||
from typing import Callable, List
|
from typing import Callable, List
|
||||||
|
|
||||||
|
import re
|
||||||
|
import random
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
type Patcher = Callable[[Response, 'Request'], Response]
|
type Patcher = Callable[[Response, 'Request'], Response]
|
||||||
|
|
||||||
|
def find_substring_in_lines(s, substring):
|
||||||
|
for line_index, line in enumerate(s.splitlines()):
|
||||||
|
position = line.find(substring)
|
||||||
|
if position != -1:
|
||||||
|
return line_index
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def extract_words_from_line(line):
|
||||||
|
clean_line = re.sub(r'<[^>]+>', '', line)
|
||||||
|
words = clean_line.split()
|
||||||
|
return words
|
||||||
|
|
||||||
|
def uwuify_text(text):
|
||||||
|
replacements = [
|
||||||
|
(r'r', 'w'),
|
||||||
|
(r'l', 'w'),
|
||||||
|
(r'R', 'W'),
|
||||||
|
(r'L', 'W'),
|
||||||
|
(r'no', 'nyo'),
|
||||||
|
(r'No', 'Nyo'),
|
||||||
|
(r'u', 'uwu'),
|
||||||
|
(r'U', 'Uwu')
|
||||||
|
]
|
||||||
|
|
||||||
|
for pattern, replacement in replacements:
|
||||||
|
text = re.sub(pattern, replacement, text)
|
||||||
|
|
||||||
|
expressions = [" owo", " UwU", " rawr", " >w<"]
|
||||||
|
sentences = text.split('. ')
|
||||||
|
uwuified_sentences = []
|
||||||
|
|
||||||
|
for sentence in sentences:
|
||||||
|
sentence = sentence.strip()
|
||||||
|
if sentence:
|
||||||
|
uwuified_sentences.append(sentence + (random.choice(expressions) if random.randint(0, 5) > 4 else ''))
|
||||||
|
|
||||||
|
return '. '.join(uwuified_sentences)
|
||||||
|
|
||||||
|
def apply_url_params(body, params: str):
|
||||||
|
body = body.decode('utf-8')
|
||||||
|
soup = BeautifulSoup(body, 'html.parser')
|
||||||
|
|
||||||
|
for a_tag in soup.find_all('a', href=True):
|
||||||
|
original_href = a_tag['href']
|
||||||
|
if '?' in original_href:
|
||||||
|
new_href = f"{original_href}&{params}"
|
||||||
|
else:
|
||||||
|
new_href = f"{original_href}?{params}"
|
||||||
|
a_tag['href'] = new_href
|
||||||
|
|
||||||
|
return str(soup)
|
||||||
|
|
||||||
|
def uwuify(body):
|
||||||
|
body = body.decode('utf-8')
|
||||||
|
soup = BeautifulSoup(body, 'html.parser')
|
||||||
|
|
||||||
|
for text in soup.find_all(text=True):
|
||||||
|
if text.parent.name not in ['script', 'style']:
|
||||||
|
original_text = text.string
|
||||||
|
words = extract_words_from_line(original_text)
|
||||||
|
uwuified_words = [uwuify_text(word) for word in words]
|
||||||
|
uwuified_text = ' '.join(uwuified_words)
|
||||||
|
text.replace_with(uwuified_text)
|
||||||
|
|
||||||
|
for a_tag in soup.find_all('a', href=True):
|
||||||
|
original_href = a_tag['href']
|
||||||
|
if '?' in original_href:
|
||||||
|
new_href = f"{original_href}&uwu=true"
|
||||||
|
else:
|
||||||
|
new_href = f"{original_href}?uwu=true"
|
||||||
|
a_tag['href'] = new_href
|
||||||
|
|
||||||
|
|
||||||
|
return str(soup)
|
||||||
|
|
||||||
|
def is_subdict(sub_dict, main_dict):
|
||||||
|
for key, value in sub_dict.items():
|
||||||
|
if key not in main_dict or main_dict[key] != value:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
patchers: List[Patcher] = [
|
patchers: List[Patcher] = [
|
||||||
|
# lambda response, request: Response(
|
||||||
|
# response.code,
|
||||||
|
# response.headers,
|
||||||
|
# "\n".join(line.replace('e', 'a') if index > find_substring_in_lines(response.body.decode('utf-8'), '</head>') else line for index, line in enumerate(response.body.decode('utf-8').splitlines())).encode('utf-8')
|
||||||
|
# ) if 'text/html' in response.headers.values() else response
|
||||||
|
lambda response, request: Response(
|
||||||
|
response.code,
|
||||||
|
response.headers,
|
||||||
|
uwuify(response.body).encode('utf-8')
|
||||||
|
) if 'text/html' in response.headers.values() and is_subdict({'uwu': 'true'}, request.path.params) else response,
|
||||||
|
lambda response, request: Response(
|
||||||
|
response.code,
|
||||||
|
response.headers,
|
||||||
|
re.sub(r'sludge', lambda match: 'sludge' + ' (/slʌd͡ʒ/)' if random.randint(0, 5) < 1 else 'sludge', response.body.decode()).encode('utf-8')
|
||||||
|
) if 'text/html' in response.headers.values() else response,
|
||||||
|
lambda response, request: Response(
|
||||||
|
response.code,
|
||||||
|
response.headers,
|
||||||
|
apply_url_params(response.body.replace(b'<head>', b'<head><style>:root,body,body>main>section{animation:swing 180s infinite ease-in-out;transform-origin:center}@keyframes swing{0%{transform:rotate(0deg)}50%{transform:rotate(-1deg)}100%{transform:rotate(1deg)}}</style>'), 'swing=true').encode('utf-8')
|
||||||
|
) if 'text/html' in response.headers.values() and (random.randint(0, 100) < 1 or is_subdict({'swing': 'true'}, request.path.params)) else response,
|
||||||
|
# spiin!
|
||||||
|
lambda response, request: Response(
|
||||||
|
response.code,
|
||||||
|
response.headers,
|
||||||
|
apply_url_params(response.body.replace(b'<head>', b'<head><style>:root,body,body>main>section,body>main>section>flex-grid>flex-grid-item{animation:spiin 480s infinite ease-in-out;transform-origin:center}@keyframes spiin{0%{transform:rotate(0deg)}50%{transform:rotate(180)}100%{transform:rotate(360deg)}}</style>'), 'spiin=true').encode('utf-8')
|
||||||
|
) if 'text/html' in response.headers.values() and (random.randint(0, 1000) < 1 or is_subdict({'spiin': 'true'}, request.path.params)) else response
|
||||||
]
|
]
|
||||||
|
@ -44,7 +44,9 @@ class Request:
|
|||||||
body_start = request_str.find('\r\n\r\n') + 4
|
body_start = request_str.find('\r\n\r\n') + 4
|
||||||
body = Body(request_bytes[body_start:], headers.get('Content-Type') or 'text/plain')
|
body = Body(request_bytes[body_start:], headers.get('Content-Type') or 'text/plain')
|
||||||
|
|
||||||
log.info(f'received request for {path.path} from {headers.get('X-Real-IP')}')
|
if not 'Nim httpclient' in headers.get('user-agent'):
|
||||||
|
log.info(f'received request for {path.path} from {headers.get('X-Real-IP')}')
|
||||||
|
|
||||||
return cls(method, path, version, headers, body)
|
return cls(method, path, version, headers, body)
|
||||||
|
|
||||||
def match(self):
|
def match(self):
|
||||||
|
@ -4,7 +4,7 @@ from .responsecodes import ResponseCode
|
|||||||
from .logger import log
|
from .logger import log
|
||||||
|
|
||||||
class Response:
|
class Response:
|
||||||
def __init__(self, code: ResponseCode, headers: Dict[str, str] = dict(), body: bytes = b''):
|
def __init__(self, code: ResponseCode, headers: Dict[str, str], body: bytes):
|
||||||
self.code = code
|
self.code = code
|
||||||
self.headers = headers
|
self.headers = headers
|
||||||
self.body = body
|
self.body = body
|
||||||
|
@ -11,12 +11,6 @@ from .patchers import patchers
|
|||||||
from .logger import log
|
from .logger import log
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
import mimetypes
|
|
||||||
import hashlib
|
|
||||||
import base64
|
|
||||||
|
|
||||||
with open('files/secrets', 'r') as f:
|
|
||||||
allowed_secrets = f.read().split('\n')
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Route:
|
class Route:
|
||||||
@ -43,125 +37,151 @@ class Route:
|
|||||||
if not self.method_is_allowed(request.method): return False
|
if not self.method_is_allowed(request.method): return False
|
||||||
return self.matcher(request.path)
|
return self.matcher(request.path)
|
||||||
|
|
||||||
def generate_opengraph_html(file_url):
|
|
||||||
mime_type, _ = mimetypes.guess_type(file_url)
|
|
||||||
file_name = os.path.basename(file_url)
|
|
||||||
|
|
||||||
og_meta = ''
|
|
||||||
twitter_meta = ''
|
|
||||||
|
|
||||||
if mime_type and mime_type.startswith('image/'):
|
|
||||||
content_type = 'image'
|
|
||||||
embed_html = f'<img src="{file_url}" alt="{file_name}" style="max-width: 100%; height: auto;">'
|
|
||||||
og_meta = f'''
|
|
||||||
<meta property="og:image" content="{file_url}" />
|
|
||||||
<meta property="og:url" content="{file_url}" />
|
|
||||||
<meta property="og:image:url" content="{file_url}" />
|
|
||||||
<meta property="og:image:width" content="500" />
|
|
||||||
'''
|
|
||||||
elif mime_type and mime_type.startswith('video/'):
|
|
||||||
content_type = 'video'
|
|
||||||
embed_html = f'<video controls style="max-width: 100%;"><source src="{file_url}" type="{mime_type}">Your browser does not support the video tag.</video>'
|
|
||||||
|
|
||||||
og_meta = f"""
|
|
||||||
<meta property="og:video" content="{file_url}" />
|
|
||||||
<meta property="og:video:url" content="{file_url}" />
|
|
||||||
<meta property="og:video:secure_url" content="{file_url}" />
|
|
||||||
<meta property="og:video:type" content="{mime_type}" />
|
|
||||||
<meta property="og:video:width" content="406" />
|
|
||||||
<meta property="og:video:height" content="720" />
|
|
||||||
"""
|
|
||||||
|
|
||||||
twitter_meta = f"""
|
|
||||||
<meta name="twitter:card" content="player" />
|
|
||||||
<meta name="twitter:title" content="{file_name}" />
|
|
||||||
<meta name="twitter:player" content="{file_url}" />
|
|
||||||
<meta name="twitter:player:width" content="406" />
|
|
||||||
<meta name="twitter:player:height" content="720" />
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
content_type = 'document'
|
|
||||||
embed_html = f'<iframe src="{file_url}" title="{file_name}" style="width: 100%; height: 600px; border: none;"></iframe>'
|
|
||||||
og_meta = ''
|
|
||||||
|
|
||||||
html_content = f"""
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Embed File: {file_name}</title>
|
|
||||||
|
|
||||||
<meta property="og:title" content="{file_name}" />
|
|
||||||
<meta property="og:type" content="{content_type}" />
|
|
||||||
<meta property="og:url" content="{file_url}" />
|
|
||||||
{og_meta}
|
|
||||||
{twitter_meta}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>{file_name}</p>
|
|
||||||
<hr>
|
|
||||||
{embed_html}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
return html_content
|
|
||||||
|
|
||||||
def is_subdict(sub_dict, main_dict):
|
|
||||||
for key, value in sub_dict.items():
|
|
||||||
if key not in main_dict or main_dict[key] != value:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def compute_md5(file_path):
|
|
||||||
md5_hash = hashlib.md5()
|
|
||||||
|
|
||||||
with open(file_path, 'rb') as file:
|
|
||||||
for chunk in iter(lambda: file.read(4096), b""):
|
|
||||||
md5_hash.update(chunk)
|
|
||||||
|
|
||||||
return md5_hash.hexdigest()
|
|
||||||
|
|
||||||
routes = [
|
routes = [
|
||||||
|
Route(
|
||||||
|
lambda request: request.path == '/style.css',
|
||||||
|
[Method.GET],
|
||||||
|
lambda request, *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
*raw_file_contents('./style.css')
|
||||||
|
)
|
||||||
|
),
|
||||||
Route(
|
Route(
|
||||||
lambda request: request.path == '/',
|
lambda request: request.path == '/',
|
||||||
|
[Method.GET, Method.POST],
|
||||||
|
lambda request, *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
{'Content-Type': 'text/html'},
|
||||||
|
((parse_file('./home.html', dict(prev='\\/')).encode('utf-8') if not 'Nim httpclient' in request.headers.get('user-agent') else error_page(200).body) if request.method == Method.GET else (
|
||||||
|
[
|
||||||
|
(lambda form_data: (
|
||||||
|
(lambda time: (
|
||||||
|
f:=open(f'./files/posts-to-homepage/post_{time}.txt', 'w'),
|
||||||
|
f.write(f"<i style='font-family: MapleMonoItalic'>{form_data['name']}</i>@{time}<br>{form_data['text']}<br><br>"),
|
||||||
|
f.close()
|
||||||
|
))(datetime.now().strftime('%Y-%m-%d_%H:%M:%S-%f')[:-3]) if set(form_data.keys()) == set(['text', 'name']) else None
|
||||||
|
))(
|
||||||
|
reduce(
|
||||||
|
lambda acc, d: acc.update(d) or acc,
|
||||||
|
map(lambda key_value_pair: {key_value_pair[0]: remove_html_tags(key_value_pair[1])}, request.body.data.items()),
|
||||||
|
{}
|
||||||
|
)),
|
||||||
|
parse_file('./home.html').encode('utf-8')
|
||||||
|
][1]
|
||||||
|
))
|
||||||
|
) if len(request.body.data) > 0 or request.method != Method.POST else error_page(400)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda path: os.path.isdir('.' + path.path),
|
||||||
|
[Method.GET],
|
||||||
|
lambda request, *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
{'Content-Type': 'text/html'},
|
||||||
|
parse_file('./dir_index.html', dict(path='.' + request.path.path, prev=request.headers.get('Referer').replace('/', '\\/') if request.headers.has('Referer') else '')).encode('utf-8')
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda path: os.path.isfile('.' + path.path) and path.path.startswith('/html/') and (path.path.endswith('.html') or '/thoughts/' in path.path),
|
||||||
|
[Method.GET],
|
||||||
|
lambda request, *_: [print(request.path), Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
{'Content-Type': 'text/html'},
|
||||||
|
parse_file('.' + request.path.path, dict((k, v.replace('\'', '')) for k, v in map(lambda item: (item[0], item[1]), request.path.params.items()))).encode('utf-8')
|
||||||
|
)][-1]
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda path: os.path.isfile('.' + path.path) and (path.path.startswith('/font/') or path.path.startswith('/files/') or path.path.startswith('/.well-known/')),
|
||||||
|
[Method.GET],
|
||||||
|
lambda request, *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
*raw_file_contents('.' + request.path.path)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda request: request.path == '/robots.txt',
|
||||||
|
[Method.GET],
|
||||||
|
lambda *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
*raw_file_contents('./robots.txt')
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda request: request.path == '/status',
|
||||||
[Method.GET],
|
[Method.GET],
|
||||||
lambda *_: Response(
|
lambda *_: Response(
|
||||||
ResponseCode.OK,
|
ResponseCode.OK,
|
||||||
{'Content-Type': 'text/html'},
|
{'Content-Type': 'text/html'},
|
||||||
parse_file('index.html').encode('utf-8')
|
parse('<style>$[cat style.css]</style>$[neofetch | ansi2html]').encode('utf-8')
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Route(
|
Route(
|
||||||
lambda request: [print(os.getcwd(), '.'+request.path, request.params, os.path.isfile('.'+request.path)), os.path.isfile('.'+request.path) and is_subdict({'embed': 'true'}, request.params)][-1],
|
lambda request: request.path == '/stats/is-its-computer-online',
|
||||||
|
[Method.GET],
|
||||||
|
lambda *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
{'Content-Type': 'text/html'},
|
||||||
|
page("online-p", """
|
||||||
|
seconds since last heartbeat message (less than 60: online; less than 120: maybe; more than 120: probably not): $[echo $(( $(date +%s) - $(stat -c %Y ./files/stats/heartbeat) ))]
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda request: request.path == '/stats/what-song-is-it-listening-to',
|
||||||
|
[Method.GET],
|
||||||
|
lambda *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
{'Content-type': 'text/html'},
|
||||||
|
page("song?", """
|
||||||
|
it is listening to $[cat ./files/stats/song] as of $[echo $(( $(date +%s) - $(stat -c %Y ./files/stats/song) ))] seconds ago.
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda request: request.path == '/stats/is-this-server-online',
|
||||||
|
[Method.GET],
|
||||||
|
lambda *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
{'Content-type': 'text/html'},
|
||||||
|
page("server online-p", """
|
||||||
|
I think so.
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda request: request.path == '/stats/what-is-its-servers-uptime',
|
||||||
|
[Method.GET],
|
||||||
|
lambda *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
{'Content-type': 'text/html'},
|
||||||
|
page("uptime", """
|
||||||
|
$[uptime]
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda request: request.path == '/stats/what-vim-buffers-does-it-have-open',
|
||||||
|
[Method.GET],
|
||||||
|
lambda *_: Response(
|
||||||
|
ResponseCode.OK,
|
||||||
|
{'Content-type': 'text/html'},
|
||||||
|
page("vim bufs", """
|
||||||
|
$[cat ./files/stats/vim-bufs | xargs -I% echo %'<br>']
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Route(
|
||||||
|
lambda request: request.path == '/stats',
|
||||||
[Method.GET],
|
[Method.GET],
|
||||||
lambda request, *_: Response(
|
lambda request, *_: Response(
|
||||||
ResponseCode.OK,
|
ResponseCode.OK,
|
||||||
{'Content-Type': 'text/html'},
|
{'Content-Type': 'text/html'},
|
||||||
generate_opengraph_html(f'https://files.natalieee.net{request.path.path}?hash={request.path.params['hash']}').encode('utf-8')
|
parse_file('./html/stats.html', dict(prev=request.headers.get('Referer').replace('/', '\\/') if request.headers.has('Referer') else '')).encode('utf-8')
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Route(
|
Route(
|
||||||
lambda request: [print(os.getcwd(), '.'+request.path, request.params, os.path.isfile('.'+request.path)), os.path.isfile('.'+request.path)][-1],
|
lambda _: True,
|
||||||
[Method.GET],
|
[Method.GET],
|
||||||
lambda request, *_: Response(
|
lambda *_: error_page(404)
|
||||||
ResponseCode.OK,
|
|
||||||
*raw_file_contents('.'+request.path.path)
|
|
||||||
) if request.path.params['hash'] == compute_md5('.'+request.path.path) else error_page(403)
|
|
||||||
),
|
|
||||||
Route(
|
|
||||||
lambda request: request.path == '/post',
|
|
||||||
[Method.POST],
|
|
||||||
lambda request, *_: [print(request), Response(
|
|
||||||
ResponseCode.OK,
|
|
||||||
{'Content-Type': 'text/html'},
|
|
||||||
(lambda f: [f.write(base64.b64decode(request.body.content)), f.close(), f'https://files.natalieee.net/{request.path.params['filename']}?hash={compute_md5(request.path.params['filename'])}'][-1])(open(request.path.params['filename'], 'wb')).encode('utf-8')
|
|
||||||
) if request.path.params['secret'] in allowed_secrets else Response(*error_page(403))][-1]
|
|
||||||
),
|
|
||||||
Route(
|
|
||||||
lambda request: True,
|
|
||||||
[Method.GET],
|
|
||||||
lambda *_: Response(*error_page(404))
|
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ def handle_client(client: socket.socket, addr: Tuple[str, int]) -> None:
|
|||||||
.execute(request, client, addr) \
|
.execute(request, client, addr) \
|
||||||
.send(client)
|
.send(client)
|
||||||
|
|
||||||
log.info('destroy thread')
|
log.debug('destroy thread')
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
http_thread = threading.Thread(name='http', target=serve, args=('0.0.0.0', config['http-port'], handle_client))
|
http_thread = threading.Thread(name='http', target=serve, args=('0.0.0.0', config['http-port'], handle_client))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user