2013-02-11 13 views
5

Ich habe einen Webviewer und möchte nur, dass er nur auf unsere Webapps zugreifen kann. Um dies zu erreichen, habe ich einen PHP-Header platziert, den ich in meiner Qt App suche. Dies funktioniert gut, aber mit einer Ausnahme und das ist mit 301 permanent verschobenen Statuscodes. Moderne Browser leiten Sie automatisch um, setzen aber am Ende der HTTP-Anfrage ein "/".QNetworkReply und 301 Redirect

Wenn eine URL zu unserer Web-App eingegeben wird, benötigt sie derzeit den abschließenden Schrägstrich, um die Header erkennen zu können, aber ich möchte, dass sie auch in diesen Header gelangt, auch wenn sie keinen nachgestellten Schrägstrich enthalten.

Hier ist meine aktuelle Methode ist es, die Header abzurufen: Ich schicke zwei Netzwerkanfragen

QNetworkAccessManager *manager = new QNetworkAccessManager(this); 
    QNetworkRequest request; 
    request.setUrl(url); 
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*))); 

    request.setRawHeader("User-Agent", "CytoViewer 1.0"); 
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/CytoViewer"); 
    QNetworkReply *reply = manager->get(request); 
    reply->ignoreSslErrors(); 
    QEventLoop loop; 

    connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); 
    loop.exec(); 
    qDebug() << "QLoop reply all: " << reply->readAll(); 
    qDebug() << "QLoop: " << reply->rawHeader("Cyto-Study-Manager"); 
    if(reply->rawHeader("OurWebApp") == "1"){ 
     //Header exists?(QEventLoop finish) Set arg[1]"url 'Found prouct: product header'" 
     product = reply->rawHeader("Product"); 
     return true; 
    } else { 
     //Header doen't exist? Graceful error - not a valid PI product 
     return false; 
    } 

Zur Lösung des Problems der von einem 301 zuerst trifft, Die erste trifft die URL eingegeben und prüfen, ob ein 301 wenn Es gibt einen 301-Statuscode, der die vorgeschlagene URL über die reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();-Methode erhält, und gibt diese URL andernfalls zurück, wenn kein Statuscode vorhanden ist. Dann gibt sie einfach die vorherige URL zurück, die der Benutzer eingegeben hat, und sendet dann eine weitere Netzwerkanforderung, um die Header zu überprüfen.

erste Anfrage I-Statuscode überprüfen aussenden:

QUrl MainWindow::networkRequest(QUrl checkUrl){ 
    qDebug() << "checkURL: " << checkUrl; 
    // 
    QNetworkAccessManager *manager = new QNetworkAccessManager(this); 
    QNetworkRequest request; 
    request.setUrl(checkUrl); 
    request.setRawHeader("User-Agent", "CytoViewer 1.0"); 
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/CytoViewer"); 
    QNetworkReply *reply = manager->get(request); 
    reply->ignoreSslErrors(); 
    QEventLoop checkLoop; 
    connect(reply, SIGNAL(finished()), &checkLoop, SLOT(quit())); 
    checkLoop.exec(); 
    //Check status code 
    if (reply->error() == QNetworkReply::NoError) { 
     int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); 
     if(statusCode == 301) { 
      QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); 
      return redirectUrl; 
     }else { 
      return checkUrl; 
     } 

    } 
} 

Lange Rede kurzer Sinn, ich sende zwei Netzwerkanfragen, 1) für 301 2) Um zu überprüfen, für unsere App-Header zu überprüfen.

Gibt es trotzdem in einer Anfrage? Fehle ich eine Methode, die diese Umleitung automatisch durchführt?

Grüße

Nathan

Antwort

9

Offenbar gibt es nicht.

Es gibt einen offiziellen Handbuch-Eintrag auf http://developer.nokia.com/community/wiki/Handling_an_HTTP_redirect_with_QNetworkAccessManager (toten Link, leider)

Extraktion aus obigem Link:

void QNAMRedirect::replyFinished(QNetworkReply* reply) { 
    /* 
    * Reply is finished! 
    * We'll ask for the reply about the Redirection attribute 
    * http://doc.trolltech.com/qnetworkrequest.html#Attribute-enum 
    */ 
    QVariant possibleRedirectUrl = 
      reply->attribute(QNetworkRequest::RedirectionTargetAttribute); 

    /* We'll deduct if the redirection is valid in the redirectUrl function */ 
    _urlRedirectedTo = this->redirectUrl(possibleRedirectUrl.toUrl(), 
             _urlRedirectedTo); 

    /* If the URL is not empty, we're being redirected. */ 
    if(!_urlRedirectedTo.isEmpty()) { 
     QString text = QString("QNAMRedirect::replyFinished: Redirected to ") 
           .append(_urlRedirectedTo.toString()); 
     this->_textContainer->setText(text); 

     /* We'll do another request to the redirection url. */ 
     this->_qnam->get(QNetworkRequest(_urlRedirectedTo)); 
    } 
    else { 
     /* 
     * We weren't redirected anymore 
     * so we arrived to the final destination... 
     */ 
     QString text = QString("QNAMRedirect::replyFinished: Arrived to ") 
           .append(reply->url().toString()); 
     this->_textContainer->setText(text); 
     /* ...so this can be cleared. */ 
     _urlRedirectedTo.clear(); 
    } 
    /* Clean up. */ 
    reply->deleteLater(); 
} 

QUrl QNAMRedirect::redirectUrl(const QUrl& possibleRedirectUrl, 
           const QUrl& oldRedirectUrl) const { 
    QUrl redirectUrl; 
    /* 
    * Check if the URL is empty and 
    * that we aren't being fooled into a infinite redirect loop. 
    * We could also keep track of how many redirects we have been to 
    * and set a limit to it, but we'll leave that to you. 
    */ 
    if(!possibleRedirectUrl.isEmpty() && 
     possibleRedirectUrl != oldRedirectUrl) { 
     redirectUrl = possibleRedirectUrl; 
    } 
    return redirectUrl; 
} 
+0

Dachte, es gab vielleicht keinen Weg, aber ich war mir nicht sicher, ob ich irgendwo etwas verpasst hatte, danke für das Aufräumen @kfunk :) – Kal

+1

der Link zum offiziellen HOWTO ist kaputt :( –

+0

@ DavidSánchez: Aktualisiert den Kommentar Leider wurde der Wiki-Inhalt vor dem Löschen nicht verschoben :( – kfunk

14

Dies ist ein wenig alt, aber Auto-Umleitung auf Qt 5.6 gerade hinzugefügt hat. Überprüfen Sie dies QNetworkRequest::FollowRedirectsAttribute (http://doc.qt.io/qt-5/qnetworkrequest.html).

+1

Was meinst du alt? für mich ist es neu. Danke, dass du das erwähnt hast, du hast mir ein ** gerettet, ich werde von 5.5 auf 5.6 updaten damit dies funktioniert. –