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

Overview

!!! I can no longer maintain this project. If you're interessed, please contact me and I can move the projetct to you !!!

Tufão - an asynchronous web framework for C++ built on top of Qt

Join the chat at https://gitter.im/vinipsmaker/tufao

Tufão is a web framework for C++ that makes use of Qt's object communication system (signals & slots). It features:

  • High performance standalone server
  • Cross-plataform support
  • Good documentation
  • Support modern HTTP features
    • Persistent streams
    • Chunked entities
    • 100-continue status
    • WebSocket
  • HTTPS support
  • Flexible request router
  • Static file server with support for conditional requests, partial download and automatic mime detection
  • Plugin-based server to allow change the running code without restart the application
  • Flexible and secure session support
  • QtCreator's plugin to allow create new applications rapidly
  • Lots of tests
  • Timeout support
  • C++11

You can generate documentation from the source code using Doxygen. The documentation will be put on the doc folder in the html and tex formats. There is also experimental support for Qt compressed help files.

LICENSE

The library is under the LGPLv2 and public header files, documentation and examples are under MIT license.

The Tufão logo is licensed under [Creative Commons Attribution 3.0 Unported] (http://creativecommons.org/licenses/by/3.0/).

The library is dynamic linked against Qt and include code from Boost.Http parser. Qt library is licensed under LGPL and Boost.Http is licensed under the Boost Software License.

So, you can create commercial applications (the only restriction is that if you do any modifications to Tufão, these modifications must be redistributed).

Getting dependencies

$ git submodule update --init

BUILD

Make sure you have Qt and CMake installed and with the PATH to its executables set, then create a folder for the build and, from there, run:

$ cmake OPTIONS path_to_source_dir
$ make MAKEOPTIONS

OPTIONS can be null or have a combination of the following values:

  • -DCMAKE_INSTALL_PREFIX=${INSTALLDIR} sets the directory where to install Tufão.
  • -DCMAKE_BUILD_TYPE=Debug
  • -DCMAKE_BUILD_TYPE=Release
  • -DCMAKE_BUILD_TYPE=RelWithDebInfo
  • -DCMAKE_BUILD_TYPE=MinSizeRel
  • -DLIB_SUFFIX=${LIB_SUFFIX} set the suffix for the install destination. If you are compiling Tufão under a 64 bit system using a 32 bit "environment", maybe you want to set this variable to 32, then Tufão libs will be installed under "${INSTALLDIR}/lib32". This setting is highly dependent on your operating system conventions and I do not try to put any auto magic detection.
  • -DGENERATE_DOC=YES generate documentation using Doxygen
  • -DENABLE_TESTS=YES generate and run tests

OPTIONS available on Windows:

  • -G"MinGW Makefiles" to generate Makefiles for use with MinGW environment
  • -G"Visual Studio 10" to generate project files for Visual Studio 10

MAKEOPTIONS can be null or have a combination of the following values:

  • install installs Tufão
  • DESTDIR=${PKGDIR} sets the directory where to install Tufão. This options should be used if you intend to package Tufão to set the package directory. To choose another installation directory, see options in OPTIONS, above.

Example:

$ cmake -DCMAKE_INSTALL_PREFIX=/usr
$ make DESTDIR=pkg install

NOTE: Qt 5.0 or later is required for 1.x series. Qt 4.7 or later is required to 0.x series.

NOTE: If you intend to create a CPack-based installer, just run:

# To create a binary distribution:
cpack -C CPackConfig.cmake

# To create a source distribution:
cpack -C CPackSourceConfig.cmake

# To create a Windows NSIS-based installer:
cpack -GNSIS

Documentation

To generate the documentation, just run doxygen using Doxyfile as configuration file and the documentation will be generated in the folder doc. The documentation is available in the following formats:

  • HTML: Always generated. It should be in the doc/html folder.
  • latex: You can use this format to generate a pdf. Just run make inside the doc/latex folder.
  • Qt Compressed Help file: If you have qhelpgenerator binary tool in the system PATH, then the file is generated when you run doxygen and should be in doc/qch/tufao.qch. If you have qhelpgenerator tool installed, but not configured in the system PATH, but still want to generate the documentation in this format, just run the tool using doc/html/index.qhp as input file.

Tests

Tufão also have a lot of code to test its correctness. These codes are based on QTestLib and generate self-contained executables. There is also some CTest rules and integration with the CMake build. To run the tests, just execute:

make tests

Or, if you don't want to use Makefiles:

ctest

In Visual Studio, the target RUN_TESTS is created.

CTest integrates with CDash to allow developers to centralize the tests result. You can send the results to CDash running the Experimental target:

make Experimental

You can see the Tufão testing log at Tufao CDash project's page.

INSTALL

The default install prefix is /usr/local, if you don't intend to change it, just run, after build:

# make install

To install to a different prefix, run:

$ cmake -DCMAKE_INSTALL_PREFIX=${DESTDIR}
$ make install

NOTE: You may need to run ldconfig after installation depending on your system.

USAGE

To use Tufão in your Qt projects, just edit your .pro file and add the line:

CONFIG += C++11 TUFAO1

You can find some examples in the examples folder.

If you're planning to use OS X, then the following line is also required, as reported by some users:

QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7

Tufão has PKG-CONFIG support also. Its module name is 'tufao1'.

If you want use Tufão in other build system, just add the compiler option -ltufao1.

You can also see Tufão documentation integrated in QtAssistant.

NEWS

Version 1.4

  • Replaces Ryan Dahl's HTTP parser. Now Boost.Http parser is used.
  • Fixes HTTP pipelining support.

Version 1.3

  • Added canHandleRequest to HttpFileServer

Version 1.2

  • New class to handle REST api introduced (thanks to Timothy Reaves)
    • The class has its own plugin system, partly incompatible with Tufão's default
  • Tufão's plugin system improved to better track files deletion.
    • It requires no code changes, but you still need to do a one-line change to the config file, because I was worried about backwards compatibility.
    • See HttpPluginServer::setConfig for details

Version 1.1

  • Add ability to ignore a set of SSL errors in WebSocket
  • Documentation updates
  • Bugfix in AbstractHttpServerRequestHandler (thanks to Benjamin Zeller)
  • Updated Ryan Dahl's HTTP parser to version 2.2.1

Version 1.0

  • The project finally have a logo (made by me in Inkscape)
  • Deprecated API was removed
  • Url and QueryString removed in favor of QUrl
  • Headers refactored to inherit from QMultiHash instead of QMultiMap
  • HttpServerResponse
    • Constructor's options argument is optional now
    • setOptions method added
    • Constructor takes a reference to a QIODevice instead a pointer
  • HttpServerRequest
    • Constructor takes a reference to a QAbstractSocket instead a pointer
    • socket method returns a reference instead a pointer
    • url returns a QUrl
    • data signal was changed and you must use readBody method to access body's content.
    • the upgrade's head data is accessed from the request body from now on
    • now the object auto-disconnects slots from data and end signals right before emit ready
    • setCustomData and customData methods added
      • Now HttpServerRequestRouter use these methods to pass the list of captured texts
  • HttpServer uses reference instead of pointers in several places
  • AbstractHttpServerRequestRouter refactored to explore lambdas features.
  • Tufão's plugin system fully refactored
    • It's using JSON files as configuration
  • AbstractHttpServerRequestHandler::handleRequest
    • It uses references instead pointers
    • It receives 2 arguments instead of 3
  • One more abstraction to sessions created to explore lambdas
  • WebSocket
    • startServerHandshake is taking references instead pointers
  • LESS POINTERS and MORE REFERENCES
    • This change exposes a model more predictive and natural
    • I'm caring less about Qt style and more about C++ style
      • But don't worry, I'll maintain a balance
  • Using scoped enums
  • HttpFileServer uses/sends mime info
  • Interfaces don't inherit from QObject anymore, so you can use multiple inheritance to make the same class implement many interfaces
  • HttpUpgradeRouter introduced
    • HttpServer::setUpgradeHandler also
  • Updated QtCreator plugin to work with QtCreator 2.7.0 and Qt 5

Version 0.6:

  • HttpServerRequest
    • setUrl added
  • UrlRewriterHandler added
  • HttpUpgradeRouter added
  • headers can be "streamed" to QDebug objects

Version 0.5:

  • WebSocket
    • peerAddress() method added
    • peerSocket() method added

Version 0.4:

  • Using CMake build system
    • Changes to allow parallel Tufão installations (if major versions differs)
    • Added PKGCONFIG support
  • Session support
  • Better documentation

Version 0.3

  • More application templates in QtCreator Tufão's plugin
  • Class to serve static files with support for conditional requests and byte-range requests
  • Robust request router added
  • HTTP plugin server added
  • Using newer version of Ryan Dahl's HTTP parser
  • Changed license from public headers to MIT
  • MSVC support
  • Some minor improvements

Version 0.2:

  • Code is more stable
  • Documentation improved
  • HttpServerResponse is easier to use
  • WebSocket support
  • TUFAO_VERSION_MAJOR and TUFAO_VERSION_MINOR macros added
  • QtCreator plugin
  • New examples

ROADMAP

Here is a small roadmap for Tufão:

1.4:

  • RPC support
  • Service discovery and description support

1.5:

  • Forms and file uploads
Issues
  • Threading Support

    Threading Support

    It would be nice to have a ThreadedHttpPluginServer, so the server can scale up when lots of requests come in at the same time.

    A possible problem with this is the handling of the loaded plugins, each thread might need to load and unload them itself.

    enhancement 
    opened by bzeller 66
  • Visual Studio 2013 Support

    Visual Studio 2013 Support

    I have tryed to compile Tufao 1.0 using VS 2013 and I run into some problems:

    • CMake looks for the CXX11 flag but, as far as I know, such flag doesn't exists in VS (and it is not required)
    • CMake adds the flag -Wextras that doesn't exists in VS 2013

    After fixing both problems the compiler has problems with the definition of a template in this struct (priv/httpserverrequest.h line 99):

    struct RawData
    {
        template<int N>
        constexpr RawData(const char (&data)[N]) :
            data(data),
            size(N - 1)
        {}
    
        const char *data;
        int size;
    };
    

    Any plan to support VS 2013? I'm doing something wrong at configuration level?

    My CMake command is:

    cmake .. -DCMAKE_INSTALL_PREFIX=c:/Qt/Qt5.3.0/5.3/msvc2013_64_opengl/ -DCMAKE_BUILD_TYPE=Release -G "NMake Makefiles"
    

    Thanks,

    David

    opened by dasloop 10
  • NO_ERROR in websocket.h

    NO_ERROR in websocket.h

    First of all, thanks for an awesome library.

    Here's a small annoyance: Currently websocket.h uses NO_ERROR as the first item in the Websocket::Error enum. This causes problems when building on windows as winerror.h does a #define NO_ERROR 0L. It fails to build unless the user is very careful not to include any files that end up including any windows headers before including <WebSocket>. I suggest you rename the enum item.

    Thanks.

    bug 
    opened by tpatja 8
  • not possible to use Websocket as a client with a self-signed server certificate

    not possible to use Websocket as a client with a self-signed server certificate

    Currently the Websocket class does not provide a means to ignore any SSL errors.

    This is usually only a problem when using a QSslSocket as a client with a server that uses a self-signed certificate (need to ignore QSslError::SelfSignedCertificate). Additionally on some builds of QT 4.x on windows, QT may report QSslError::NoError and forces the user to ignore it in order to continue (bug in QT).

    I suggest a new method WebSocket::setExpectedSslErrors(QList<QSslError>&) which would store the list in a member variable. In case all the error codes of SSL errors QT reports in WebSocket::onSslErrors are in the expected list, call qobject_cast<QSslSocket*>(sender())->ignoreSslErrors(m_ignoreList), otherwise do what it does now.

    To clarify, it is possible to use the current Websocket class with a self-signed certificate as a server, but not as a client.

    enhancement 
    opened by tpatja 7
  • Cannot compile on QT 5 MinGW windows XP

    Cannot compile on QT 5 MinGW windows XP

    Hi, (issue copied from code.google, I saw that git is new repo)

    Maybe will be better when you read this stackoverflow topic: http://stackoverflow.com/questions/15029894/qt-cant-add-external-package

    I have also tried precompiled binaries but they need Qt 4. So I don't know what to do.

    Notice that on linux 64bit Qt 5.0.1 it is working fine. I just added whole tufao source into my project and everything works fine. On windows this trick doesn't work. I get hounded of errors "undefined reference...".

    Regards

    invalid 
    opened by dibok 7
  • can't link apps in debug mode on VS

    can't link apps in debug mode on VS

    I've built Tufao 1.3.7 on Windows with Visual Studio 2013, using cmake -DCMAKE_INSTALL_PREFIX=c:/dev/tufao/install .. cmake --build . --target install

    This generates tufao1d.lib/dll, but the tufao1.prf file added to the Qt install only looks for a release build (tufao1.lib/dll), so it's impossible to build anything in debug mode.

    opened by hmoffatt 6
  • Any doc on using this server with a redis client API?

    Any doc on using this server with a redis client API?

    Hi, I'd like to try this framework with a redis DB store behind. as I know, this framework is using the Qt event loop, while this api ( https://github.com/nekipelov/redisclient ) is using the boost.asio event loop. It seems to me that it is impossible to integrate two frameworks with two different kinds of event loop. Could you please give me some advice? Thanks & Regards, Simon

    question 
    opened by minixxie 6
  • Every handler connect signal data(QByteArray) and end() of every request

    Every handler connect signal data(QByteArray) and end() of every request

    Hi everyone, I have many handlers inherit Tufao::AbstractHttpServerRequestHandler. In each handler, I have slots: onData(QByteArray) connect with signal data(QByteArray) and onEndRequest() connect with signal end() of each request comes to handler. I also have router to route request to right handler. But every time new request comes, it emits signal data(QByteArray), signal end() and all of my handlers catch these signal and connect to their slots. Can you have a try to give an answer? thanks a lot. Edited: I use Tufao on branch 0.x for Qt 4.7

    question 
    opened by tnm0113 6
  • Fast requests hanging Tufao

    Fast requests hanging Tufao

    I use tufao for playing video and audio from libtorrent. So, when I make frequently requests, like frequently switching audio files, tufao starts hanging. I added additional logs in sources and here what have I got:

    virtual void Tufao::TcpServerWrapper::incomingConnection(qintptr) void Tufao::HttpServer::onNewConnection(qintptr) virtual bool Tufao::HttpConnectionHandler::incomingConnection(qintptr) virtual void Tufao::TcpServerWrapper::incomingConnection(qintptr) void Tufao::HttpServer::onNewConnection(qintptr) virtual bool Tufao::HttpConnectionHandler::incomingConnection(qintptr)

    As You see, starting from Tufao::TcpServerWrapper::incomingConnection(qintptr) we have recirculation. In 10 seconds I've got more than 10 000 of calls of these methods.

    So, can it be fixed and in what may be problem? In tufao or in Qt?

    opened by cijic 6
  • 204 No Content on HTTP/1.1 generates an empty chunk

    204 No Content on HTTP/1.1 generates an empty chunk

    My code is doing:

    response.writeHead(Tufao::HttpResponseStatus::NO_CONTENT);
    response.end();
    

    This generates a 204 No Content, with Transfer-Encoding: chunked and includes and empty chunk '0\r\n\r\n'. But this is not valid according to the RFC2616:

    10.2.5 204 No Content ... The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.

    The Microsoft .NET HTTP Client is upset by the extra chunk being sent. The only work-around is to disable keep-alive by adding Connection: close to the request.

    bug 
    opened by zecke 6
  • Loop parsing POST contains request with two

    Loop parsing POST contains request with two "readyRead"

    Tufao version 1.4.1

    I discovered problem with some browsers. Create simple web-server handled POST request. If the client sends data to two packages I take loop parsing request in void HttpServerRequest::onReadyRead().

    Example:

    First buffer from priv->socket.readAll();

    POST https://127.0.0.1:45678/sign HTTP/1.1
    Referer: https://somesite.com/test/
    Origin: https://somesite.com
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/538.1 (KHTML, like Gecko) QupZilla/1.8.9 Safari/538.1
    Content-Type: application/xml
    Accept: */*
    Content-Length: 47
    Accept-Language: ru-RU,ru;q=0.8
    Connection: Keep-Alive
    Accept-Encoding: gzip, deflate
    Host: 127.0.0.1:45678
    
    

    Second buffer must be

    123456789 AUTH
    DATE=2015-02-17 17:59
    IP=1.2.3.4
    

    But he had to be read because we are still spinning in the processing cycle of the first buffer is constantly falling on the condition:

            case http::token::code::error_insufficient_data:
                    continue;
    
    opened by AlexObukhoff 5
  • Data is truncated when using WebSocket to transfer data over 128k

    Data is truncated when using WebSocket to transfer data over 128k

    version:1.4.5 protocol :websocket

    When the amount of data over 128K, slot "newMessage" can only receive most of the data. I found the last part of the data is in priv->payload, so I modified the code.

    websocket.cpp

    if (priv->frame.fin()) {
            // FINAL
            if (priv->frame.isControlFrame()) {
                evaluateControlFrame();
            } else {
                if (priv->frame.opcode() == FrameType::CONTINUATION) {
                    // CONTINUATION
                    QByteArray chunk(priv->fragment);
                    chunk.append(priv->payload); // add this line,  the last part of data
                    priv->fragment.clear();
                    priv->payload.clear();  // also clear
                    emit newMessage(chunk);
                } else {
                    // NON-CONTINUATION
                    QByteArray chunk(priv->payload);
                    priv->payload.clear();
                    emit newMessage(chunk);
                }
            }
        } 
    

    It seems that everything is ok Please help to check whether this modification is feasible,thanks

    opened by harryhdk 2
  • What is the maximum amount of data for a single transfer?

    What is the maximum amount of data for a single transfer?

    Question: During self-test,the Web transfers data to the application through the tufao library,But when the amount of transmitted data is 128KB, the application does not receive the data message through the signal "newMessage", so I want to ask:“What is the maximum amount of data for a single transfer?”

    Thanks!

    bug 
    opened by Lucas2525117 7
  • How to interact with HTML file

    How to interact with HTML file

    Because I have a very good-looking HTML page, how can I transfer values to the HTML page? Thank.

    I'm sorry to see that you are not maintaining the project. Thank you very much for your contribution to this project

    opened by FineBlack 0
  • server close connection after server response client

    server close connection after server response client

    hi I use tufao 0.8.9 version. the problem is http client post a long polling request, and after waiting more than 5 minutes server response client , but the same time the connection is close . sounds somewhere timeout parameter set ?

    question 
    opened by mozeat-sun 2
  • Create Conan package

    Create Conan package

    It is possible to install Qt via Conan package manager [0], so with this dependency available, it would be really cool to fetch Tufao too for your local project simply with conan install .

    [0] https://bintray.com/bincrafters/public-conan/qt%3Abincrafters

    opened by Talkless 0
Owner
Vinícius dos Santos Oliveira
Vinícius dos Santos Oliveira
🌱Light and powerful C++ web framework for highly scalable and resource-efficient web application. It's zero-dependency and easy-portable.

Oat++ News Hey, meet the new oatpp version 1.2.5! See the changelog for details. Check out the new oatpp ORM - read more here. Oat++ is a modern Web F

Oat++ 5.5k Jun 27, 2022
C++ peer to peer library, built on the top of boost

Breep What is Breep? Breep is a c++ bridged peer to peer library. What does that mean? It means that even though the network is constructed as a peer

Lucas Lazare 110 Jun 16, 2022
Mongoose Embedded Web Server Library - a multi-protocol embedded networking library with TCP/UDP, HTTP, WebSocket, MQTT built-in protocols, async DNS resolver, and non-blocking API.

Mongoose - Embedded Web Server / Embedded Networking Library Mongoose is a networking library for C/C++. It implements event-driven non-blocking APIs

Cesanta Software 8.5k Jun 29, 2022
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.

Restbed Restbed is a comprehensive and consistent programming model for building applications that require seamless and secure communication over HTTP

Corvusoft 1.7k Jun 21, 2022
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.

Restbed Restbed is a comprehensive and consistent programming model for building applications that require seamless and secure communication over HTTP

Corvusoft 1.4k Mar 8, 2021
Enabling services on your device 66 Jun 23, 2022
A Tcp/Ip stack implementation on top of Solarflare ef_vi, and a C++ headers only framework for tcp multiplexing client/server.

Efvitcp Efvitcp is a tcp library using Solarflare ef_vi interface on linux, and also a tcp multiplexing framework for both C++ client and server progr

Meng Rao 17 Jun 9, 2022
Drogon: A C++14/17 based HTTP web application framework running on Linux/macOS/Unix/Windows

English | 简体中文 | 繁體中文 Overview Drogon is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web applicat

An Tao 7.4k Jun 19, 2022
Lightweight Python Web framework

fly Python lightweight web application framework. Event driven architecture. Usable as Web server and Application server. Lightweight and fast. Since

tatsuya.s 17 Dec 18, 2021
C++ Web Framework REST API

✨ wfrest: C++ Web Framework REST API Fast, efficient, and easiest c++ async micro web framework based on C++ Workflow. ?? Contents wfrest: C++ Web Fra

null 376 Jun 28, 2022
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

Welcome! The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design

Microsoft 6.9k Jun 22, 2022
Cross-platform, efficient, customizable, and robust asynchronous HTTP/WebSocket server C++14 library with the right balance between performance and ease of use

What Is RESTinio? RESTinio is a header-only C++14 library that gives you an embedded HTTP/Websocket server. It is based on standalone version of ASIO

Stiffstream 863 Jun 23, 2022
A C library for asynchronous DNS requests

c-ares This is c-ares, an asynchronous resolver library. It is intended for applications which need to perform DNS queries without blocking, or need t

c-ares 1.4k Jun 22, 2022
Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution

CppServer Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and

Ivan Shynkarenka 848 Jun 26, 2022
Asynchronous networking for C

Overview Dyad.c is an asynchronous networking library which aims to be lightweight, portable and easy to use. It can be used both to create small stan

null 1.3k Jun 23, 2022
C++ Parallel Computing and Asynchronous Networking Engine

As Sogou`s C++ server engine, Sogou C++ Workflow supports almost all back-end C++ online services of Sogou, including all search services, cloud input method,online advertisements, etc., handling more than 10 billion requests every day

Sogou Open Source 8.4k Jun 24, 2022
Asynchronous gRPC with Boost.Asio executors

asio-grpc This library provides an implementation of boost::asio::execution_context that dispatches work to a grpc::CompletionQueue. Making it possibl

Dennis 126 Jun 24, 2022
A Lightweight and fully asynchronous WebSocket client library based on libev

libuwsc(中文) A Lightweight and fully asynchronous WebSocket client library based on libev for Embedded Linux. And provide Lua-binding. Why should I cho

Jianhui Zhao 283 Jun 8, 2022
A C++ async HTTP client library to use in asynchronous applications while communicating with REST services.

libashttp An asynchronous HTTP library using Boost.ASIO as the backend. This project is licensed under: Usage Here is a example usage which is taken f

Tolga Hoşgör 51 Dec 19, 2021