QT download video with SSL not working - qt

This code downloads a video, but for some reason does not work
globals.h
QString videoDirectLink = "";
mainwindow.cpp
#include "globals.h"
void MainWindow::readOutput() {
QByteArray outData = myProcess->readAllStandardOutput(); // read from CMD
videoDirectLink = outData; // videoDirectLink Contains https://media08.vbox7.com/s/91/91f4c651car96dafe736.mp4
if (videoDirectLink.contains("https")) {
// SSL downloading
QNetworkAccessManager *manager2 = new QNetworkAccessManager(this);
connect(manager2, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*)));
QNetworkRequest *req = new QNetworkRequest();
req->setUrl(QUrl(videoDirectLink)); //videoDirectLink
QSslConfiguration configSsl = QSslConfiguration::defaultConfiguration();
configSsl.setProtocol(QSsl::AnyProtocol);
req->setSslConfiguration(configSsl);
connect(manager2->get(*req), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
}
If changes req->setUrl(QUrl(videoDirectLink));
to req->setUrl(QUrl("https://media08.vbox7.com/s/91/91f4c651car96dafe736.mp4"));
or
QString n ="https://media08.vbox7.com/s/91/91f4c651car96dafe736.mp4";
req->setUrl(QUrl(n));
everything works
This is worked code for download without SSL. The principle is the same
globals.h
QString videoDirectLink = "";
mainwindow.cpp
#include "globals.h"
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
// start downloading
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(downloadFinished(QNetworkReply*)));
QString target = videoDirectLink;
QUrl url = QUrl::fromEncoded(target.toLocal8Bit());
connect(manager->get(QNetworkRequest(url)), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
I tried to add encoding, but that is not the problem.
other suggestions ?
// NOT WORKING
void MainWindow::readOutput() {
QString outData = myProcess->readAllStandardOutput(); // URL -> https://www.vbox7.com/play:91f4c651ca
videoDirectLink = outData; // videoDirectLink -> https://media28.vbox7.com/s/91/91f4c651car96dafe736.mp4
if (videoDirectLink.contains("https")) {
QNetworkAccessManager *manager2 = new QNetworkAccessManager(this);
connect(manager2, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*)));
QNetworkRequest *req = new QNetworkRequest();
req->setUrl(QUrl(videoDirectLink)); //videoDirectLink
connect(manager2->get(*req), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
QMessageBox::information(this,"SSL downloading",videoDirectLink,"ok"); // displays https://media28.vbox7.com/s/91/91f4c651car96dafe736.mp4
}
}

Related

QNetworkReply::RemoteHostClosedError

I was learning the Github API and wanted to create an Issue on github by Qt.
But, when I submit my Issue, the "Debug Console" said
QNetworkReply::RemoteHostClosedError
(I catched error).
I don't know why, please help me!
Code on Github:
void MainWindow::on_pushButton_2_clicked()
{
QString id = ui->ID_Send->text();
QJsonObject JJ;
QJsonDocument jd;
JJ["title"] = ui->Title->text();
JJ["body"] = ui->Comment->toPlainText();
QHttpMultiPart *part = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart info;
info.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/json"));
jd.setObject(JJ);
info.setBody(jd.toJson());
part->append(info);
QNetworkRequest request;
qDebug()<<"https://api.github.com/repos/MoyuSteve/Comment/issues?client_id="+
client_id+"&client_secret="+client_secret;
request.setUrl(QUrl("https://api.github.com/repos/MoyuSteve/Comment/issues?client_id="+
client_id+"&client_secret="+client_secret));
QNetworkReply* reply = manager->post(request,part);
QObject::connect(reply, &QNetworkReply::finished, [reply, this] () {
if (reply->error() == QNetworkReply::NoError) {
ui->status->setText("ok");
} else {
ui->status->setText("failed");
qDebug()<<reply->error();
}
reply->deleteLater();
});
}
You can take example in this answer or here.
Compared to your code, it sets the header to "application/json".
And it uses a QNetworkAccessManager to send network requests and receive replies.
QUrl url("https://api.github.com/repos/" + owner +"/" + project + "/tags");
qInfo() << url.toString();
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkAccessManager nam;
QNetworkReply * reply = nam.get(request);

