How can I read content (HTTP response body) from QNetworkReply
I am using qt5.3 and I have googled many times before posting.
I want to read data from QNetworkReply
. I have QWebView
, and I also need a http response that will be read QWebView
to render the webpage. I just need to log web content or any other response to http posts.
The problem QNetworkReply
is that you can only read it once.
-
If I call
readAll()
when I select thereadyRead()
signal, I get the complete data. But it will be cleared, soQWebView
it won't display anything (it won't receive any response data). -
Or if I choose a
finished()
signal since the data is already being readQWebView
(orQNetworkAccessManager
) I get nothing if I callreadAll()
here. Is there somewhereQNetworkReply
, or a manager or any class, that stores data that I can still read?
At # 1, I can get some of the data if I call peek()
. This function does not clear response data. But it won't work if the response body is large. QNetworkReply
is a sequential thing in which I can neither know its data nor read further than buffering.
I do not know how to do that.....
I just want to track and log the request body and response of any request made on my QWebView
...
Edit: Please note that my read data from the answer is 1MB in size, so it will not be ok to view all data without further reading.
source to share
You can create your own subclass QNetworkAccessManager
and override the virtual function createRequest
. Make a call to the base class to get the response object and connect the signal readyRead
to some slot that will capture the data. In this function, call the call to the slot to read the data so that WebKit also receives the data:
class NetworkAccessManagerProxy : public QNetworkAccessManager {
Q_OBJECT
signals:
void dataGot(QByteArray data);
public:
NetworkAccessManagerProxy(QObject * parent = 0)
: QNetworkAccessManager()
{
}
virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice *outgoingData)
{
reply = QNetworkAccessManager::createRequest(op, request, outgoingData);
connect(this,SIGNAL(readyRead()), SLOT(readInternal()));
return reply;
}
private slots:
void readInternal()
{
QByteArray data = reply->peek(reply->bytesAvailable());
emit dataGot(data);
}
private:
QNetworkReply* reply;
};
After the object is created, QWebPage
call setNetworkAccessManager
and pass the newly created instance of your subclass:
QWebPage * page = new QWebPage;
page->setNetworkAccessManager(new NetworkAccessManagerProxy());
page->mainFrame()->load(url);
webView->setPage(page);
source to share