QNetworkReply和301重定向 [英] QNetworkReply and 301 redirect

查看:494
本文介绍了QNetworkReply和301重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个webviewer,只希望它只能访问我们的webapps,实现这里我放置了一个php头,我寻找在我的Qt应用程序。这工作正常,但有一个例外,那是301永久移动的状态代码。现代浏览器会自动重定向您,但在http请求的末尾放置一个/。



当我们的网络应用程序的URL输入时,它目前需要尾部斜杠能够检测头部,但我想它也得到那个头部,即使他们没有放一个尾斜杠。



这是我当前的方法来检索

  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){
//头文件存在?QEventLoop完成设置arg [1]url
product = reply-> rawHeader(Product);
return true;
} else {
// Header doen't exists?正常错误 - 不是有效的PI产品
return false;
}

为了解决先打301的问题,我发送两个网络请求,第一个命中URL输入,并检查301,如果有一个301状态码,它通过 reply->属性(QNetworkRequest :: RedirectionTargetAttribute).toUrl();获得的建议的URL。 code>方法并返回该URL否则如果没有状态代码,那么它只是返回用户输入的上一个URL,然后发送另一个网络请求检查头。



第一个请求发送到检查状态代码:

  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();
//检查状态码
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;
}

}
}

短,我发送两个网络请求,1)检查301 2)检查我们的应用程序头。



有没有反正在一个请求中这样做?



Nathan

$ b



http://developer.nokia.com/community/wiki/Handling_an_HTTP_redirect_with_QNetworkAccessManagerrel =nofollow> http://developer.nokia.com/community/wiki/Handling_an_HTTP_redirect_with_QNetworkAccessManager (不幸的是死链接)



从以上链接提取:

  void QNAMRedirect :: replyFinished(QNetworkReply * reply ){
/ *
*回复完成!
*我们将要求关于重定向属性的回复
* http://doc.trolltech.com/qnetworkrequest.html#Attribute-enum
* /
QVariant possibleRedirectUrl =
reply-> attribute(QNetworkRequest :: RedirectionTargetAttribute);

/ *如果重定向在redirectUrl函数中有效,我们将扣除* /
_urlRedirectedTo = this-> redirectUrl(possibleRedirectUrl.toUrl(),
_urlRedirectedTo);

/ *如果网址不为空,我们将被重定向。 * /
if(!_ urlRedirectedTo.isEmpty()){
QString text = QString(QNAMRedirect :: replyFinished:Redirected to)
.append(_urlRedirectedTo.toString());
this-> _textContainer-> setText(text);

/ *我们将再次请求重定向网址。 * /
this-> _qnam-> get(QNetworkRequest(_urlRedirectedTo));
}
else {
/ *
*我们没有重定向了
*所以我们到达了最终目的地...
* /
QString text = QString(QNAMRedirect :: replyFinished:Arrived to)
.append(reply-> url()。toString());
this-> _textContainer-> setText(text);
/ * ...所以这个可以清除。 * /
_urlRedirectedTo.clear();
}
/ *清理。 * /
reply-> deleteLater();
}

QUrl QNAMRedirect :: redirectUrl(const QUrl& possibleRedirectUrl,
const QUrl& oldRedirectUrl)const {
QUrl redirectUrl;
/ *
*检查URL是否为空和
*,我们没有被欺骗成无限重定向循环。
*我们还可以跟踪我们已经到达
*的重定向数量,并设置了一个限制,但我们将留给你。
* /
if(!possibleRedirectUrl.isEmpty()&&
possibleRedirectUrl!= oldRedirectUrl){
redirectUrl = possibleRedirectUrl;
}
return redirectUrl;
}


I have a webviewer and only want it to only be able to access our webapps, to achieve this I have placed a php header which I look for in my Qt App. This works fine but with one exception and that's with 301 permanent moved status codes. Modern browsers redirect you automatically but putting a "/" at the end of the http request.

When a URL to our web app is entered it currently needs the trailing slash to be able to detect the headers but I want it to also get at that header even if they don't put a trailing slash.

Here is my current method to retrieve the header:

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;
    }

To solve the problem of of hitting a 301 first I send two network requests, The first one hits the URL entered and check for a 301 if there is a 301 status code it get's the proposed url via the reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); method and returns that URL else if there is no status code then it simply returns the previous URL the user entered and then sends another network request to check the headers.

First request I send out to check status code:

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;
        }

    }
}

Long story short, I am sending two network requests, 1) To check for 301 2) To check for our app header.

Is there anyway to do this in one request? Am I missing a method that will do this redirection automatically?

Regards

Nathan

解决方案

Apparently there is not.

There's an official HOWTO entry on http://developer.nokia.com/community/wiki/Handling_an_HTTP_redirect_with_QNetworkAccessManager (dead link, unfortunately)

Extraction from link above:

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;
}

这篇关于QNetworkReply和301重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