背景

近期将笔记本系统从万年的Windows换成了Ubuntu,想着Linux环境下进行C/C++开发能方便点。因为之前已经玩了两年PT下载,对qBittorrent的使用是刚需。但是,装好qBittorrent并在设置中配置好Web UI后,根据相应端口访问管理界面发现无法正常打开,而是弹出相应html文件的下载框,起初我以为是Edge浏览器的问题,但尝试换到Chrome也于事无补(其实两者都是chromium内核)。遂上Google查询,最终在Arch社区的一个帖子下找到了解决办法,回答者还对qBittorrent的相关源码进行了分析,现翻译如下。

一、问题

——2021年6月27日来自daneel971

我的家庭服务器上运行了配置过Web UI的qbittorrent-nox。从今天开始我发现当我通过任何操作系统(Linux、Win10、Android)的任何浏览器(Firefox、Chrome、chromium)来访问Web UI时,浏览器打开了一个下载框而不是显示Web UI的登录界面。

Paclog没有列出任何关于html、Firefox或bittorrent的信息。

请问谁有解决办法吗?

二、解决办法

——2021年7月31日来自Rogach

我在我的电脑上复现了这个问题,我也进行了debug,我认为这不是qBittorrent的问题。

1.简单来说

你需要从你的~/.local/share/mime/packages/目录下删除x-extension-html相关内容(rm user-extension-*htm*.xml),最后执行命令update-mime-database ~/.local/share/mime

2.详细分析

通过查看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范围是从b8841b34d23de39d,共计三个commit,其中看起来最有可能导致了这个问题的是:更新shared-mime-info2.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也可以正常工作了。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