summaryrefslogtreecommitdiff
path: root/day7
diff options
context:
space:
mode:
Diffstat (limited to 'day7')
-rw-r--r--day7/db/cookies.dbbin16384 -> 16384 bytes
-rw-r--r--day7/http_handler.py33
-rw-r--r--day7/router.py33
-rw-r--r--day7/templater.py6
-rw-r--r--day7/utils.py8
5 files changed, 79 insertions, 1 deletions
diff --git a/day7/db/cookies.db b/day7/db/cookies.db
index 89b0f61..d2ece8b 100644
--- a/day7/db/cookies.db
+++ b/day7/db/cookies.db
Binary files differ
diff --git a/day7/http_handler.py b/day7/http_handler.py
index 8344d7f..67769d4 100644
--- a/day7/http_handler.py
+++ b/day7/http_handler.py
@@ -17,6 +17,12 @@ logging.basicConfig(filename=db.get_config_entry('log_path'), level=logging.INFO
def log_requests(func):
+ """
+ *Используется как декоратор.*
+
+ Логирует в файл все запросы, приходящие в функцию `process_request`.
+ """
+
def wrapper(address, request, *args, **kwargs):
response = func(*args, **kwargs)
status = response.split('\n').pop(0).split()[1]
@@ -61,6 +67,13 @@ def log_requests(func):
@log_requests
def process_request(address, request: dict):
+ """
+ *Эта функция логируется с помощью функции* `log_func`
+
+ Проверяется валидность url. Если url валиден,
+ то запрос отправляется на обработку в `backend.py`.
+ """
+
if validate_url(request['url']):
response = run(request)
else:
@@ -70,6 +83,11 @@ def process_request(address, request: dict):
def parse_request(connection):
+ """
+ Принимаем запрос от клиента и тут же парсим заголовки. Если в теле
+ запроса приходят дополнительные данные, то они тоже обрабатываются.
+ """
+
buffer = b''
request = b''
while not request.endswith(b'\r\n\r\n'):
@@ -119,6 +137,13 @@ def get_color():
def handle_connection(connection, address):
+ """
+ Как только к серверу присоединяется какой-то клиент,
+ то это соединение обрабатывается тут. С помощью `get_request`
+ принимаются заголовки и отправляются в `process_request`. Ответ
+ клиенту, полученный из бекэнда, отправляется тут.
+ """
+
try:
request = parse_request(connection)
except ValueError as e:
@@ -137,6 +162,14 @@ def handle_connection(connection, address):
def main():
+ """
+ *Точка входа в программу.*
+
+ Адрес хоста берется из базы данных конфигурации.
+ Запускает сервер по адресу `host:port`. Также тут
+ обрабатывается остановка сервера при нажатии `Ctrl+C`
+ """
+
host = db.get_config_entry('host')
port = db.get_config_entry('port')
diff --git a/day7/router.py b/day7/router.py
index c662592..1e3d5af 100644
--- a/day7/router.py
+++ b/day7/router.py
@@ -6,16 +6,31 @@ from backend import *
class Route:
+ """
+ Представляет из себя класс роута. При инициализации принимает допустимые
+ методы и регулярное выражение. Содержит методы для работы роутинга.
+ Чтобы созданный путь стал обрабатываться необходимо поместить объект Route в таблицу роутера.
+ """
+
def __init__(self, callback, url_format, methods=None):
self.methods = ['GET'] if methods is None else methods
self.url_pattern = re.compile(url_format)
self.callback = callback
- def check_route(self, url, method):
+ def check_route(self, url, method) -> bool:
+ """
+ По указанным URL и методу проверят подходит ли URL под соответсвующие настройки пути.
+ """
+
match = self.url_pattern.fullmatch(url)
return bool(match) and len(match.groups()) == self.url_pattern.groups and method in self.methods
def invoke_callback(self, url, method, query):
+ """
+ Как и `check_route` проверяет параметр на валидность, но если он валиден, то
+ вызывается соответствующий обработчик.
+ """
+
match = self.url_pattern.fullmatch(url)
groups = match.groups()
@@ -28,6 +43,15 @@ class Route:
# url_format - регулярное выражение
def route(url_format, methods=None):
+ """
+ *Используется как декоратор.*
+
+ Указание при каком url и методах в запросе должна вызываться декорируемая функция.
+ При инициализации декоратора надо указать url регулярное выражение и http методы.
+ В декорируемую функцию передаются параметры query из тела запроса и сматченные группы
+ из регулярного выражения `url_format`. Добавляет декорируемые функции в дерево роутера.
+ """
+
if methods is None:
methods = ['GET']
@@ -52,6 +76,13 @@ def route(url_format, methods=None):
def run(request):
+ """
+ Принимает разобранный http-запрос, добавляет новые cookie-данные в базу данных.
+ Ищет в таблице роутера функцию, которую необходимо вызвать для обработки текущего запроса.
+ При нахождении такой функции передает ей все необходимые данные о запросе.
+ Если подходящая функция не была найдена возвращает обработчику статус `404 Not Found`.\
+ """
+
res = NOT_FOUND, NOT_FOUND
for key, value in request['cookies'].items():
diff --git a/day7/templater.py b/day7/templater.py
index ac9416e..2963b7e 100644
--- a/day7/templater.py
+++ b/day7/templater.py
@@ -1,4 +1,10 @@
def render_template(template_name, **kwargs):
+ """
+ Нам постоянно нужно присылать однотипные HTML-странички и для этого пригодится HTML-шаблонизатор,
+ который может по небольшому количеству изменяемых параметров вернуть готовую страницу.
+ При каждом вызове шаблон загружается заново, поэтому нет необходимости перезагружать сервер при изменении шаблона.
+ """
+
with open(f'templates/{template_name}.html') as f:
data = f.read()
diff --git a/day7/utils.py b/day7/utils.py
index c17a02d..b00c5c2 100644
--- a/day7/utils.py
+++ b/day7/utils.py
@@ -15,6 +15,10 @@ FIRST_LINE_PATTERN = re.compile(rf'{"(" + "|".join(HTTP_METHODS) + ")"} {URL_REG
def add_text_headers(status, html: str):
+ """
+ Добавляет заголовки к ответной html-странице
+ """
+
return '\r\n'.join([
status,
f'Date: {strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime())}',
@@ -47,6 +51,10 @@ def parse_cookies(cookies_line: str):
def format_cookies(cookies: dict):
+ """
+ Формирование cookie-строки из переданного словаря.
+ """
+
pairs = []
for key, value in cookies:
pairs.append(f'{key}={value}')