Ich bin Informatikstudent und gezwungen, nun mit Qt zu arbeiten.
Was bei mir am Ende rauskommen muss ist ein Webdav Client. Dieser muss erstmal nur GET und PUT können. Da QHttp als deprecated markiert ist, nutze ich also QNetworkAccessManager.
GET funktioniert, PUT macht mir allerdings zu schaffen.
Ich benutze Qt 4.5.3.9 auf einem FC11. gcc aktuell und Eclipse als GUI.
Ich habe folgenden Code (dieser wird ohne Fehler kompiliert):
Code: Alles auswählen
this->localFile = new QFile("./" + filename);
if(! QFile::exists(this->localFile->fileName())){
QMessageBox::warning(this->downloadManager, "Datei fehlt", QString("Die Datei %1 konnte nicht gefunden werden.").arg(filename).toLatin1(), QMessageBox::Ok);
return;
}
qDebug("File exists, upload!");
this->localFile->open(QIODevice::ReadOnly);
this->url = new QUrl();
this->url->setScheme("https");
this->url->setHost(servername);
this->url->setPort(port);
this->url->setPath("/upload-webdav/" + filename);
this->url->setUserName("test");
this->url->setPassword("test");
this->downloadManager = mgr;
this->http = new QNetworkAccessManager(this);
connect(this->http, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(slotSslErrors(QNetworkReply*, QList<QSslError>)));
connect(this->http, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*, QAuthenticator*)));
connect(http, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
qDebug("upload begins to " + this->url->host().toLatin1() + QString(" data:").toLatin1() + this->localFile->readAll());
this->localFile->reset();
QSslConfiguration *ssl = new QSslConfiguration();
QList<QSslCertificate> certs;
QFile *pem = new QFile("./cert.pem");
pem->open(QIODevice::ReadOnly);
certs = QSslCertificate::fromDevice(pem, QSsl::Pem);
ssl->setCaCertificates(certs);
ssl->setPeerVerifyMode(QSslSocket::QueryPeer);
QNetworkRequest req(*this->url);
req.setSslConfiguration(*ssl);
this->rpl = this->http->put(req,this->localFile->readAll());
this->rpl->ignoreSslErrors();
this->rpl->setSslConfiguration(*ssl);
connect(this->rpl, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError)));
connect(this->rpl, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(sendStatus(qint64, qint64)));
connect(this->rpl, SIGNAL(finished()), this, SLOT(replyFinished()));
qDebug("Webdav Uploader inited");Der SslConfig kram ist dann reingenommen worden, weil ich in dem entsprechenden Slot viele SslError Meldungen bekommen habe. Ansonsten fällt auf, dass die Verbindung nicht etwa mit finished() Signal beendet wird, sondern nach eineiger Zeit (vielleicht 2-5 Minuten) mit Network Error 2 (Host hat die Verbindung getrennt) beendet wird.
Der uploadProgress Slot gibt mir recht schnell 26 von 26 aus, also müsste die Datei eigentlich da sein, ist sie aber nicht. Falls ihr euch wundert, warum ich die Klamotten tlw. auf den Stack, tlw. auf den Heap schiebe, dass liegt nur daran, dass ich im Zuge der Tests und Fehlersuche rumprobiert habe. Gibt es da einen Qt-Standard?
Das finished Signal des QNetworkReply gibt es wohl nicht? Zumindest sagt er dann immer etwas von QNetworkReplyImpl::finished() nicht gefunden.
Noch eine Frage zu QtNetworkAccessManager:
Wenn ich einen SslError bekomme, bspw. weil das Zertifikat abgelaufen ist und im Slot der Benutzer gefragt wird, ob dennoch fortgefahren werden soll, wie kommt man dann aus dem Slot wieder an die Stelle vor dem SslError emit? Das ist z.B. so ein Punkt, den ich bei Qt noch nicht verstanden habe. Wenn es da generell etwas gutes zu lesen gibt (bitte etwas anspruchsvoller als "da gibt signale und da slots und so kommunizieren die"), bitte einfach als Link mitgeben.
Ich danke allen, die hier helfen im Voraus,
MatthiasMit2T