QHttpMultiPart upload file boundary issue

I'm trying to upload some files to a server by using QHttpMultiPart. The following version file is just an example. For some reason, Qt will automatically add boundary into the files. However, what I truly uploaded are .tar.gz files and they will be considered damaged if such boundary were added.
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QNetworkAccessManager *netManager = new QNetworkAccessManager();
HTTPFirmwareUpgrader upgrader(netManager,"http://mytest.com");
upgrader.upgradeCIU();
return app.exec();
}
void HTTPFirmwareUpgrader::upgradeCIU()
{
QString filename = "version";
QString filePath = QString("C:/Users/User/Desktop/HTTP/%1").arg(filename);
qDebug() << uploadFirmware(filename, filePath);
}
bool HTTPFirmwareUpgrader::uploadFirmware(const QString &filename, const QString &filePath)
{
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart myPart;
QFile *file = new QFile(filePath);
if(!file->exists())
qWarning() << "File DOES NOT exists";
file->open(QIODevice::ReadOnly);
myPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("form-data"));
myPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"version\"; filename=\"version\""));
myPart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(ciu);
QByteArray resp = this->post(createUploadRequest(QString("filename=%1").arg(filename)),
multiPart, file);
qDebug() << "Upload Filrmware " << resp;
return resp != "";
}
QByteArray HTTPFirmwareUpgrader::post(QUrl url, QHttpMultiPart *multiPart, QFile *file)
{
QNetworkRequest request;
QEventLoop loop;
request.setUrl(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("multipart/form-data"));
QNetworkReply *reply = m_manager->post(request, multiPart);
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
multiPart->setParent(reply);
reply->deleteLater();
return reply->readAll();
}
This is the original "version" file:
enter image description here
And this is the "version" file that transferred:
enter image description here
And if I do not set header for the request, the size of the transferred file will be 0.
Does anyone have any idea what should I do?
Problem solved!!!
Turns out I use the wrong way to upload the file. What I need to use is QIODevice instead of QMultipart.

QNetworkRequest to download an image?

I have used QNetworkRequest to retrieve xml off the web without problems:
request.setUrl(QUrl("http://api.somesite.com/api/4we35r/somefile.xml"));
myNetworkAccessManager->get(request);
How would I go about downloading an image? Ex:
http://www.mysite.com/27eye28/images/myimage.png
Do I just replace the xml url above with the png url? Do I have to do anything special?
Yes, replacing the URL is all that you have to do.
Here's a working example,
void MainWindow::GetImage(QString url)
{
QNetworkAccessManager* manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
QUrl url = QUrl(url);
QNetworkRequest request(url);
manager->get(request);
}
void MainWindow::replyFinished(QNetworkReply *reply)
{
if(reply->error() != QNetworkReply::NoError)
{
ui->textBrowser->setText("Error: " + reply->errorString());
}
else
{
QByteArray responseData = reply->readAll();
QFile file("d:\\myImage.png");
file.open(QIODevice::WriteOnly);
file.write((responseData));
file.close();
}
}

Qt HTTP GET freezes screen

