Russian Qt Forum

Qt => Работа с сетью => Тема начата: xintrea от Январь 19, 2016, 23:54



Название: QNetworkAccessManager: скачивание файла по HTTPS не всегда работает
Отправлено: xintrea от Январь 19, 2016, 23:54
Скачивание файла по HTTPS с сайта с самоподписанным сертификатом

Тестирую свой Downloader-виджет, использующий QNetworkAccessManager.

И обратил внимание, что он не может скачать файл по HTTPS с хабрастраджа, например, вот такой:

https://habrastorage.org/files/28a/a2f/a47/28aa2fa47fd5411c8bb615a381fd5e6a.jpg

При этом с ЛОРа по HTTPS скачивает нормально:

https://www.linux.org.ru/gallery/12279480-icon.jpg

wget мне показал, что habrastorage.org имеет самоподписанный сертификат.

Во время работы с любым из вышеприведенных линков, виджет выдает такую ошибку в консоль:

Код:
qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method

Но в случае ЛОРа файл скачивается, а в случае хабрастораджа приходит ткой ответ:

Код:
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

Для отладки я сделал небольшой пример:

http://rghost.ru/8gxlBNYzz (4.3 Кб)

К сожалению, я плохо разбираюсь в этих HTTPS и сертификатах. Подозреваю, что нужно настроить экземпляр QNetworkRequest в методе startNextDownload() путем установки setSslConfiguration().

Может быть поможет тот факт, что, например, в Windows wget с дефолтными настройками не может загрузить файл с хабрастораджа. И помогает опция --no-check-certificate. В Linux wget молча скачивает файл.

Но в методах класса QSslConfiguration не нашел, как устанавливать режим "не проверять SSL сертификат".

Конечная задача - так изменить код примера, чтобы файл с хабрастрораджа начал скачиваться.


Название: Re: QNetworkAccessManager: скачивание файла по HTTPS не всегда работает
Отправлено: Alex Custov от Январь 20, 2016, 00:28
Смотри сигнал sslErrors, там есть ошибка про самоподписанный сертификат, которую и нужно игнорировать. Это классика, примеров полно в сети и в документации.


Название: Re: QNetworkAccessManager: скачивание файла по HTTPS не всегда работает
Отправлено: xintrea от Январь 20, 2016, 01:13
Смотри сигнал sslErrors, там есть ошибка про самоподписанный сертификат, которую и нужно игнорировать. Это классика, примеров полно в сети и в документации.

В документации написано вот что:

Цитировать
void QNetworkAccessManager::sslErrors(QNetworkReply * reply, const QList<QSslError> & errors)

This signal is emitted if the SSL/TLS session encountered errors during the set up, including certificate verification errors. The errors parameter contains the list of errors and reply is the QNetworkReply that is encountering these errors.

To indicate that the errors are not fatal and that the connection should proceed, the QNetworkReply::ignoreSslErrors() function should be called from the slot connected to this signal. If it is not called, the SSL session will be torn down before any data is exchanged (including the URL).

Я связал сигнал-слот так:

Код:
 
void Downloader::setupSignals()
{
 ...
 connect(&webManager, SIGNAL (sslErrors(QNetworkReply *, const QList<QSslError> &)),
          this,        SLOT   (onSslErrors(QNetworkReply *, const QList<QSslError> &)) );
 ...
}

И написал такой слот:

Код:
void Downloader::onSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
{
  reply->ignoreSslErrors();
}

Но файл все равно не скачивается.


Название: Re: QNetworkAccessManager: скачивание файла по HTTPS не всегда работает
Отправлено: Alex Custov от Январь 20, 2016, 01:53
Но файл все равно не скачивается.

Файл редиректится на другой URL. Ты обрабатываешь редирект?


Название: Re: QNetworkAccessManager: скачивание файла по HTTPS не всегда работает
Отправлено: gil9red от Январь 20, 2016, 02:58
/offtop
как то все это сложно...

я конечно, понимаю что есть разница между языками высокого и среднего уровня, но...

Код
Python
C:\Users\ipetrash>python
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from urllib.request import urlretrieve
>>> url = 'https://habrastorage.org/files/28a/a2f/a47/28aa2fa47fd5411c8bb615a381fd5e6a.jpg'
>>> urlretrieve(url, 'C:/img.jpg')
('C:/img.jpg', <http.client.HTTPMessage object at 0x03823810>)
>>>
 
Как то сложно это и мне, кажется, в Qt есть способ проще :)


Название: Re: QNetworkAccessManager: скачивание файла по HTTPS не всегда работает
Отправлено: Bepec от Январь 20, 2016, 08:30
Тут закавыка что есть компонент высокого уровня - QWebView и низкого QNAM, а вот среднего нет. В принципе обработка перенаправления и 90% проблем решится. Да и делается это несколькими строками в коде.


Название: Re: QNetworkAccessManager: скачивание файла по HTTPS не всегда работает
Отправлено: xintrea от Январь 21, 2016, 19:49
Файл редиректится на другой URL. Ты обрабатываешь редирект?

Да, дело было в редиректе.