У меня есть веб-обозреватель, и я хочу, чтобы он имел доступ только к нашим веб-приложениям, для этого я поместил заголовок 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) Проверить заголовок нашего приложения.
Есть ли способ сделать это в одном запросе? Я пропустил метод, который будет делать это перенаправление автоматически?
С уважением
Натан
Видимо нет.
На HOWTO есть официальная запись http://developer.nokia.com/community/wiki/Handling_an_HTTP_redirect_with_QNetworkAccessManager (мертвая ссылка, к сожалению)
Извлечение по ссылке выше:
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;
}
Это немного устарело, но поддержка автоматического перенаправления была добавлена в Qt 5.6. Проверь это QNetworkRequest::FollowRedirectsAttribute
(http://doc.qt.io/qt-5/qnetworkrequest.html).