forked from skyhhjmk/windblog
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDebugToolkit.php
More file actions
124 lines (108 loc) · 4.49 KB
/
Copy pathDebugToolkit.php
File metadata and controls
124 lines (108 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace app\middleware;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
/**
* Class DebugToolkit
*/
class DebugToolkit implements MiddlewareInterface
{
public function process(Request $request, callable $handler): Response
{
$start = microtime(true);
/** @var Response $response */
$response = $handler($request);
// 权限策略:必须存在 Header X-Debug-Toolkit=1
$hasHeader = $request->header('x-debug-toolkit') === '1' || $request->header('X-Debug-Toolkit') === '1';
$hasQuery = !empty($request->get('debug'));
$hasCookie = $request->cookie('debug_toolkit') === '1';
if (!$hasHeader) {
return $response;
}
// 安全注入:仅当响应体可用且包含 </body>,且未已注入
$content = $response->rawBody();
if (!is_string($content)) {
return $response;
}
if (stripos($content, '</body>') === false) {
return $response;
}
if (str_contains($content, '<!-- Debug Toolkit Start -->')) {
return $response;
}
// 采集数据(轻量)
$end = microtime(true);
$timingTotalMs = round(($end - $start) * 1000, 2);
$data = [
'trigger' => [
'header' => $hasHeader,
'query' => $hasQuery,
'cookie' => $hasCookie,
],
'request' => [
'method' => $request->method(),
'uri' => $request->uri(),
'path' => $request->path(),
'query' => $request->get(),
'cookies' => $request->cookie(),
// 头部仅保留常见字段,避免过大
'headers' => [
'host' => $request->header('host'),
'user-agent' => $request->header('user-agent'),
'accept' => $request->header('accept'),
'content-type' => $request->header('content-type'),
'x-requested-with' => $request->header('x-requested-with'),
],
],
'response' => [
// Webman Response 可能不同实现,这里只提供精要占位
'status' => method_exists($response, 'getStatusCode') ? $response->getStatusCode() : null,
'headers' => method_exists($response, 'getHeaders') ? $response->getHeaders() : [],
'length' => is_string($content) ? strlen($content) : null,
],
'timing' => [
'total_ms' => $timingTotalMs,
],
'logs' => [
'recent' => [],
'endpoint' => '/api/debug/logs',
'note' => '前端通过 /api/debug/logs 拉取最近N条日志',
],
'sql' => [
'queries' => [],
'note' => '如已接入PDO事件或ORM监听可填充此处;当前为占位',
],
];
// 生成调试工具注入片段
$debugContent = $this->getDebugToolkit($data);
$content = str_replace('</body>', $debugContent . '</body>', $content);
return $response->withBody($content);
}
private function getDebugToolkit(array $data): string
{
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
return <<<HTML
<!-- Debug Toolkit Start -->
<link rel="stylesheet" href="/assets/css/debug.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.0/css/all.min.css" integrity="sha512-DxV+EoADOkOygM4IR9yXP8Sb2qwgidEmeqAEmDKIOfPRQZOWbXCzLC6vjbZyy0vPisbH2SyW27+ddLVCN+OMzQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- Tailwind CDN(按你的选择加载) -->
<script src="https://cdn.tailwindcss.com"></script>
<script>window.__DEBUG_TOOLKIT_DATA = {$json};</script>
<script src="/assets/js/debug.js"></script>
<!-- Debug Toolkit End -->
HTML;
}
}