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:80

    my=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("&lt;html&gt;&lt;body>&lt;form method=\"post\"&gt;&lt;input type=\"text\" name=\"aggi\" />&lt;input type=\"submit\" name=\"submit\" value=\"submit\" /&gt;&lt;/form>&lt;/body&gt;&lt;/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.


  • Moderators

    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.



  • d'oh, you are right (both), just didn't understand it the first tme. As i close the connection on the first readReady signal, the second never had a chance to occur.

    Thanx a lot!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.