azadkuh / qhttp

a light-weight and asynchronous HTTP library (both server & client) in Qt5 and c++14
MIT License
484 stars 158 forks source link

The basic-server example and others are not handling post requests with large data. #16

Closed snaeji closed 4 years ago

snaeji commented 8 years ago

It may be due to my lack of knowledge but i think i've found a bug.

When receiving post requests that have around 30kb+ data the server is randomly reading from 20-100% of them before going into onEnd(). The isSuccessful() is also false in onEnd() if it has not read the full packet.

So basicly if you: Run the keep-alive or basic-server. Send a post request with a large body Print out the data server side

Then it randomly prints out 20-100% of the request at onEnd()

azadkuh commented 8 years ago

hi

1) please first checkout into dev branch, the dev branch has fixed POST problems. depending on your req->collectData(size_t size) you can collect larger chunks.

2) sample:

#include "qhttpserver.hpp"
#include "qhttpserverresponse.hpp"
#include "qhttpserverrequest.hpp"

#include <QCoreApplication>

#include <QTimer>
#include <QFile>
#include "../include/unixcatcher.hpp"
///////////////////////////////////////////////////////////////////////////////

int main(int argc, char ** argv) {
    QString port = "8080";
    if ( argc == 2 ) {
        port = argv[1];
    }

    QCoreApplication app(argc, argv);
#if defined(Q_OS_UNIX)
    catchUnixSignals({SIGQUIT, SIGINT, SIGTERM, SIGHUP});
#endif

    using namespace qhttp::server;
    QHttpServer server(&app);
    server.listen(port, [](QHttpRequest* req, QHttpResponse* res) {
        req->collectData(8*1024*1024);

        req->onEnd([req, res](){
            // status 200
            res->setStatusCode(qhttp::ESTATUS_OK);
            // it's the default header, this line can be omitted.
            res->addHeader("connection", "close");

            int size = req->collectedData().size();
            auto message = [size]() -> QByteArray {
                if ( size == 0 )
                    return "Hello World!\n";

                char buffer[33] = {0};
                qsnprintf(buffer, 32, "Hello!\nyou've sent me %d bytes!\n", size);
                return buffer;
            };
            res->end(message());  // reponse body data

            if ( size > 0 ) {
                // dump the incoming data
                QFile f("dump.bin");
                if ( f.open(QFile::WriteOnly) )
                    f.write(req->collectedData());
            }
        });

    });

    if ( !server.isListening() ) {
        qDebug("failed. can not listen at port %s!\n", qPrintable(port));
        return -1;
    }

    return app.exec();
}

now you can start the server as:

$> server 8090

now try POSTing data by curl:

$> curl -X POST --data-binary "@sample.jpeg" 127.0.0.1:8090

(replace the sample.jpeg with other filenames)

the above server will dump the incoming data into dump.bin

now you can check data integrity as:

$> md5 sample.jpeg
$> md5 dump.bin
snaeji commented 8 years ago

Thank you for your answer!

When i clone the dev branch i'm getting a compile error. Am i doing something wrong or is the dev branch broken? All help greatly appreciated.

screen shot 2016-06-21 at 00 48 55
azadkuh commented 8 years ago

which compiler are you using?

it's not broken for sure! but you need a c++14 compiler.

snaeji commented 8 years ago

Great that's good to know!

I'm using c++14 as far as i know....

snaebjorn@snow-box:~$ g++ --version g++ (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3

screen shot 2016-06-21 at 03 50 06

It's probably some foolish error, i'm going to keep on trying to figure out whats broken on my end.

azadkuh commented 8 years ago

well, i haven't checked g++ 4.9.3 with c++14 yet, personally i'm using g++ 5.3 and clang 3.8.

would you please try g++ 5.2 or higher?

you may also try -std=c++1y instead of -std=c++14 for g++ 4.9.3.

azadkuh commented 8 years ago

you can checkout the: asciicast

snaeji commented 8 years ago

Thanks this helped a lot especially the ascii feed! I changed the src/commondir.pri "QMAKE_CXXFLAGS += -std=c++11" to "c++14" and that did the trick!

azadkuh commented 8 years ago

gr8, happy to know that. i will push some other commits into dev to making build process easier.