I'm using qt5.3 and I googled a lot before I post.
I want to read data from QNetworkReply
. I have a QWebView
and I also need the http response to be read by QWebView
to display the webpage. What I need is just to log the web content or whatever response to http posts.
The problem is QNetworkReply
is something that can only be read once.
If I call readAll()
when I pick readyRead()
signal, I will get the full data. But it will be cleared so QWebView
displays nothing (it won't get any reply data).
Or if I pick finished()
signal, since the data is already read by QWebView
(or QNetworkAccessManager
), I get nothing if I call readAll()
here. Is there somewhere that QNetworkReply
, or manager or any class, stores the data which I can still read?
In #1 I can get part of the data if I call peek()
. This function does not clear the response data. But it won't work if the response body is big. The QNetworkReply
is a sequential thing that I can neither know its data nor read further than buffered.
I have no idea of how to do with this.....
I just want to monitor and log the request and response body of any request made on my QWebView
...
Edit: note that my data to read from response is as large as 1MB so it won't be ok to peek the whole data without further reading.
You can create your own subclass of QNetworkAccessManager
and override virtual function createRequest
. Call base class implementation to get the response object and connect readyRead
signal to some slot that will capture the data. In that slot call peek function to read data so that WebKit will get the data also :
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 creating QWebPage
object, call setNetworkAccessManager
and pass a newly created instance of your subclass :
QWebPage * page = new QWebPage;
page->setNetworkAccessManager(new NetworkAccessManagerProxy());
page->mainFrame()->load(url);
webView->setPage(page);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With