Skip to content

Commit edaf540

Browse files
committed
update middleware
1 parent eb04154 commit edaf540

File tree

6 files changed

+100
-68
lines changed

6 files changed

+100
-68
lines changed

domain-driven-design/python-web/src/app.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
from src.interfaces.controllers.order_controller import OrderController
1515
from src.application.services.order_service import OrderService
1616
from src.infrastructure.repository.order_repository_impl import OrderRepositoryImpl as OrderRepository
17-
from src.middleware.logging_middleware import logging_middleware
1817
from src.utils.logging import setup_logging
1918
from src.config.server_config import PORT, LOGGING
2019

20+
log_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), LOGGING['file'])
2121
logging.basicConfig(
2222
level=logging.DEBUG,
2323
format='%(asctime)s - %(levelname)s - %(message)s',
24-
handlers=[logging.StreamHandler()] # 确保日志输出到控制台
24+
handlers=[logging.StreamHandler(), logging.FileHandler(log_file, encoding="utf-8")],
25+
force=True # 强制重新配置
2526
)
2627

2728
#""" 以下修复端口占用问题
@@ -39,14 +40,21 @@ def is_port_in_use(port):
3940
order_service = OrderService(order_repository)
4041
order_controller = OrderController(order_service)
4142

42-
# 初始化日志系统
43-
setup_logging(LOGGING['file'])
44-
4543
# 初始化路由
46-
router = order_routes(order_controller, logging_middleware)
44+
router = order_routes(order_controller)
45+
4746

47+
# MainHandler类,启动HTTP server
48+
class MainHandler(http.server.BaseHTTPRequestHandler):
49+
50+
def log_message(self, format, *args):
51+
logging.info("%s - - [%s] %s\n" %
52+
(self.client_address[0],
53+
self.log_date_time_string(),
54+
format % args))
55+
# 初始化日志系统
56+
setup_logging(log_file)
4857

49-
class MainHandler(http.server.SimpleHTTPRequestHandler):
5058
def handle_request(self):
5159
if self.path == '/favicon.ico':
5260
self.send_response(204)
@@ -80,18 +88,17 @@ def handle_request(self):
8088
return
8189

8290
# 处理其他 API 路由
83-
middleware, handler = router.match_route(method, path)
84-
logging.debug(f"Route match result: {middleware}, {handler}")
91+
handler = router.match_route(method, path)
92+
logging.debug(f"Route match result: Handler: {handler}")
8593

8694
if not handler:
8795
logging.warning(f"No matching route found for {method} {path}")
8896
self.send_error(404, "Not Found")
8997
return
9098

9199
try:
92-
if middleware:
93-
middleware(self) # 执行中间件
94-
handler(self) # 调用处理函数,传递 request 和 response
100+
# 调用包装后的处理函数,将 self 同时作为 req 和 resp 传递
101+
handler(self, self)
95102
except Exception as e:
96103
logging.error(f"Error handling request: {e}")
97104
self.send_error(500, "Internal Server Error")
@@ -108,6 +115,7 @@ def do_PUT(self):
108115
def do_DELETE(self):
109116
self.handle_request()
110117

118+
111119
def run_server():
112120
with socketserver.TCPServer(("", PORT), MainHandler) as httpd:
113121
logging.info(f"Starting server on :{PORT} successfully.")

domain-driven-design/python-web/src/interfaces/routes/order_routes.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
# -*- coding: utf-8 -*-
22
import logging
33
from src.interfaces.routes.router import create_router
4+
from src.middleware.logging_middleware import logging_middleware
5+
from src.middleware.auth_middleware import auth_middleware
46

57
api_prefix = "/api"
68

79
# 订单路由设置函数
8-
def order_routes(order_controller, logging_middleware):
10+
def order_routes(order_controller):
911
if order_controller is None:
1012
raise ValueError("order_controller cannot be None")
11-
if logging_middleware is None:
12-
raise ValueError("logging_middleware cannot be None")
1313

