Rabbit Remote Control
0.1.0-bate16
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
QString szHandler = mgr.getDefaultHandlerForProtocol(url.scheme());
33
if
(szHandler.isEmpty()) {
34
qCritical(log) <<
"Don't find handler"
<< url.scheme();
35
return
;
36
}
37
szHandler = szHandler.section(
' '
, 0, 0).trimmed();
38
int
nRet = QMessageBox::question(
39
nullptr
, url.scheme(),
40
tr(
"Use the %1 to open %2"
)
41
.arg(szHandler)
42
.arg(url.toString()),
43
QMessageBox::Yes|QMessageBox::No,
44
QMessageBox::No);
45
if
(QMessageBox::Yes == nRet) {
46
// 方法1:使用 QDesktopServices 打开(会触发系统默认处理)
47
QDesktopServices::openUrl(url);
48
49
// 方法2:直接重定向到外部(如果需要)
50
// 注意:这不会在 WebView 中显示,而是打开外部应用
51
}
52
53
QByteArray emptyData = generateResponsePage(url, QMessageBox::Yes == nRet);
54
QBuffer *buffer =
new
QBuffer();
55
buffer->setData(emptyData);
56
buffer->open(QIODevice::ReadOnly);
57
request->reply(
"text/html"
, buffer);
58
}
59
60
bool
CSystemProtocolHandler::isUrlSafe(
const
QUrl &url)
const
61
{
62
// 安全检查:防止 file:// 等危险协议
63
QString scheme = url.scheme();
64
if
(scheme ==
"file"
|| scheme ==
"data"
) {
65
if
(url.isLocalFile()) {
66
QFileInfo fi(url.toLocalFile());
67
if
(fi.suffix() ==
"rrc"
)
68
return
true
;
69
else
70
return
false
;
71
}
72
// 只允许特定路径
73
if
(scheme ==
"file"
&& !url.path().startsWith(
"/tmp/"
)) {
74
return
false
;
75
}
76
return
false
;
77
}
78
79
// 检查是否包含可疑字符
80
QString urlStr = url.toString();
81
if
(urlStr.contains(
".."
) || urlStr.contains(
"%2e%2e"
)) {
82
return
false
;
83
}
84
85
return
true
;
86
}
87
88
QByteArray CSystemProtocolHandler::generateResponsePage(
const
QUrl &url,
bool
opened)
const
89
{
90
QString html = R
"(
91
<html>
92
<head>
93
<meta charset="UTF-8">
94
<style>
95
body { font-family: Arial, sans-serif; margin: 50px; }
96
.success { color: #4CAF50; }
97
.error { color: #f44336; }
98
</style>
99
</head>
100
<body>
101
<h2>%1</h2>
102
<p>%2: %3</p>
103
<p>URL: %4</p>
104
<p class="%5">%6: %7</p>
105
<p><a href='javascript:history.back()'>%8</a></p>
106
</body>
107
</html>
108
)";
109
110
html = html.arg(tr(
"Process protocol"
))
111
.arg(tr(
"Protocol"
))
112
.arg(url.scheme())
113
.arg(url.toString().toHtmlEscaped())
114
.arg(opened ?
"success"
:
"error"
)
115
.arg(tr(
"Status"
))
116
.arg(opened ? tr(
"External application opened"
) : tr(
"Cancel Open"
))
117
.arg(tr(
"Go back"
));
118
119
return
html.toUtf8();
120
}
CProtocolManager
Definition
ProtocolManager.h:10
CSystemProtocolHandler
Definition
SystemProtocolHandler.h:8
Author: Kang Lin (kl222@126.com)
Copyright (c) Kang Lin Studios All Rights Reserved