UndeadDragon
@UndeadDragon
Разработчик ПО на C++, Qt, Python и др.

Почему перестал работать QtNetwork после переноса на другой ПК?

Привет. У меня такой баг, не могу уже пару дней побороть. Короче, программа загружает длл и исполняет код в ней. В случае моего бага это длл содержащая запрос к серверу. Все работало хорошо, пока я не решил протестировать перенос на другой компьютер. Версия Windows там такая же (на виртуалку воткнул), но чистая, с нуля. Когда я перенес, внезапно запрос перестал работать, программа стала возвращать всегда пустой ответ. Я очень удивился, долго гуглил, поставил все подряд: Open SSL, Windows SDK, MS VC++ всех версий, но ничто не помогло, ответ пустой и запрос вообще не уходит до сервера. Я вывел ошибку, и показало "SSL handshake failed". Я не очень понимаю почему, как это исправить и почему работает на старой системе.
Ниже привожу код и логи, полученные с новой системы, где не работает. Подскажите, пожалуйста, в чем дело:
const char *lastError = NULL;
const char *URL_TOKEN = "https://blablabla";
const char *URL_AUTH = "https://blablabla=%1";

#define EXT(code) if (!lastError) qDebug() << lastError; return code;
#define SETLERR(msg) if (!lastError) lastError = msg;

// +
RESULT Run(const char *k, void *p)
{
    qDebug() << __FUNCTION__ ;
    (void*) p;
    // Check args
    if ((void*)k == (void*)0)
    {
        SETLERR("(void*)k == (void*)0) is true; Ошибка - отсутствует ключ");
        EXT(RESULT_WRONGARGS);
    }

    QString key(k);
    if (key.isEmpty())
    {
        SETLERR("Ошибка - ключ пустой");
        EXT(RESULT_WRONGKEY);
    }

    // Start working
    qDebug() << "Before QString reply = PostRequest(key);";
    QString reply = PostRequest(key);
    qDebug() << "After QString reply = PostRequest(key);";

    if (reply.isEmpty())
    {
        SETLERR("Ответ от сервера пустой, это может быть вызвано внутренней "
                "ошибкой PostRequest()");
        EXT(RESULT_UNKNOWN_ERROR);
    }
    else if (reply == "GoodTry!")
    {
        SETLERR("Ответ от сервера \"GoodTry\"");
        EXT(RESULT_WRONGKEY);
    }

    QString token_url(URL_AUTH);
    token_url = token_url.arg(reply);
    bool success = QDesktopServices::openUrl(token_url);
    if (success)
    {
        EXT(RESULT_SUCCESS);
    }
    else
    {
        SETLERR("OpenUrl is false, failure;"
                "Ошибка - открыть страницу не удалось");
        EXT(RESULT_FAILURE);
    }

    SETLERR("Amazing error, nobody knows what there have been");
    EXT(RESULT_UNKNOWN_ERROR);
}

// +
const char *GetPluginName()
{
    return "Portal Biocad";
}

// +
const char *GetLastError()
{
    if (!lastError)
        return "no error";
    return lastError;
}

// +-
bool IsAvailable(const char *key)
{
    (void*) key;

    /*
    if (key.empty()) {
        return 0;
    }
    QString reply = PostRequest("");
    if (reply.isEmpty()) {
        return 0;
    }
    else {
        return 1;
    }//*/

    return true;
}

// +
QString PostRequest(const QString &key)
{
    // setting POST request params
    QUrl params;
    params.addQueryItem("key", key);
    // creating request
    QNetworkRequest request;
    request.setUrl(QString(URL_TOKEN));
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      QVariant("application/x-www-form-urlencoded"));

    // executing request
    QNetworkAccessManager manager;
    QEventLoop wait_reply;

    QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)),
                     &wait_reply, SLOT(quit()));
    QNetworkReply *answer = manager.post(request, params.encodedQuery());

    qDebug() << "Before wait_reply.exec();";
    wait_reply.exec();
    qDebug() << "After wait_reply.exec();";

    if (answer)
    {
        if (answer->error() == QNetworkReply::NoError)
        {
            const int available = answer->bytesAvailable();
            if (available > 0)
            {
                return answer->readAll();
            }
        }
        else
        {
            qDebug() <<  QString("Error: %1 status: %2").arg(
                             answer->errorString(),
                             answer->attribute(
                                 QNetworkRequest::HttpStatusCodeAttribute)
                             .toString());
        }

        qDebug() << "code: " << answer->attribute(
                        QNetworkRequest::
                        HttpStatusCodeAttribute).toString()
                 << " response: " << answer->readAll();
        answer->deleteLater();
    }

    return "";
}


Логи:
Run
Before QString reply = PostRequest(key);
Before wait_reply.exec();
"Error: SSL handshake failed status: "
code: "" response: ""
After wait_reply.exec();
After QString reply = PostRequest(key);
Reply is empty
  • Вопрос задан
  • 3301 просмотр
Пригласить эксперта
Ответы на вопрос 1
@DancingOnWater
Скорее всего проблемы сертефикатом. Мой код в похожей ситуации:

void SpaceTrackConnection::sendReguest(const QString &request) const
{
     QNetworkRequest req(request);
     req.setSslConfiguration(d->m_sslConfiguration);
         req.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/x-www-form-urlencoded"));
         req.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue<QList<QNetworkCookie>>(d->m_cookieList));
         req.setHeader(QNetworkRequest::SetCookieHeader,QVariant::fromValue<QList<QNetworkCookie>>(d->m_cookieList));
    auto reply = d->m_networkAcess->get(req);
     QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(read()));
         QObject::connect(reply, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(errorSlotSSL(const QList<QSslError> &)));
         QObject::connect(reply, SIGNAL(readyRead()), this, SLOT(read()));
         QObject::connect(reply, SIGNAL(finished()), this, SLOT(read()));
}


void SpaceTrackConnection::errorSlotSSL(const QList<QSslError> &erros)
{
    auto sender = static_cast<QNetworkReply*>(this->sender());
    sender->ignoreSslErrors(erros);
    qDebug()<<"ssl errors";
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы