QHttp
is a lightweight, asynchronous and fast HTTP library in c++14 / Qt5
,
containing both server and client side classes for managing connections,
parsing and building HTTP requests and responses.
- the objective of
QHttp
is being light weight with a simple API for Qt developers to implement RESTful web services in private (internal) zones. more - by using
std::function
andc++14 generic lambda
, the API is intentionally similar to the Node.js' http module. Asynchronous and non-blocking HTTP programming is quite easy withQHttp
. have a look at sample codes. - the fantastic nodejs/http-parser
(which is a single pair of
*.h/*.c
files) is the only dependency of theQHttp
.
attention: c++14 is the minimum requirement for version 3.0+ please see releases
This project was inspired by
nikhilm/qhttpserver effort to
implement a Qt HTTP server. QHttp
pushes the idea further by implementing
client side classes, better memory management, a lot more Node.js-like API, ...
a HelloWorld HTTP server by QHttp
looks like:
int main(int argc, char** argv) {
QCoreApplication app(argc, argv);
using namespace qhttp::server;
QHttpServer server(&app);
server.listen( // listening on 0.0.0.0:8080
QHostAddress::Any, 8080,
[](QHttpRequest* req, QHttpResponse* res) {
// http status 200
res->setStatusCode(qhttp::ESTATUS_OK);
// the response body data
res->end("Hello World!\n");
// automatic memory management for req/res
});
if ( !server.isListening() ) {
qDebug("failed to listen");
return -1;
}
return app.exec();
}
to request weather information by HTTP client:
int main(int argc, char** argv) {
QCoreApplication app(argc, argv);
using namespace qhttp::client;
QHttpClient client(&app);
QUrl weatherUrl("http://wttr.in/tehran");
client.request(qhttp::EHTTP_GET, weatherUrl, [](QHttpResponse* res) {
// response handler, called when the incoming HTTP headers are ready
// gather HTTP response data (HTTP body)
res->collectData();
// when all data in HTTP response have been read:
res->onEnd([&]() {
writeTo("weather.html", res->collectedData());
// done! now quit the application
qApp->quit();
});
// just for fun! print incoming headers:
qDebug("\n[Headers:]");
res->headers().forEach([](auto cit) {
qDebug("%s : %s", cit.key().constData(), cit.value().constData());
});
});
// set a timeout for the http connection
client.setConnectingTimeOut(10000, []{
qDebug("connecting to HTTP server timed out!");
qApp->quit();
});
return app.exec();
}
- the only dependencies are:
Qt5
,c++14
and thehttp-parser
- both TCP and UNIX (local) sockets are supported as backend.
- separate
namespace
s for server and client classes. - HTTP server classes: QHttpServer, QHttpConnection, QHttpRequest and QHttpResponse.
- optional HTTP client classes: QHttpClient,
QHttpRequest and
QHttpResponse. the client classes can be
disabled at build time by commenting
QHTTP_HAS_CLIENT
in common.dir - automatic memory management of objects. Instances of connections, requests and replies will be deleted automatically when socket drops or disconnected.
- PIMPL (Private implementaion) to achieve better ABI compatibility and cleaner API and faster compile time.
- Asynchronous and non-blocking. You can handle thousands of concurrent HTTP connections efficiently by a single thread, although a multi-threaded HTTP server is easy to implement.
- high throughput, I have tried the
QHttp
and gason++ to implement a REST/Json web service on an Ubuntu VPS (dual core + 512MB ram) with more than 5800 connections per second (stress test). On a MacBook Pro (i5 4258U, 8GB ram),QHttp
easily reaches to more than 11700 connections / second. GenerallyQHttp
is 1.5x ~ 3x faster thanNode.js
depending on your machine / OS. - Easily portable where ever
Qt5 / c++14
works. Tested under:- Linux Ubuntu 12.04 ~ 16.04 LTS, g++ 5.3+
- OS X 10.9+, clang 3.7+
- Windows 7/8.1, msvs2015 / mingw (g++ 6.1)
instructions:
# first clone this repository:
$> git clone https://github.com/azadkuh/qhttp.git
$> cd qhttp
# prepare dependencies:
$qhttp/> ./update-dependencies.sh
# now build the library and the examples
$qhttp/> qmake -r qhttp.pro
$qhttp/> make -j 8
As QHttp
is asynchronous and non-blocking, your app can handle
thousands of concurrent HTTP connections by a single thread.
in some rare scenarios you may want to use multiple handler threads (although it's not always the best solution):
- there are some blocking APIs (QSql, system calls, ...) in your connection handler (adopting asynchronous layer over the blocking API is a better approach).
- the hardware has lots of free cores and the measurement shows that the load
on the main
QHttp
thread is close to highest limit. There you can spawn some other handler threads.
src/
: holds the source code ofQHttp
. server classes are prefixed byqhttpserver*
and client classes byqhttpclient*
.private/
: Private classes of the library.
3rdparty/
: will containhttp-parser
source tree as the only dependency. this directory is created by setup. see also: setup.example/
: contains some sample applications representing theQHttp
usage:helloworld/
: the HelloWorld example ofQHttp
, both server + client are represented. see: README@helloworldbasic-server/
: a basic HTTP server shows how to collect the request body, and respond to the clients. see: README@basic-serverkeep-alive
: shows how to keep an http connection open and transmitting many requests/responses. see: README@keep-alivepost-collector
: another server example shows how to collect large data by POST requests. see: README@post-collector
tmp/
: a temporary directory which is created whilemake
ing the library and holds all the.o
,moc files
, etc.
xbin/
: all the executable and libraries will be placed on this folder by build system.
- Implementing a lightweight and simple HTTP server/client in Qt with Node.js
like API, is the main purpose of
QHttp
. - There are lots of features in a full blown HTTP server which are out of scope
of this small library, although those can be added on top of
QHttp
. - The client classes are by no mean designed as a
QNetworkAccessManager
replacement.QHttpClient
is simpler and lighter, for serious scenarios just useQNetworkAccessManager
which supports proxy, redirections, authentication, cookie jar, ssl, ... - I'm a busy person.
If you have any ideas, critiques, suggestions or whatever you want to call it, please open an issue. I'll be happy to hear different ideas, will think about them, and I try to add those that make sense.
Distributed under the MIT license. Copyright (c) 2014, Amir Zamani.