1414
router = create_router()
1515

1616
# 注册路由
1717
router.post(
1818
api_prefix + '/orders',
1919
logging_middleware,
20+
auth_middleware,
2021
order_controller.create_order
2122
)
2223
logging.debug("Registered route: POST /api/orders")
@@ -38,13 +39,15 @@ def order_routes(order_controller, logging_middleware):
3839
router.put(
3940
api_prefix + '/orders/:id',
4041
logging_middleware,
42+
auth_middleware,
4143
order_controller.update_order
4244
)
4345
logging.debug("Registered route: PUT /api/orders/:id")
4446

4547
router.delete(
4648
api_prefix + '/orders/:id',
4749
logging_middleware,
50+
auth_middleware,
4851
order_controller.delete_order
4952
)
5053
logging.debug("Registered route: DELETE /api/orders/:id")

domain-driven-design/python-web/src/interfaces/routes/router.py

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# -*- coding: utf-8 -*-
2-
# 自定义路由类
32
import logging
43
import re
54

6-
5+
# 自定义路由工具
76
class Router:
87
def __init__(self):
98
self.routes = {
@@ -13,41 +12,57 @@ def __init__(self):
1312
'DELETE': []
1413
}
1514

16-
def add_route(self, method, path, middleware, handler):
17-
self.routes[method].append((path, middleware, handler))
15+
def add_route(self, method, path, *handlers):
16+
if not handlers:
17+
raise ValueError("必须至少提供一个处理函数")
18+
# 最后一个参数是真正的处理函数
19+
handler = handlers[-1]
20+
# 前面的参数是中间件
21+
middlewares = handlers[:-1]
22+
# 按顺序应用中间件(先提供的中间件最先执行)
23+
for middleware in reversed(middlewares):
24+
handler = middleware(handler)
25+
self.routes[method].append((path, handler))
1826

19-
def get(self, path, middleware, handler):
20-
self.add_route('GET', path, middleware, handler)
27+
def get(self, path, *handlers):
28+
self.add_route('GET', path, *handlers)
2129

22-
def post(self, path, middleware, handler):
23-
self.add_route('POST', path, middleware, handler)
30+
def post(self, path, *handlers):
31+
self.add_route('POST', path, *handlers)
2432

25-
def put(self, path, middleware, handler):
26-
self.add_route('PUT', path, middleware, handler)
33+
def put(self, path, *handlers):
34+
self.add_route('PUT', path, *handlers)
2735

28-
def delete(self, path, middleware, handler):
29-
self.add_route('DELETE', path, middleware, handler)
36+
def delete(self, path, *handlers):
37+
self.add_route('DELETE', path, *handlers)
3038

3139
def match_route(self, method, path):
3240
if method not in self.routes:
33-
return None, None
41+
return None
3442

35-
for route_path, middleware, handler in self.routes[method]:
43+
for route_path, handler in self.routes[method]:
3644
if ':' in route_path:
37-
# 将路径参数替换为正则表达式,并在前后加 `^``$`
45+
# 将路径参数替换为正则表达式,并在前后加上 ^$
3846
pattern = '^' + re.sub(r':(\w+)', r'(?P<\1>[^/]+)', route_path) + '$'
3947
try:
4048
match = re.fullmatch(pattern, path)
4149
if match:
4250
# 提取参数并存储到 request.params
4351
params = match.groupdict()
44-
return middleware, lambda req: setattr(req, 'params', params) or handler(req, req)
52+
# 包装处理函数,先将参数写入 request 对象
53+
def wrapped_handler(req, resp, h=handler, params=params):
54+
setattr(req, 'params', params)
55+
return h(req, resp) # 传入 request 和 response
56+
return wrapped_handler
4557
except re.error as e:
4658
logging.error(f"正则表达式匹配出错: {e}")
4759
elif route_path == path:
48-
return middleware, lambda req: handler(req, req)
60+
# 对于无参数的静态路由,同样包装后调用 h(req, resp)
61+
def wrapped_handler(req, resp, h=handler):
62+
return h(req, resp)
63+
return wrapped_handler
4964