I'm writing a Qt program to get an image from site and insert in a QLabel. When I send my request my screen freezes and nothing more occurs.
Notice I'm new in Qt.
Based on my initial knowledge of Qt it's enough send a signal when download is finished.
...
MapReader::MapReader(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
imageLabelMap = ui.imageMap;
getImageButton = ui.getImageButton;
networkManager = new QNetworkAccessManager(this);
setup();
}
MapReader::~MapReader()
{
}
void MapReader::setup()
{
QObject::connect(getImageButton, SIGNAL(clicked()), this, SLOT(triggerDownload()));
QObject::connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedDownload(QNetworkReply*)));
}
void MapReader::setImage(QByteArray imageBytes)
{
QImage map;
...
}
void MapReader::triggerDownload()
{
QUrl url("http://images.tsn.ca/images/stories/2012/09/26/terrydunfield_2035-430x298.jpg");
QNetworkReply* reply = networkManager->get(QNetworkRequest(url));
QObject::connect(reply, SIGNAL(readyRead()), &loop, SLOT(quit()));
}
void MapReader::finishedDownload(QNetworkReply* reply)
{
reply->deleteLater();
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if(reply->error() != QNetworkReply::NoError)
{
QMessageBox msgBox;
msgBox.setWindowTitle("Error");
msgBox.setInformativeText("Error on downloading file: \n"+reply->errorString());
msgBox.exec();
return;
}
QVariant attribute = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (attribute.isValid())
{
QUrl url = attribute.toUrl();
qDebug() << "must go to:" << url;
return;
}
setImage(reply->readAll());
}
I think there is some code missing that might give us a clue. You have
QObject::connect(reply, SIGNAL(readyRead()), &loop, SLOT(quit()));
But I don't see where loop is defined? Sounds like you are running an additional event loop?
Regardless, you don't need that. This should be as simple as:
void MapReader::triggerDownload()
{
QUrl url("http://images.tsn.ca/images/stories/2012/09/26/terrydunfield_2035-430x298.jpg");
QNetworkReply* reply = networkManager->get(QNetworkRequest(url));
QObject::connect(reply, SIGNAL(finished()), this, SLOT(finishedDownload()));
}
void MapReader::finishedDownload()
{
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender()); // sender() allows us to see who triggered this slot - in this case the QNetworkReply
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if(reply->error() != QNetworkReply::NoError)
{
QMessageBox msgBox;
msgBox.setWindowTitle("Error");
msgBox.setInformativeText("Error on downloading file: \n"+reply->errorString());
msgBox.exec();
return;
}
QVariant attribute = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (attribute.isValid())
{
QUrl url = attribute.toUrl();
qDebug() << "must go to:" << url;
return;
}
setImage(reply->readAll());
reply->deleteLater();
}
Make sure you have defined finishedDownload() as a slot in your header file

QTcpSocket stucks sometimes for dynamic created java script

