QNetworkReply liefert 'Not permitted' bei valider URL


#1

Ich bin gerade dabei ein kleines Projekt in C++ und Qt zu realisieren. Es handelt sich dabei um ein Tool um Youtube-Videos runter zu laden. Ich bin im Moment so weit, dass ich von einer beliebigen Watch-URL die originale URL ausfindig machen kann. Es hapert allerdings am eigentlichen Download dieses Videos, und ich befürchte fast, dass es sich hierbei um einen Qt-Bug handelt.
Ich bekomme jedesmal von QNetworkReply::error() den Wert 202 zurückgeliefert (403 Not permitted) und weiß nicht wieso. Wenn ich mir das Socket selbst in C schreibe sehe ich, dass diese URL selbst nicht das eigentliche Video enthält sondern nur eine Umleitung vornimmt. Das sollte aber soweit kein Problem sein (mit Java kriegt ichs ja auch hin?!).

In dieser Datei tritt der Fehler konkret auf:


#include "YoutubeInterface.h"

#include <QString>
#include <QEventLoop>
#include <QFile>
#include <QUrl>
#include <QNetworkAccessManager>

DownloadManager::DownloadManager(QNetworkAccessManager *manager, const YoutubeInterface *yti)
{
	this->manager = manager;
	this->yti = yti;

	setRawHeader("User-Agent", "clipcrawler");
}

void DownloadManager::writeToFile()
{
	//(*outputStream) << reply->readAll();
	emit statusMessage("Write message");
}

void DownloadManager::downloadTo(const QString &dir)
{
	QEventLoop loop;
	QFile target(dir + "/" + yti->getVideoTitle() + "." + yti->getVideoFormat());

	if(!target.open(QIODevice::WriteOnly))
	{
		emit statusMessage("Cannot open file.");
		return;
	}

	//outputStream = new QTextStream(&target);

	setUrl(QUrl(yti->getVideoUrl()));
	reply = manager->get(*this);

	emit statusMessage("Download file '" + target.fileName() + "' from url '" + yti->getVideoUrl() + "' ...");
	QObject::connect(reply, SIGNAL(readyRead()), this,  SLOT(writeToFile()));
	QObject::connect(reply, SIGNAL(finished()),  &loop, SLOT(quit()));
	loop.exec();
	emit statusMessage("Download finished! (return code " + QString::number(reply->error()) + ")");

	target.close(); // close file stream
	//delete outputStream;
}

Hier findet sich der komplette Source-Code:


#2

Ich bin nach 3 Tagen herumrätseln endlich draufgekommen: QUrl encoded die als Strings übergebenen URLs gleich nochmal (dann wird %2C plötzlich zu %252C). Ich musste im Prinzip nur Zeile 38 so umändern: setUrl(QUrl(QUrl::fromPercentEncoding(yti->getVideoUrl().toAscii())));

Das entscheidende hier ist die Methode QUrl::fromPercentEncoding(), die mir sämtlich %-Encodings rausschmeißt, bevor ich die URL dem Konstruktor übergebe.