50-
return None, None
65+
return None
5166

5267
# 创建路由实例的函数
5368
def create_router():
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# -*- coding: utf-8 -*-
2+
import time
3+
import logging
4+
from utils.logging import log_request
5+
def auth_middleware(handler):
6+
def wrapper(request, response):
7+
start_time = time.time()
8+
log_message = f"Auth Checking: {request.command} {request.path}"
9+
logging.info("auth_middleware:", log_message)
10+
log_request(request, start_time)
11+
# 模拟授权检查,这里总是通过
12+
authorized = True
13+
if not authorized:
14+
response.send_response(401)
15+
response.send_header("Content-Type", "text/plain")
16+
response.end_headers()
17+
response.wfile.write(b"Unauthorized")
18+
return
19+
return handler(request, response)
20+
return wrapper
Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,16 @@
11
# -*- coding: utf-8 -*-
22
import time
33
from utils.logging import log_request
4+
import logging
45

5-
def logging_middleware(request, response=None, next_handler=None):
6-
"""
7-
当只传入一个参数时(装饰器调用模式),
8-
将 request 视为处理函数 handler,返回包装后的函数;
9-
10-
当传入三个参数时(中间件链调用模式),
11-
分别认为参数为 request, response, next_handler,
12-
并在调用 next_handler(request) 前后记录日志。
13-
"""
14-
# 装饰器模式:只传入一个参数,request 实际上是 handler
15-
if response is None and next_handler is None:
16-
handler = request
17-
def middleware(req):
18-
start_time = time.time()
19-
res = handler(req)
20-
duration = (time.time() - start_time) * 1000
21-
log_message = f"REQUEST: {req.method} {req.path} took {duration:.2f}ms\n"
22-
print("logging_middleware:", log_message)
23-
log_request(log_message, start_time)
24-
return res
25-
return middleware
6+
import functools
267

27-
# 中间件链模式:传入 request, response, next_handler
28-
start_time = time.time()
29-
result = next_handler(request)
30-
duration = (time.time() - start_time) * 1000
31-
log_message = f"REQUEST: {request.method} {request.path} took {duration:.2f}ms\n"
32-
print("logging_middleware:", log_message)
33-
log_request(log_message, start_time)
34-
return result
8+
def logging_middleware(handler):
9+
@functools.wraps(handler)
10+
def wrapper(self, *args, **kwargs):
11+
start_time = time.time()
12+
log_message = f"REQUEST recoder: {self.command} {self.path}"
13+
logging.info(f"logging_middleware: {log_message}")
14+
log_request(self, start_time)
15+
return handler(self, *args, **kwargs)
16+
return wrapper

domain-driven-design/python-web/src/utils/logging.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: utf-8 -*-
22
import os
33
import time
4+
from src.config.server_config import LOGGING
45

56
# 全局变量,用于存储日志文件路径
67
log_file_path = None
@@ -33,9 +34,12 @@ def log_error(message):
3334

3435
# 将日志消息写入文件
3536
def log_to_file(message):
36-
global log_file_path
37-
if log_file_path:
38-
with open(log_file_path, 'a', encoding='utf-8') as log_file:
39-
log_file.write(message)
40-
else:
41-
print("日志文件路径未初始化,无法写入日志。")
37+
print('log_to_file:', message)
38+
# global log_file_path
39+
# log_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), LOGGING['file'])
40+
# print('log_to_file:', log_file_path)
41+
# if log_file_path:
42+
# with open(log_file_path, 'a', encoding='utf-8') as log_file:
43+
# log_file.write(message)
44+
# else:
45+
# print("日志文件路径未初始化,无法写入日志。")

0 commit comments

Comments
 (0)