Rabbit Remote Control
0.1.0-bate14
Toggle main menu visibility
Loading...
Searching...
No Matches
Plugins
WebBrowser
ProtocolManager
SystemProtocolHandler.cpp
1
#include <QFileInfo>
2
#include <QMessageBox>
3
#include <QUrl>
4
#include <QWebEngineUrlRequestJob>
5
#include <QLoggingCategory>
6
#include <QDesktopServices>
7
#include <QBuffer>
8
#include "ProtocolManager.h"
9
#include "SystemProtocolHandler.h"
10
11
static
Q_LOGGING_CATEGORY(log,
"WebBrowser.SystemProtocolHandler"
)
12
void
CSystemProtocolHandler
::requestStarted(QWebEngineUrlRequestJob *request)
13
{
14
QUrl url = request->requestUrl();
15
qDebug(log) <<
"Intercepting"
<< m_scheme <<
":"
<< url.toString();
16
17
// 检查 URL 是否有效
18
if
(!url.isValid()) {
19
qWarning(log) <<
"Invalid URL:"
<< url;
20
request->fail(QWebEngineUrlRequestJob::UrlInvalid);
21
return
;
22
}
23
24
// 安全验证:防止恶意 URL
25
if
(!isUrlSafe(url)) {
26
qWarning(log) <<
"Blocked potentially unsafe URL:"
<< url;
27
request->fail(QWebEngineUrlRequestJob::UrlInvalid);
28
return
;
29
}
30
31
CProtocolManager
mgr;
32
33
int
nRet = QMessageBox::question(
34
nullptr
, url.scheme(),
35
tr(
"Use the %1 to open %2"
)
36
.arg(mgr.getDefaultHandlerForProtocol(url.scheme()))
37
.arg(url.toString()),
38
QMessageBox::Yes|QMessageBox::No,
39
QMessageBox::No);
40
if
(QMessageBox::Yes == nRet) {
41
// 方法1:使用 QDesktopServices 打开(会触发系统默认处理)
42
QDesktopServices::openUrl(url);
43
44
// 方法2:直接重定向到外部(如果需要)
45
// 注意:这不会在 WebView 中显示,而是打开外部应用
46
}
47
48
QByteArray emptyData = generateResponsePage(url, QMessageBox::Yes == nRet);
49
QBuffer *buffer =
new
QBuffer();
50
buffer->setData(emptyData);
51
buffer->open(QIODevice::ReadOnly);
52
request->reply(
"text/html"
, buffer);
53
}
54
55
bool
CSystemProtocolHandler::isUrlSafe(
const
QUrl &url)
const
56
{
57
// 安全检查:防止 file:// 等危险协议
58
QString scheme = url.scheme();
59
if
(scheme ==
"file"
|| scheme ==
"data"
) {
60
if
(url.isLocalFile()) {
61
QFileInfo fi(url.toLocalFile());
62
if
(fi.suffix() ==
"rrc"
)
63
return
true
;
64
else
65
return
false
;
66
}
67
// 只允许特定路径
68
if
(scheme ==
"file"
&& !url.path().startsWith(
"/tmp/"
)) {
69
return
false
;
70
}
71
return
false
;
72
}
73
74
// 检查是否包含可疑字符
75
QString urlStr = url.toString();
76
if
(urlStr.contains(
".."
) || urlStr.contains(
"%2e%2e"
)) {
77
return
false
;
78
}
79
80
return
true
;
81
}
82
83
QByteArray CSystemProtocolHandler::generateResponsePage(
const
QUrl &url,
bool
opened)
const
84
{
85
QString html = R
"(
86
<html>
87
<head>
88
<meta charset="UTF-8">
89
<style>
90
body { font-family: Arial, sans-serif; margin: 50px; }
91
.success { color: #4CAF50; }
92
.error { color: #f44336; }
93
</style>
94
</head>
95
<body>
96
<h2>协议处理</h2>
97
<p>协议: %1</p>
98
<p>URL: %2</p>
99
<p class="%3">%4: %5</p>
100
<p><a href='javascript:history.back()'>%6</a></p>
101
</body>
102
</html>
103
)";
104
105
html = html.arg(url.scheme())
106
.arg(url.toString().toHtmlEscaped())
107
.arg(opened ?
"success"
:
"error"
)
108
.arg(
"Status"
)
109
.arg(opened ?
"External application opened"
:
"Cancel Open"
)
110
.arg(
"Go back"
);
111
112
return
html.toUtf8();
113
}
CProtocolManager
Definition
ProtocolManager.h:10
CSystemProtocolHandler
Definition
SystemProtocolHandler.h:8
Author: Kang Lin (kl222@126.com)
Copyright (c) Kang Lin Studios All Rights Reserved