QNetworkReply и 301 редирект

У меня есть веб-просмотрщик, и я хочу, чтобы он имел доступ только к нашим веб-приложениям, для этого я разместил заголовок 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"){
        //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;
    }

Чтобы решить проблему попадания 301 сначала, я отправляю два сетевых запроса. Первый попадает по введенному URL-адресу и проверяет 301, если есть код статуса 301, он получает предложенный URL-адрес через метод reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); и возвращает этот 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();
    //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;
        }

    }
}

Короче говоря, я отправляю два сетевых запроса: 1) для проверки 301 2) для проверки заголовка нашего приложения.

Есть ли способ сделать это в одном запросе? Мне не хватает метода, который будет выполнять это перенаправление автоматически?

С Уважением

Натан


person Kal    schedule 11.02.2013    source источник


Ответы (2)


Видимо нет.

Есть официальная запись HOWTO на http://developer.nokia.com/community/wiki/Handling_an_HTTP_redager_With_Query. a> (к сожалению, мертвая ссылка)

Извлечение по ссылке выше:

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;
}
person kfunk    schedule 11.02.2013
comment
Думал, что, возможно, не было способа, но не был уверен, что я что-то где-то упустил, спасибо, что прояснили это @kfunk :) - person Kal; 11.02.2013
comment
ссылка на официальный HOWTO не работает :( - person David Sánchez; 24.11.2015
comment
@ DavidSánchez: Обновил комментарий, чтобы отразить это. К сожалению, содержимое вики не было перемещено до его удаления :( - person kfunk; 03.01.2016

Если вы используете Qt 6, пропустите чтение этого ответа как автоматическое перенаправление - поведение по умолчанию

Старый ответ, если вы не используете Qt 6:

Поддержка автоматического перенаправления была добавлена ​​в Qt 5.6 (QNetworkRequest::FollowRedirectsAttribute).

По умолчанию он не включен:

QNetworkRequest req(QUrl("https://example.com/"));
req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
person Konrad    schedule 03.04.2016
comment
Что значит старый? для меня это ново. спасибо, что упомянули об этом, вы сохранили мою задницу, я обновлю с 5.5 до 5.6, чтобы это работало. - person Raiden Core; 09.06.2016
comment
Быстрое обновление: QNetworkRequest::FollowRedirectsAttribute устарел и заменен QNetworkRequest::RedirectPolicyAttribute (проверьте возможные значения). - person cbuchart; 28.04.2021
comment
Я использую Qt6, и перенаправление, похоже, не выполняется по умолчанию, так как оно не работает - person HBatalha; 17.07.2021
comment
@HBatalha хм странно, вы уверены, что он не пытается перенаправить с https на http? - person Konrad; 18.07.2021
comment
@Konrad да, вот ссылка, вы можете протестировать: dropbox.com /s/zqbxgw4owoteas0/version.txt?dl=1 - person HBatalha; 18.07.2021