vinipsmaker / tufao

An asynchronous web framework for C++ built on top of Qt

Home Page:http://vinipsmaker.github.io/tufao/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Programm crashes if connection is aborted

ECP-Black opened this issue · comments

Hello,

when a connection is aborted between the handle of the request and the response.end() the application crashes.

I use Qt 5.4.0 with mingw32 4.9.1 on Windows7 64bit. Tufao Version 1.3.1 but it also crashes with 1.2.x.

Here is an modified hello world example with a delay between request and response of 1s:

#include <QCoreApplication>
#include <Tufao/HttpServer>
#include <QtCore/QUrl>
#include <Tufao/HttpServerRequest>
#include <Tufao/Headers>
#include <QThread>
#include <QTimer>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Tufao::HttpServer server;

    QObject::connect(&server, &Tufao::HttpServer::requestReady,
                     [](Tufao::HttpServerRequest &request,
                     Tufao::HttpServerResponse &response) {
        QObject::connect(&request, &Tufao::HttpServerRequest::close, []() {
            qDebug() << "close connection";
        });
        qDebug() << " new request";
        QTimer* timer = new QTimer();
        timer->setSingleShot(true);
        QObject::connect(timer, &QTimer::timeout, [&response, &request, timer]() {
            qDebug() << "write response";
            response.writeHead(Tufao::HttpResponseStatus::OK);
            response.headers().replace("Content-Type", "text/plain");
            response.end("Hello " + request.url().path().toUtf8());
            timer->deleteLater();
        });
// Simulate some work and delay the response
        timer->start(1000);
    });

    server.listen(QHostAddress::Any, 8080);

    return a.exec();
}

If you cancel the request (for example in the browser with ESC after pressing RETURN) the app crashes.

Or here an nodejs request example:

var request = require('request');

for (var i = 0; i < 7; i++)
{
    doReq(i);
}

function doReq(i) {
    try {
        console.time("req" + i);
        var req = request({
            method: "GET",
            url: 'http://localhost:8080', 
        }, 
        function (error, response, body) {
            try {
                console.log("Request" + i + ":", response.statusCode, body);
                console.timeEnd("req" + i);
            } catch(e) {
                console.log(e, response);
            }
        });
        setTimeout(function(abort) {
            req.abort();
        },100);         
    } catch(e) {

    }
}

I hope somebody can help to fix that problem.

Thanks & Regards,
Dennis

#include <QCoreApplication>
#include <Tufao/HttpServer>
#include <QtCore/QUrl>
#include <Tufao/HttpServerRequest>
#include <Tufao/Headers>
#include <QThread>
#include <QTimer>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Tufao::HttpServer server;

    QObject::connect(&server, &Tufao::HttpServer::requestReady,
                     [](Tufao::HttpServerRequest &request,
                     Tufao::HttpServerResponse &response) {
        qDebug() << " new request";
        QTimer* timer = new QTimer();
        timer->setSingleShot(true);
        auto c = QObject::connect(timer, &QTimer::timeout,
                                  [&response, &request, timer]() {
            qDebug() << "write response";
            response.writeHead(Tufao::HttpResponseStatus::OK);
            response.headers().replace("Content-Type", "text/plain");
            response.end("Hello " + request.url().path().toUtf8());
            timer->deleteLater();
        });
        QObject::connect(&request, &Tufao::HttpServerRequest::close, [c]() {
            QObject::disconnect(c);
            qDebug() << "close connection";
        });
// Simulate some work and delay the response
        timer->start(1000);
    });

    server.listen(QHostAddress::Any, 8080);

    return a.exec();
}

You should also check documentation on safe signals.

Ok thanks for your help.