PDA

View Full Version : Program crashes on QNetworkAccessManager::post() request.



ayanda83
13th March 2017, 20:01
Hi there guys, please see my code below. The program crashes on "line 93". The first QNetworkAccessManager::get() request on line 17 works just fine but for some reason the program crashes on the second request on line 93. Please see debug output attached at the bottom of the post.
#include "cpt_rfqs.h"

CPT_RFQs::CPT_RFQs()
{
connect(this, &CPT_RFQs::downloadedSiteData, this, &CPT_RFQs::filterRFQs);
}

void CPT_RFQs::start_downloading()
{
getRFQinfo();
}

void CPT_RFQs::getRFQinfo()
{
rfqNetworkManager = new QNetworkAccessManager(this);
connect(rfqNetworkManager, &QNetworkAccessManager::sslErrors, this, &CPT_RFQs::sslConnectionErrors);
rfqNetworkManager->get(QNetworkRequest(QUrl("http://web1.capetown.gov.za/web1/ProcurementPortal/RFQ/")));

connect(rfqNetworkManager, &QNetworkAccessManager::finished, this, [this](QNetworkReply *homePageReply){
std::string html_buffer = static_cast<std::string>(homePageReply->readAll());
xmlDoc *doc = htmlReadDoc((xmlChar*)html_buffer.c_str(), NULL, NULL, HTML_PARSE_RECOVER|HTML_PARSE_NOERROR|HTML_PARSE_N OWARNING);

xmlNode *node = xmlDocGetRootElement(doc);
xmlpp::Element *root = new xmlpp::Element(node);
auto node_set = root->find("/html/body/div/div/section/form/div/div/table/tbody");

auto containerDiv = dynamic_cast<const xmlpp::Element*>(node_set[0]);
auto elementList = containerDiv->get_children("tr");

QSet<QString> siteDataList;
for(const auto& child : elementList)
{
auto tableDiv = dynamic_cast<xmlpp::Element*>(child);
auto tableRows = tableDiv->get_children("td");

int i = 0;
QStringList dataRecord;
for(const auto& data : tableRows)
{
auto tdElement = dynamic_cast<xmlpp::Element*>(data);
if(i == 7)
{
auto aNode = tdElement->get_children("a");
auto hrefEle = dynamic_cast<const xmlpp::Element*>(aNode.front());
dataRecord.append(QString::fromUtf8(static_cast<std::string>(hrefEle->get_attribute_value("href")).c_str()).simplified());
}
else
{
std::string stdStr = static_cast<std::string>(tdElement->get_child_text()->get_content()).c_str();
dataRecord.append(QString::fromUtf8(stdStr.c_str() ).simplified());
}
i++;
}
QStringList tempContainer;
tempContainer << dataRecord.at(0) << dataRecord.at(6) << dataRecord.at(4) << dataRecord.at(7);
siteDataList.insert(tempContainer.join(","));
dataRecord.clear();
tempContainer.clear();
}
xmlFreeDoc(doc);
emit downloadedSiteData(siteDataList);
homePageReply->deleteLater();
});
}

void CPT_RFQs::filterRFQs(QSet<QString> siteInfo)
{
QFile rfqRegister("/home/ayanda/Desktop/TenderBot_Utilis/cpt/rfq_s/previosly_downloaded_rfq_s.csv");
if(!rfqRegister.open(QFile::ReadWrite | QFile::Text))
qDebug() << "RFQ file failed to open" <<endl;

QTextStream inStream(&rfqRegister);
QSet<QString> registerDataSet;
while(!inStream.atEnd())
registerDataSet.insert(inStream.readLine().simplif ied());

homePageDataList = siteInfo.subtract(registerDataSet);
if(!homePageDataList.isEmpty())
loginToPage();
else
emit noNewRFQs();
}

void CPT_RFQs::loginToPage()
{
QUrlQuery logins;
logins.addQueryItem("UserName","theusername");
logins.addQueryItem("Password","thepassword");

QNetworkRequest request(QUrl("http://web1.capetown.gov.za/web1/ProcurementPortal/Account/LogOn"));
request.setHeader(QNetworkRequest::ContentTypeHead er, "application/x-www-form-urlencoded");
connect(rfqNetworkManager, &QNetworkAccessManager::finished, this, &CPT_RFQs::get_RFQ);
rfqNetworkManager->post(request, logins.toString(QUrl::FullyEncoded).toUtf8());
}

void CPT_RFQs::get_RFQ(QNetworkReply* reply)
{
Q_UNUSED(reply);
foreach(const QString &value, homePageDataList)
qDebug() << value <<endl;
}


#include <QTextStream>
#include <QUrlQuery>
#include <QStringList>
#include <QList>
#include <QDebug>
#include <string>
#include <QSet>
#include "page.h"

class CPT_RFQs : public Page
{
Q_OBJECT
public:
CPT_RFQs();
void start_downloading();

signals:
void downloadedSiteData(QSet<QString>);
void noNewRFQs();
void login();
public slots:
//void sslConnectionErrors(QNetworkReply *reply, const QList<QSslError> &errors);
void getRFQinfo();
void filterRFQs(QSet<QString>);
void loginToPage();
void get_RFQ(QNetworkReply*);

private:
QSet<QString> homePageDataList;
QNetworkAccessManager *rfqNetworkManager;
};

#endif // CPT_RFQS_H

12384

anda_skoa
14th March 2017, 09:53
The screenshot and your description don't match.

The screenshot says line 27, your comment says line 93.

Cheers,
_

ayanda83
14th March 2017, 10:03
thank you for your response anda_skoa. I'm sorry that was my mistake, the line is "27" as per the screenshot, it's just that when I comment out line 93, the program doesn't crash but of course in that case it does work as required.

ayanda83
14th March 2017, 16:15
I was able to solve this problem. The problem was that I connected the QNetworkAccessManager::finished() signal twice in line 16 and 92. The solution is to assign the QNetworkAccessManager::get() (or QNetworkAccessManager::post() ) to pointer of QNetworkReply and then connect the finished signal for QNetworkReply to a slot.