Jesús Fernández

Introducing the Qt Http Server

Published Friday January 25th, 2019
57 Comments on Introducing the Qt Http Server
Posted in Automation, C++, Dev Loop, Embedded, HTML vs Qt, Internet, Internet of Things, Labs | Tags: ,

First things first, Happy new year dear Qt users!

I’m sorry, I’m really late 🙁

Some time ago we decided to avoid repeating the same tedious code to write our own “Simple” Http Servers. So we started writing a Qt HTTP server with several essential features. The word simple is quoted because something planned to be “simple” evolved into a piece of code hard to maintain.
To give few numbers during the last two years, I wrote three times the same code to parse request headers, write response headers, deal with connections, … And I know, I’m not the only one who did the same (just check GitHub).

To take a look into the code, you can clone it with:

git clone --recursive https://codereview.qt-project.org/qt-labs/qthttpserver

You can manually build it using the last Qt release.
Before listing the features let’s show the mandatory hello world example:

#include <QtCore>
#include <QtHttpServer>

int main(int argc, char **argv) {
  QCoreApplication app(argc, argv);
  QHttpServer httpServer;
  httpServer.route("/", []() {
    return "Hello world";
  });
  httpServer.listen(QHostAddress::Any);
  return app.exec();
}

At this moment it’s a qt-labs project, and it’s not officially part of the Qt distribution, but at some point, we’ll add it.

Some features already implemented are:

  • HTTP 1.1
  • HTTPS but not yet merged
  • Customizable Routing
  • WebSockets integration
  • Error handling

I have planned some use-cases for this module:

  • Change the current embedded web server (and WebSockets) in the WebGL plugin to make it easy to create your own custom solutions based on the plugin.
  • Provide a way to serve an application built with WebAssamebly with live communication with the server via WebSockets and maybe using QtWebChannel.
  • Embed a web server into your application running on your desktop machine or embedded device.
  • Create a REST API
  • HTTP Server for QML

If you’re interested in this project, don’t forget to clone it and maybe if you’re concerned you can consider contributing or provide some feedback in QTBUG-60105.

Next week Mikhail Svetkin will write more about the routing API. Stay tuned 😀

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Automation, C++, Dev Loop, Embedded, HTML vs Qt, Internet, Internet of Things, Labs | Tags: ,

57 comments

Tomaz Canabrava says:

Why didn’t you guys used the awesome work started by Daniel Ncoletti that is stable, build on top of Qt, called Cuteyst?
If you didn’t please take a look at it as he did quite a lot of things for a Simple Qt based Http server and deservers the praise. 🙂

Jesús Fernández Jesús Fernández says:

Hi Tomaz,

Yes, we took a look to Cutelyst and it’s an awesome project. But the idea is not to replace Cutelyst is just to provide an alternative inside Qt.

Jason says:

I wrote a HTTP 1.1 server in Qt 10 years ago… Definitely late to the party, but glad we’ll all stop having to reinvent our own wheels.

