QTcpSocket and WebKit: form post data gets lost
-
Hi,
i have problems with a server / client thing i am writing. I make a multithreaded webserver using QTcpSocket
@Connection::Connection(QObject *parent) :
QTcpSocket(parent)
{
setReadBufferSize(MaxBufferSize);
connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead()));
}void Connection::processReadyRead()
{
readDataIntoBuffer(MaxBufferSize);
HTTPRequest req(buffer);
processRequest(req);
}int Connection::readDataIntoBuffer(int maxSize)
{
if (maxSize > MaxBufferSize)
return 0;int numBytesBeforeRead = buffer.size(); if (numBytesBeforeRead == MaxBufferSize) { abort(); return 0; } while (bytesAvailable() > 0 && buffer.size() < maxSize) { buffer.append(read(1)); } return buffer.size() - numBytesBeforeRead;
}
void Connection::processRequest(HTTPRequest &req)
{
// do something
flush();qDebug() << "connectin done " << QThread::currentThreadId(); waitForBytesWritten(); disconnectFromHost(); waitForDisconnected();
}
@in HTTPRequest i debug the full data get from server:
@
void HTTPRequest::fromString(QString &str)
{
qDebug() << str;
}
@Problem is, if i submit a form, the connection gets the header, something like:
@
"POST /test HTTP/1.1
Origin: https://127.0.0.1:80/form.html
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) Qt/4.8.0 Safari/534.34
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Referer: https://127.0.0.1:80/form.html
Content-Length: 10
Connection: Keep-Alive
Accept-Encoding: gzip
Accept-Language: en-US,*
Host: 127.0.0.1:80"
@it should end with
@
...
Host: 127.0.0.1:80my=post&data=here
@it stops right after the http header. This only happens with the QtWebKit client, if i submit the form with firefox, i get the data.
The thing is though, that i used tcpdump and QtWebKit is sending the data, in a new packet, seems the server somehow thinks there is no data left, although there is.
I also tried to force a wait for data after the first read, it waits unlimited, as it thinks there is no data left, but there is.
What am i doing wrong, or could this even be a bug in QtWebKit?
Thanx.
-
You're doing it wrong in regard of two aspects:
Don't subclass QTcpSocket, but just use it as a member in your class
you don't listen to readyRead() signal and read after that. bytesAvailable() may return false but after some more cycles there may be data available again
There are some http servers implemented in Qt available out there. Did you consider using one of them before reinventing the wheel?
-
Thanx, but all examples i found was with overwriting QTcpSocket (in official QT docs)... anyway, i did a quick test:
@
QTcpSocket socket;
if (!socket.setSocketDescriptor(this->socketDescriptor)) {
return;
}if (socket.waitForReadyRead()) { QByteArray dat = socket.readAll(); qDebug() << QString(dat); } socket.write("HTTP/1.1 200 OK\r\n"); socket.write("Content-Type: text/html\r\n\r\n"); socket.write("<html><body><form method=\"post\"><input type=\"text\" name=\"aggi\" /><input type=\"submit\" name=\"submit\" value=\"submit\" /></form></body></html>"); socket.waitForBytesWritten(); socket.disconnectFromHost(); if (socket.isOpen()) { socket.waitForDisconnected(); }
@
still no post data arriving. Unfortunately using some other http server is no option for me, but ofcourse peeking in other http servers source would be ;) - which i did, i did not see a obvious difference.
-
I think the issue is that you are still not watching out for signal "readyRead":https://qt-project.org/doc/qt-4.8/qiodevice.html#readyRead
The waitForReadyRead may fire with only one byte in return. You need to continuously monitor, because data may be spreat over time.