Russian Qt Forum

Qt => Работа с сетью => Тема начата: adminimus от Август 02, 2010, 22:32



Название: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: adminimus от Август 02, 2010, 22:32
Если сервер посылает одновременно заголовки Content-Encoding: gzip и Content-Length, то QNetworkReply в упор не видит заголовок Content-Length и выдает пустое значение. Примерный код для проверки:
Код:
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkRequest request;
QEventLoop eventLoop;
connect( &manager, SIGNAL(finished(QNetworkReply *)), &eventLoop, SLOT(quit()) );

request.setUrl( QUrl("http://www.overclockers.ru/") );
QNetworkReply *reply = manager.get(request);
do {
  eventLoop.exec();
} while ( ! reply->isFinished() );

qDebug() << "length=" << reply->header( QNetworkRequest::ContentLengthHeader);

Это баг сборки, баг Qt или я чего не понимаю?
Qt 4.6.3-1, Debian testing


Название: Re: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: SABROG от Август 02, 2010, 22:37
Посмотри в сниффере или через Live HTTP Headers плагин. Вполне возможно это баг сервера.


Название: Re: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: adminimus от Август 02, 2010, 22:44
В первую очередь и фаербагом, и через wireshark заголовки изучил. Сервер шлет оба указанных заголовка


Название: Re: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: SimpleSunny от Август 02, 2010, 23:32
Это фича ;)

из исходников
Код
C++ (Qt)
void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
{
   // The header "Content-Encoding  = gzip" is retained.
   // Content-Length is removed since the actual one send by the server is for compressed data
   QByteArray name("content-length");
   QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(),
                                                  end = fields.end();
   while (it != end) {
       if (qstricmp(name.constData(), it->first.constData()) == 0) {
           fields.erase(it);
           break;
       }
       ++it;
   }
 
}
 


Название: Re: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: adminimus от Август 02, 2010, 23:47
Мда, маразм какой-то. Собственно мне и нужно было посмотреть размер сжатых данных. Пробовал через QNetworkReply::downloadProgress смотреть bytesTotal и bytesReceived. В доках написано:
Цитировать
Note that the values of both bytesReceived and bytesTotal may be different from size(), the total number of bytes obtained through read() or readAll(), or the value of the header(ContentLengthHeader). The reason for that is that there may be protocol overhead or the data may be compressed during the download.
Т.е. по логике при включенном сжатии должен выдаваться именно размер сжатых данных. Но на деле выдается размер уже распакованных данных. Он же выдается в QNetworkReply::size.

Может есть еще какой способ узнать именно размер данных, пересылаемых по сети (до распаковки)?


Название: Re: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: SimpleSunny от Август 03, 2010, 11:02
Похоже, что никак.
Можно попросить троллей, чтобы добавили такую возможность в следующих версиях.
Или самому подправить Qt :)


Название: Re: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: SABROG от Август 03, 2010, 12:35
А если попробовать получить хидер в том виде, в каком его шлет сервер?

QByteArray QNetworkReply::rawHeader ( const QByteArray & headerName ) const


Название: Re: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: adminimus от Август 03, 2010, 12:39
rawHeader тоже пробовал, с тем же результатом :(


Название: Re: QNetworkReply не видит заголовок Content-Length при gzip-сжатии
Отправлено: adminimus от Август 04, 2010, 14:12
Покурил стандарт.
Цитировать
Messages MUST NOT include both a Content-Length header field and a non-identity transfer-coding. If the message does include a non- identity transfer-coding, the Content-Length MUST be ignored.
Сервер вроде как вообще не должен посылать оба заголовка, но апач может послать оба запросто.
Хотя даже с одним content-encoding=gzip и без content-length все равно qnetworkreply не выдает размер пересылаемых данных, только размер распакованных. Это уже похоже на баг, пойду на нокиевский форум отпишу