PDA

View Full Version : SSL JSON in Qt 4.5.3 + MinGW 3.81



Mr_Cloud
24th June 2015, 02:40
Hello everyone,

I'm trying to make a quick program to retrieve buttcoin price from btc-e in json format, but I'm not actually receiving anything in the QNetworkReply. I think it's due to SSL (Heartbleed) updates that I don't have, but I'm not quite sure. Here's my code:




#include <QtGui/QMainWindow>
#include <QUrl>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QSslConfiguration>
#include <QNetworkProxy>

//in constructor
QNetworkAccessManager *nwam = new QNetworkAccessManager();
connect(nwam,SIGNAL(finished(QNetworkReply*)),this ,SLOT(rfinish(QNetworkReply*)));

void mainWindow::pbSendClicked(){
QUrl url("https://btc-e.com/api/3/ticker/btc_usd");
QNetworkRequest request;
request.setUrl(url);

QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setProtocol(QSsl::TlsV1);
request.setSslConfiguration(config);

nwam->get(request);
}

void hcode::rfinish(QNetworkReply *r){
QString herp=QString::fromUtf8(r->readAll());
//debug
cout << "reply: " << herp.toStdString().c_str() << endl;
}



The herp string is empty when I send the query. I have libeay32.dll and ssleay32.dll in the same folder as the exe. What's missing?


Thanks in advance.


Mr_Cloud

anda_skoa
24th June 2015, 09:09
What have you tried so far?

A non https site?
Not forcing a specific protocol?
Connected to the reply's sslErrors() signal?
Checked for any runtime log/warning output?

Cheers,
_

Mr_Cloud
24th June 2015, 14:40
Hi Anda,

>non-https
Yes, it works

>not forcing specific protocol
If I don't force a protocol, reply is blank; if I force TLS, QList<QSslError> has two entries, both being "No error" for https://btc-e.com

>connected to sslErrors()
Thanks for the tip; see previous

>check for any runtime warning output
If I launch from Qt Creator, I don't have any errors; program exits with return code 0.

anda_skoa
24th June 2015, 15:56
So sslErrors gets emitted, but the list only contains "no error" entries?
Sounds strange. Both the enum and the string value?

Does the network reply error give you any hint?
Also check for the case of not forcing a protocol.

Cheers,
_

Mr_Cloud
26th June 2015, 14:26
Thanks for your replies, anda_skoa. I assume that by enum you mean the number of errors? In which case it'd agree, it's 2. Forcing SSLv3 or SSLv2 has identical effect to not forcing protocol: Blank reply. Forcing TLS gives the strange SSL errors. Can confirm again that http:// returns index.html of a page just fine, including this one's!

Here's the code I'm using:


mw.h


#ifndef MW_H
#define MW_H

#include <QtGui/QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QSslError>
#include <QSslConfiguration>
#include <QUrl>
#include <fstream>

namespace Ui
{
class mw;
}

class mw : public QMainWindow
{
Q_OBJECT

public:
mw(QWidget *parent = 0);
~mw();

public slots:
void rfinish(QNetworkReply *);
void refresh();
void errors(QNetworkReply *,QList<QSslError>);

private:
Ui::mw *ui;
QNetworkAccessManager *nwam;
};

#endif // MW_H



mw.cpp


#include "mw.h"
#include "ui_mw.h"

using namespace std;

mw::mw(QWidget *parent)
: QMainWindow(parent), ui(new Ui::mw)
{
ui->setupUi(this);
nwam=new QNetworkAccessManager();
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(refresh())) ;
connect(nwam,SIGNAL(finished(QNetworkReply*)),this ,SLOT(rfinish(QNetworkReply*)));
connect(nwam,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),this,SLOT(errors(QNetworkReply*,QList<QSslError>)));
}

void mw::refresh(){
QUrl url("https://www.btc-e.com/api/3/ticker/btc_usd");
QNetworkRequest request;
request.setUrl(url);

QSslConfiguration config = QSslConfiguration::defaultConfiguration();
// config.setProtocol(QSsl::TlsV1);
request.setSslConfiguration(config);

nwam->get(request);
ui->statusBar->showMessage("Updating...",0);
}

void mw::rfinish(QNetworkReply *r){
QString reply=QString::fromUtf8(r->readAll());
ofstream file;
file.open("debug.txt");
file << reply.toStdString().c_str() << endl;
file.close();
ui->statusBar->showMessage("reply received",3000);
}

void mw::errors(QNetworkReply *r,QList<QSslError> errList){
ofstream file;
file.open("debugErr.txt");
file << errList.size() << endl;
for (int i=0;i<errList.size();i++) file << errList[i].errorString().toStdString().c_str() << endl;
file.close();
ui->statusBar->showMessage("SSL errors",3000);
}

mw::~mw()
{
delete ui;
}



main.cpp (default


#include <QtGui/QApplication>
#include "mw.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
mw w;
w.show();
return a.exec();
}

.pro file has QT += network added
.ui file has a push button called pushButton.


Any ideas?

Thanks in advance.

anda_skoa
26th June 2015, 14:55
Thanks for your replies, anda_skoa. I assume that by enum you mean the number of errors?

No, I meant the value returned by the error() method, the one that returns an error code, one of a set of enum values.

Maybe also check r->error() and r->errorString() in the slot connected to finish().

Another thing you can try, just to see if it has any affect, call ignoreSslErrors() on the reply object right after it gets returns from nwam->get().

Cheers,
_

Mr_Cloud
26th June 2015, 15:33
Ah yes. Ok enum was 0 for both "No error" entries when forcing TLS.

I outputted the error() and errorString() in rfinish() [edit: when not forcing TLS or SSL] and we're onto something! Enum 6, SSL handshake failed

Added after 24 minutes:

Update: Your solution worked. Putting r->ignoreSslErrors(); in the mw::errors() function did it. Thanks a lot mate!


Regards,
Mr_Cloud