近期将笔记本系统从万年的Windows换成了Ubuntu,想着Linux环境下进行C/C++开发能方便点。因为之前已经玩了两年PT下载,对qBittorrent的使用是刚需。但是,装好qBittorrent并在设置中配置好Web UI后,根据相应端口访问管理界面发现无法正常打开,而是弹出相应html文件的下载框,起初我以为是Edge浏览器的问题,但尝试换到Chrome也于事无补(其实两者都是chromium内核)。遂上Google查询,最终在Arch社区的一个帖子下找到了解决办法,回答者还对qBittorrent的相关源码进行了分析,现翻译如下。
我的家庭服务器上运行了配置过Web UI的qbittorrent-nox。从今天开始我发现当我通过任何操作系统(Linux、Win10、Android)的任何浏览器(Firefox、Chrome、chromium)来访问Web UI时,浏览器打开了一个下载框而不是显示Web UI的登录界面。
Paclog没有列出任何关于html、Firefox或bittorrent的信息。
请问谁有解决办法吗?
我在我的电脑上复现了这个问题,我也进行了debug,我认为这不是qBittorrent的问题。
你需要从你的~/.local/share/mime/packages/
目录下删除x-extension-html
相关内容(rm user-extension-*htm*.xml
),最后执行命令update-mime-database ~/.local/share/mime
通过查看qBittorrent的源码我们能发现他们使用了QMimeDatabase
来决定要在Countent-Type头中发送什么(事实上,我对他们自己重新实现了HTTP服务器很感兴趣,我猜这个功能是在各种流行的http库被开发出来之前被实现的)。
下面是一个Qt5小程序,通过它我们能发现对mime类型的检测是不正确的:
// compile with g++ -std=c++14 -fPIC -o test test.cpp -I/usr/include/qt -I/usr/include/qt/QtCore -Wall /usr/lib/libQt5Core.so
#include <QDebug>
#include <QString>
#include <QMimeDatabase>
int main() {
QString path("index.html");
QString data("<!DOCTYPE html><html><body></body></html>");
QMimeType mimeType {QMimeDatabase().mimeTypeForFileNameAndData(path, data.toLatin1())};
qInfo() << mimeType;
}
输出:
QMimeType("application/x-extension-html")
QMimeDatabase
来自qt5-base
包,通过对该包的更新历史进行检查我发现mime类型检测有误是从5.15.2+kde+r203
版本之后开始出现的。这个版本的包其commit范围是从b8841b34
到d23de39d
,共计三个commit,其中看起来最有可能导致了这个问题的是:更新shared-mime-info
到2.1 release
版本,同时调整实现。shared-mime-info
没有包含对x-extension-html
的引用,而且从来也没有这么做过,因此很可能对mime-type
匹配优先级的更改导致了错误的mime类型检测。
通过参考mime-type
相关的文档,我们可以知道mime类型的定义要么在/usr/share/mime/packages/
,要么在~/.local/share/mime/
。前者不包含任何x-extension-html
相关文件,但是对于后者,我发现了文件~/.local/share/mime/packages/user-extension-html.xml
。而且,也有别的几个文件在几乎同一时间被创建。这些文件创建时间在大概一年前,不幸的是,我没发现到底是什么创建了它们。我猜可能是和Wine或者Proton相关的某些东西,因为在那段时间我在Steam上玩过游戏。
通过以上分析,我认为这些文件没啥用,因此可以安全地删除,首先执行命令rm user-extension-*htm*.xml
,然后我们需要重新生成mime数据库,执行命令update-mime-database ~/.local/share/mime
。至此,我们的小程序可以给出正确的输出了:
QMimeType("text/html")
同时qBittorrent的Web UI也可以正常工作了。