未使用 SSL 时的 QSslSocket 错误

11
我注意到我的两个使用QNetworkRequest从外部加载数据的Qt应用程序都输出了以下内容:
QSslSocket: cannot resolve TLSv1_1_client_method
QSslSocket: cannot resolve TLSv1_2_client_method
QSslSocket: cannot resolve TLSv1_1_server_method
QSslSocket: cannot resolve TLSv1_2_server_method
QSslSocket: cannot resolve SSL_select_next_proto
QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb
QSslSocket: cannot resolve SSL_get0_next_proto_negotiated

这些警告出现的请求示例之一是:
QNetworkReply reply = m_nam->get(QNetworkRequest(QUrl("http://api.openweathermap.org/data/2.5/forecast?id=2835297&mode=xml")));

我相当确定在所有的请求中都没有TLS / SSL参与,所有请求都是普通的HTTP。消息总是在第一个请求被发送后出现,无论URL如何。我没有使用SSL的意图,在代码中也没有提到SSL,这意味着我无法通过编程方式忽略警告。
我的设置是Windows 7 64位,MSVC2013和MinGW,Qt 5.3.2。不管使用哪个编译器,都会出现这些消息。未安装OpenSSL或其他SSL开发库。
问题是:如何摆脱这些警告?
4个回答

18

这些警告只是在解析OpenSSL函数时发出的qWarning()调用。它并不试图调用这些函数,只是在解析它们。调用未解析的函数将导致QSslSocket: cannot call unresolved function ...警告。

警告是由运行时通过调用QNetworkAccessManager::supportedSchemesImplementation() 中的静态QSslSocket::supportsSsl()调用解析OpenSSL函数而引起的。该静态函数返回支持的模式——http和(如果支持SSL)https

对于这些警告,您有几个选项:

  1. 忽略它们,因为您不需要SSL。
  2. 重新编译Qt,并使用-no-openssl参数传递给configure
  3. 提供OpenSSL库,以便函数可以被解析,从而使https可用——这可能不是您想要的。

非常好的解释,谢谢!通常我不喜欢简单地忽略我的程序输出,但在这里看起来是最优解。 - Pavel
3
另外,您还可以通过设置环境变量QT_LOGGING_RULES=qt.network.ssl.warning=false来禁用这些消息。 - Arash Kazemi
虽然这样做不太好,但我最好还是看到警告并忽略它们,而不是隐藏它们,否则以后可能会遇到麻烦,也不知道发生了什么,警告有助于调试。 - Xsmael
我该如何“发布 OpenSSL”? - Zhang

5
可以使用QLoggingCategory::setFilterRules("qt.network.ssl.warning=false");来禁用相关警告信息。

有趣的是,即使有额外的空格也能正常工作。而且它甚至可以完全不用“.warning”。想象一下... - Machta

4
我们偶尔会遇到客户收到非常相似的警告信息,但软件也会崩溃。
QSslSocket: cannot resolve TLSv1_1_client_method
QSslSocket: cannot resolve TLSv1_2_client_method
QSslSocket: cannot resolve TLSv1_1_server_method
QSslSocket: cannot resolve TLSv1_2_server_method
QSslSocket: cannot resolve SSL_select_next_proto
QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb
QSslSocket: cannot resolve SSL_get0_next_proto_negotiated
QMutex: destroying locked mutex

我们发现问题出在程序尝试与客户端计算机上的OpenSSL进行接口交互,虽然我们没有使用SSL。但是,程序找到的OpenSSL版本过旧 (从Qt 5.2开始需要v1.0.0或更高版本)。
解决方案是将OpenSSL动态链接库与应用程序一起分发(大小约为1.65 MB)。另外一个解决方案是重新编译Qt,不包含OpenSSL支持。

1

1
我不使用QSslSocket,因为我没有可以使用它的对象。根本没有使用SSL的意图。我将编辑原始答案以使其更清晰。 - Pavel
我尝试了,但它并没有解决问题:警告仍然出现,程序仍然会冻结。 - Fylhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接