Qt C++ QNetworkRequest - FollowRedirectsAttribute не работает с QHttpMultiPart* и QIODevice*
Какая-то странная логика у QtNetwork.
Видимо, QNetworkAccessManager считает, что при отправке запроса и получение ответа 302 Redirect совсем не надо отправлять те же данные, что были переданы в QHttpMultiPart* или QIODevice* ещё раз, достаточно просто отправить заново этот же запрос по новому адресу с пустым телом запроса.
Приблизительно так это выглядит при ПЕРВОМ запросе
POST / HTTP/1.1
Host: https://example.com
Content-Type: multipart/form-data
Content-Length: 123
ДАННЫЕ ДЛЯ ОТПРАВКИ С ПОМОЩЬЮ QIODevice* / QHttpMultiPart*
А вот так при редиректе (302):
POST / HTTP/1.1
Host: https://example.com
Content-Type: multipart/form-data
Content-Length: 0
(****А ТУТ УЖЕ ПУСТО****)
Из-за того, что
QNetworkAccessManagerчитает из буфераQIODevice*с помощьюreadAll()при редиректе этот буфер уже пуст и, следовательно, отправлять больше нечего. Это баг? Что с этим можно сделать, чтобы не страдать?
Ответы (1 шт):
Решил проблему переопределением QNetworkAccessManager::createRequest простым сохранением данных в переменную и повторную отравку запроса. Работает без проблем:
QNetworkReply *NetworkAccessManager::createRequest(QNetworkAccessManager::Operation op,
const QNetworkRequest &request, QIODevice *outgoingData)
{
if (outgoingData) {
if (outgoingData->atEnd()) {
QScopedPointer<QBuffer> buffer(new QBuffer);
buffer->setData(lastData);
buffer->open(QIODevice::ReadOnly);
//outgoingData->deleteLater(); Будем считать, что удалением основного QIODevice*
// экземпляра должен заниматься пользователь,
// так как о редиректе он ничего не знает
return QNetworkAccessManager::createRequest(op, request, buffer.take());
}
else {
lastData = outgoingData->readAll();
return createRequest(op, request, outgoingData);
}
}
return QNetworkAccessManager::createRequest(op, request);
}