[SOLVED] How to download files from SourceForge using Qt
-
wrote on 31 Aug 2012, 10:12 last edited by
I'm writing a C++ application using Qt framework that needs to download a file from SourceForge.
I have to download this file https://sourceforge.net/projects/meshlab/files/updates/1.3.3/updates.xml
I wrote the following code using Qt and the QHttp class:
@QFile tmpfile;
int hostreqid;
int checkreqid;
...
...
tmpfile.setFileName("updates.xml");
hostreqid = http.setHost("sourceforge.net",QHttp::ConnectionModeHttp);
checkreqid = http.get(QString(QUrl::toPercentEncoding("/projects/meshlab/files/updates/1.3.3/updates.xml")),&tmpfile);
...
...
void parseAnswer( int id,bool error )
{
if (!error && (id == checkreqid))
{
...
tmpfile.close();
}
if (error)
{
QHttp::Error err = http.error();
QString errstrg = http.errorString();
}
}@
Both QHttp::setHost and QHttp::get are not blocking functions returning immediately an int id. When the http file transfer completed the parseAnswer function is automatically called. The problem is that inside the updates.xml file I got, instead the data I was expecting I received an html file from SouceForge reporting an "Invalid Project" error.I noticed that when I access the https://sourceforge.net/projects/meshlab/files/updates/1.3.3/updates.xml from browser I have been redirected to https://sourceforge.net/projects/meshlab/files/updates/1.3.3/updates.xml/download page. I tried also this other address but nothing changed.
Please, notice that I'm using Http protocol (QHttp::ConnectionModeHttp) instead of the https. If I could I would wish to avoid to use the https. Can be the source of the problem?
Thanks a lot!
-
wrote on 31 Aug 2012, 13:29 last edited by
You can't download from sourceforge directly, use one of it's mirrors, or generate url to be directly redirected to the right mirror:
@
QUrl url("http://downloads.sourceforge.net/project/meshlab/updates/1.3.3/updates.xml?r=&ts="+QString::number(QDateTime::currentDateTime ().toTime_t())+"&use_mirror=heanet");
@heanet is the example mirror in this case.
-
wrote on 31 Aug 2012, 16:52 last edited by
Thanks a lot for your suggestion! Unfortunately now I'm getting an empty file...Have you some other idea? Really really thanks for your help
-
wrote on 1 Sept 2012, 09:04 last edited by
Make sure you handle the HTTP redirect and initiate another request with the location reported back.
-
wrote on 3 Sept 2012, 06:31 last edited by
This works for me:
header:
@
#ifndef SFORGE_H
#define SFORGE_H#include <QNetworkAccessManager>
#include <QNetworkReply>class SForge : public QNetworkAccessManager
{
Q_OBJECT
public:
explicit SForge(QObject *parent = 0);private slots:
void fin(QNetworkReply *);};
#endif // SFORGE_H
@code:
@
#include "sforge.h"
#include <QDateTime>
#include <QUrl>
#include <QNetworkRequest>
#include <QDebug>SForge::SForge(QObject *parent):QNetworkAccessManager(parent)
{
QUrl url("http://downloads.sourceforge.net/project/meshlab/updates/1.3.3/updates.xml?r=&ts="+QString::number(QDateTime::currentDateTime().toTime_t())+"&use_mirror=heanet");connect(this, SIGNAL(finished(QNetworkReply*)), this, SLOT(fin(QNetworkReply*))); QNetworkRequest req(url); this->get(req);
}
void SForge::fin(QNetworkReply * reply)
{
if(reply->error() != QNetworkReply::NoError)
qDebug() << reply->errorString();if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 307 || reply->rawHeaderList().contains("Location")) { QNetworkRequest req(reply->header(QNetworkRequest::LocationHeader).toString()); this->get(req); return; } qDebug() << __LINE__ << reply->bytesAvailable() << reply->readAll();
}
@ -
wrote on 3 Sept 2012, 08:06 last edited by
I love you! You own my soul! Probably my problem was (also like Terence suggested) that I didn't manage the redirect... Thanks a lot! Really Really thanks!
-
wrote on 3 Sept 2012, 08:54 last edited by
I'm glad I could help you! :) Please add "[SOLVED]" prefix, left to the topic subject. Thanks!
1/7