Rabbit Remote Control 0.1.0-bate14
Loading...
Searching...
No Matches
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
11static Q_LOGGING_CATEGORY(log, "WebBrowser.SystemProtocolHandler")
12void 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
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
55bool 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
83QByteArray 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}