I am trying to connect to a website through a proxy. I implemented a QTcpServer and a QTcpSocket.
The server passes the connection to the socket.
It works well, but for some sites, expecially for those which have dynamically created javascript, the socket stucks at some point and nothing is shown in the navigator.
Attach the code, hope clear.
#include "webproxy.h"
#include <QtNetwork>
#include <QMessageBox>
#include <QtGui>
#include <QHash>
WebProxy::WebProxy(QObject *parent,int port): QObject(parent)
{
qDebug()<<" Listen...";
authMethod = "";
QTcpServer *proxyServer = new QTcpServer(this);
if (!proxyServer->listen(QHostAddress::Any, port)) {
emit error(1);
return;
}
connect(proxyServer, SIGNAL(newConnection()), this, SLOT(manageQuery()));
qDebug() << "Proxy server running at port" << proxyServer->serverPort();
void WebProxy::manageQuery() {
QTcpServer *proxyServer = qobject_cast<QTcpServer*>(sender());
QTcpSocket *socket = proxyServer->nextPendingConnection();
connect(socket, SIGNAL(readyRead()), this, SLOT(processQuery()));
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
qDebug()<<"New connection started..."<<socket->peerAddress();
}
QUrl WebProxy::getUrl(QList<QByteArray > &entries)
{
QByteArray method = entries.value(0);
QByteArray address = entries.value(1);
QByteArray version = entries.value(2);
qDebug()<<method;
qDebug()<<address;
qDebug()<<version;
QUrl url = QUrl::fromEncoded(address);
if (!url.isValid()) {
qWarning() << "Invalid URL:" << url;
return QString();
}
return url;
}
void WebProxy::processQuery() {
int wSize = 0;
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
QByteArray requestData = socket->readAll();
qDebug()<<"Request "<<requestData;
int pos = requestData.indexOf("\r\n");
QByteArray requestLine = requestData.left(pos);
requestData.remove(0, pos + 2);
QList<QByteArray> entries = requestLine.split(' ');
QByteArray method = entries.value(0);
QByteArray address = entries.value(1);
QByteArray version = entries.value(2);
QByteArray auth;
QByteArray authMethod;
QUrl url = QUrl::fromEncoded(address);
if (!url.isValid()) {
qWarning() << "Invalid URL:" << url;
socket->disconnectFromHost();
return;
}
QString host = url.host();
int port = (url.port() <= 0) ? 80 : url.port();
QByteArray req = url.encodedPath();
if (url.hasQuery())
req.append('?').append(url.encodedQuery());
requestLine = method + " " + req + " " + version + "\r\n";
if (!authMethod.isEmpty())
{
requestLine.append(requestLine);
requestLine.append(authMethod);
requestLine.append("\r\n");
}
QString key = host + ':' + QString::number(port);
QTcpSocket *proxySocket = socket->findChild<QTcpSocket*>(key);
if (proxySocket) {
proxySocket->setObjectName(key);
proxySocket->setProperty("url", url);
proxySocket->setProperty("requestData", requestData);
wSize = proxySocket->write(requestData);
} else {
proxySocket = new QTcpSocket(socket);
proxySocket->setObjectName(key);
proxySocket->setProperty("url", url);
proxySocket->setProperty("requestData", requestData);
connect(proxySocket, SIGNAL(connected()), this, SLOT(sendRequest()));
connect(proxySocket, SIGNAL(readyRead()), this, SLOT(transferData()));
connect(proxySocket, SIGNAL(disconnected()), this, SLOT(closeConnection()));
connect(proxySocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(closeConnection()));
proxySocket->connectToHost(host, port);
}
}
void WebProxy::sendRequest() {
QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());
QByteArray requestData = proxySocket->property("requestData").toByteArray();
int wSize = 0;
wSize = proxySocket->write(requestData);
}
void WebProxy::transferData() {
QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());
QByteArray data = proxySocket->readAll();
qDebug()<<"READ TRANSFER SIZE..."<<data.size();
QString host = proxySocket->peerAddress().toString();
QByteArray filtered(data);
QTcpSocket *socket = qobject_cast<QTcpSocket*>(proxySocket->parent());
int wSize = 0;
if (!data.trimmed().isEmpty())
{
wSize = socket->write(filtered);
if (wSize==-1)
qDebug()<<"WP error";
else
qDebug()<<"TRANSFER WRITE SIZE = "<<wSize<<" READ SIZE"<<filtered.size();
}
}
void WebProxy::closeConnection() {
QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());
if (proxySocket) {
QTcpSocket *socket = qobject_cast<QTcpSocket*>(proxySocket->parent());
if (socket)
socket->disconnectFromHost();
if (proxySocket->error() != QTcpSocket::RemoteHostClosedError)
qWarning() << "Error for:" << proxySocket->property("url").toUrl()
<< proxySocket->errorString();
proxySocket->deleteLater();;
}
}
You may want to use QTcpServer in a multi-threaded way.
Subclass QTcpServer, overload QTcpServer::incomingConnection(int), create your QThread derived handler (described next) and start it with QThread::start
Subclass QThread, make the constructor accept an int (the socket descriptor), overload QThread::run(). In the run function, create QTcpSocket, call QAbstractSocket::setSocketDescriptor to initialise the socket, connect up the socket slots and call QThread::exec() to start the thread event loop.
Make sure you create the socket in the run of QThread, not the constructor so the socket is associated with that thread.
For more details, look at the Threaded Fortune Server Example

Resources