One thing that I would love to see is JSON-RPC (a *very* simple standard, https://www.jsonrpc.org/specification ) added so that QObject-derived classes can communicate across servers transparently using signals/slots.)

Jesús Fernández Jesús Fernández says:

Hi Jason,

Thank you, really good suggestion. I added it to https://bugreports.qt.io/browse/QTBUG-60105. Feel free to follow this ticket.

Mihai says:

Please have a look at https://github.com/joncol/jcon-cpp
Very useful!

Jesús Fernández Jesús Fernández says:

Thank you.

I’ll take a look. But it sounds similar to QtWebChannel.

John says:

I used QJsonRpc in small project. Worked quite well.

Pi says:

Additional to routing, a pre and post handling for request processing would be nice ( like middleware in laravel or filters in java sevlet api).

Jesús Fernández Jesús Fernández says:

I’m not familiar with this concept. But I’ll take a look into it.

Thank you!

Aleksey says:

Cool, long awaited feature. However what about https://github.com/supamii/QttpServer? Do we really need to reinvent the wheel again?

Jesús Fernández Jesús Fernández says:

Hi Aleksey,

I checked the project during the development, it’s really cool. But we need to provide an alternative inside the Qt Project. We’re always open to hosting different open-source projects but it’s their decision to submit the request.

Alejandro Exojo says:

Ahem. No updates since March 2017. Are you sure this is a project to recommend?

Will says:

Any plans for HTTP/2 and QUIC support after HTTPS is working? Any notes on performance/benchmarking?

Jesús Fernández Jesús Fernández says:

Yes, we plan to support HTTP/2. About QUIC no plans yet, but it can be considered.

Jesús Fernández Jesús Fernández says:

About the performance, our HTTP server is not fully featured yet, so it’s unfair to compare it with others.

Petar says:

Great stuff! Reinvented the wheel few times myself already so I’m really happy to have this officially. M
any times I also used Node.js since it’s super easy to have a HTTP server with it, so really glad now I can cover anything from Qt really for backend and fronted development. Really useful for prototyping as well.

Jesús Fernández Jesús Fernández says:

Thank you!

jon says:

What about scalability ? any chance to get ready to use performance tune up based on epoll, kqueue and iocp…. I see qabstracteventdispatcher class, but most of the users are expecting to get “just use it and it works”

Jesús Fernández Jesús Fernández says:

One of the ideas we discussed was to have different backends. But our current target is to have something easy and feature complete.

Ali Bitek says:

A great example of a highly scalable HTTP server using the async I/O mechanisms provided by the Linux kernel:
– epoll I/O event notification (epoll_create1, epoll_ctl, epoll_wait): https://en.wikipedia.org/wiki/Epoll
– scatter/gather I/O (readv/writev): https://en.wikipedia.org/wiki/Vectored_I/O
is the getodac project: https://github.com/bog-dan-ro/getodac

A sneak peek:
– epoll loop: https://github.com/bog-dan-ro/getodac/blob/master/src/server/sessions_event_loop.cpp#L20
– vectored I/O: https://github.com/bog-dan-ro/getodac/blob/master/src/server/server_session.cpp#L249
– server loop usage: https://github.com/bog-dan-ro/getodac/blob/master/src/server/server.cpp#L447

The creator is the Qt for Android platform maintainer: https://wiki.qt.io/Maintainers#Platform_Maintainers

Vladimir says:

Major webservers have a long, long story of war with vulnerabilities. What about security in a new project? We don’t want news “10 billion devices running Qt now became a botnet”, do we?

Jesús Fernández Jesús Fernández says:

We are concerned about security, and my idea is to try to reuse reliable open source components as much as possible.

stlcours says:

Can we use it to transfer files? I hope it can. Thanks.

Jesús Fernández Jesús Fernández says:

Yes of course, but WebDAV is not supported yet.

teh 1 says:

When it comes to Qt, I’m just a user via the KDE project; I’m curious, what use-case does the Qt webserver serve? I’ve come here following the Phoronix article about Qt Http Server’s imminent release, but I haven’t the foggiest idea about how one might be used in a graphical toolkit.

Jesús Fernández Jesús Fernández says:

Hi teh,

The thing is Qt is not only a GUI framework. You can create console applications, servers, …

teh 1 says:

It seems my knowledge of the toolkit is severely lacking. Thank you and keep of the great work.

Jesús Fernández Jesús Fernández says:

No problem 🙂

JKSH says:

Hi teh 1, if you’d like to see what functionality Qt provides, see an overview at http://doc.qt.io/qt-5/qtmodules.html

Leo says:

Hi,

Very glad to know that, very good news.
Could you check http://nikhilism.com/post/2011/qhttpserver-web-apps-in-qt/ other for inspiration.
Thank you.

Jesús Fernández Jesús Fernández says:

Cool!

BTW the blog reader example is down 🙁

Mikhail Svetkin Mikhail Svetkin says:

I even forked this project several years ago and fixed some bugs 🙂
It was a really nice project.

Frank Meerkötter Frank Meerkötter says:

Great addition to the stack! Any reason why this project didn’t show up with the other playground repos at https://code.qt.io/cgit/?

Jesús Fernández Jesús Fernández says:

No idea.

angelus says:

Finally wait for the official web server, but still suggest to look at this project, simple, only rely on qtbase

https://github.com/HerikLyma/CPPWebFramework

Jesús Fernández Jesús Fernández says:

Nice thanks!

The server of the blog post uses only QtCore + QtNetwork with optional support for WebSockets using Qt WebSockets.

wu says:

whats different with “tufao” https://github.com/vinipsmaker/tufao

Jesús Fernández Jesús Fernández says:

I don’t see any comment about WebSockets support in Tufao.

T.Robin says:

Nobody seems to have mentioned http://stefanfrings.de/qtwebapp/index-en.html
I think this is also awesome Qt HTTP server project. Have you looked at this?

Jesús Fernández Jesús Fernández says:

Nop I did not, thank you!

John says:

>it’s not officially part of the Qt distribution, but at some point, we’ll add it.

We have heard exactly this about QBS just one year ago…
Later someone like Thiago Macieira will say: “How I hate, with a passion, non-standard web-servers.” (https://plus.google.com/+ThiagoMacieira/posts/DqTKdRGfuwR) And your lovely project will be deprecated…

No, until it will go an official LTS release, I will not touch it.

Jesús Fernández Jesús Fernández says:

Deprecating QBS was not Thiago’s decision AFAIK.

And I don’t entirely agree with his opinion about build systems. At least not talking about Build Systems, which a part of at some sort Autotools has no standard, (no cmake is not, and my opinion is it sucks). But we should embrace standards as much as possible to focus on the gaps not filled by the standard. For example, stop using our own containers instead of STL containers so we can focus on things like a graphics API or in this case an HTTP Server. And yes when networking is adopted by the STL, I think the same, Qt Network should be rewritten or dropped to use std::networking.

It’s a pity if you won’t touch it because it’s the perfect moment to give your feedback or suggestions.

John says:

>Deprecating QBS was not Thiago’s decision AFAIK

AFAIR he is QtCore maintainer. He intentionally declared such requirements for Qt6 build system which QBS can’t satisfy (like being available via packer managers in several major Linux ditro’s for 3+ years, sorry, but QBS developers don’t have time machine).

>It’s a pity if you won’t touch it because it’s the perfect moment to give your feedback or suggestions.

That is the price of broken trust in Qt decision making process. We can’t invest time in something that can be easily deprecated despite of being absolutely superior to all alternatives.

Qt is successful because of passionate and talented people behind some core ideas and products (moc and QtCreator’s editor without tabs are good examples), and company should believe in such ideas and people even if outsiders don’t believe in them right now. You are strong enough push away CMake with QBS.

Jesús Fernández Jesús Fernández says:

> AFAIR he is QtCore maintainer. He intentionally declared such requirements for Qt6 build system which QBS can’t satisfy (like being available via packer managers in several major Linux ditro’s for 3+ years, sorry, but QBS developers don’t have time machine).

Yes, he is the main maintainer of QtCore.

> That is the price of broken trust in Qt decision making process. We can’t invest time in something that can be easily deprecated despite of being absolutely superior to all alternatives.

I’m sorry to hear that.

Edward Welbourne Edward Welbourne says:

Thiago’s requirement for long-term use by several projects was clearly couched in terms of “by the time we make the switch” – and, had QBS seen adoption by projects other than Qt at that time, it would have had three years before Qt6’s release, which was the anticipated time for the switch; so what he asked for didn’t require a time machine. It only required projects taking up QBS when he wrote to still be using it three years later.

Mikhail Svetkin Mikhail Svetkin says:

Unfortunately we don’t have a standard c++ web servers.

John says:

We don’t have standard build system in C++ either, but someone have decided that CMake is a “standard” and should be used for Qt6 despite of being technically inferior to QBS or meson.

Jesús Fernández Jesús Fernández says:

> We don’t have standard build system in C++ either, but someone have decided that CMake is a “standard” and should be used for Qt6 despite of being technically inferior to QBS or meson.

I understand your anger, but this is not the place to complain about other tools/modules. Please use development@qt-project.org instead, your feedback is valuable but in a comment on this blog post is going to be almost useless.

Richard says:

Hi Jon, good to see you are passionate about Qbs. Please support the project with bug reports, contributions and by spreading the word. Even if the Qt Company doesn’t push it anymore, it is still alive.

fgutierrez says:

This step to include a http server in Qt is important!!

Christopher says:

Some bits of your API are fine, but I would like to take this opportunity to plug my own library: https://github.com/meltwater/served Please see the examples for API inspiration, note how natural the mapping is between HTTP verbs and handlers, and also how handlers can optionally support static routes “/person”, with named route parameters “/person/{name}” and optional regular expression matching “/person/{name}/{age:\d+}”. Query parameters can also be accessed just as easily. Finally, middleware can be used to insert common code before / after handlers are invoked for the purpose of logging and timing requests (most commonly).

Jesús Fernández Jesús Fernández says:

Our high-level API is inspired by Flask. We’ll provide more details in few days.

Soroush Rabiei says:

Very nice (: Personally I waited for this for a very, very long time, and even reinvented the wheel on several projects…
It would be great if we can add (thin and thick) layers over QHttpServer. maybe JSOR-RPC and SOAP?

I am given to understand that Qt 6 is not going to happen sooner than 2020. That’s too late for me. I hope we can use this as a third-party library before Qt 6 using Qt 5.9 series (though I can see some private API functions introduced in 5.12. makeIndexSequence).

Thanks

Jesús Fernández Jesús Fernández says:

> It would be great if we can add (thin and thick) layers over QHttpServer. maybe JSOR-RPC and SOAP?

It’s possible.

> That’s too late for me. I hope we can use this as a third-party library before Qt 6 using Qt 5.9 series (though I can see some private API functions introduced in 5.12.

You can customize your own HTTP Server using QAbstractHttpServer. You’ll lose some features but it’ll work.

d3fault says:

It’s a shame this is only GPLv3. Would be useful to expose APIs of existing LGPLv3-compliant software via REST.

I guess I’ll just keep reinventing the wheel. For anyone else needing to reinvent this wheel, you can use my extremely minimal HTTP/HTTPS server(s) as a starting point (it too is based on QTcpServer):

HTTP: https://gitlab.com/d3fault/autobackup/tree/master/Projects/Prototypes/QtHttpServer
HTTPS: https://gitlab.com/d3fault/autobackup/tree/master/Projects/Prototypes/QtHttpsServer

Doesn’t have nearly as many features as the official QHttpServer, but it’s simple/minimal enough that you can extend it to your needs… while also being more permissively licensed than GPLv3.

@d3fault: If you do not want to use GPLv3, there is the commercial option available as well.

Commenting closed.

Get started today with Qt Download now