This is a web framework written in C++ that uses multiple underlying protocols.
It's being developed. News will be shared on Telegram.
This project on:
Look at the Core Readme file for the core concepts of the project.
Feature / Standard | Description | Status |
---|---|---|
URI | WHATWG-Compliant URL Parser | 95% |
UTS #46 | Unicode IDNA Compatibility Processing | 70% |
UTS #15 | Unicode Normalization Forms | 70% |
Routing System | HTTP Routing with C++ APIs (static and dynamic router) | ✅ |
Mustache DSL | A modified version exists | ✅ |
JSON | A Concept exits + A Wrapper for rapidjson library | ✅ |
CGI Client | Common Gateway Interface | ✅ |
CGI Server | Run other CGI application | ❌ |
FastCGI Client | It's based on CGI | 40% |
FastCGI Server | Pass requests to other FastCGI applications | ❌ |
HTTP 1.0 Server | HTTP 1.0 and HTTP 1.1 Server (using boost::Beast) | ✅ (buggy) |
HTTP/2 Server | HTTP 2.0 | ❌ |
HTTP/3 Server | HTTP 3.0 and the QUIC protocol | ❌ |
HTTP 1.0 Client | HTTP 1.0 and HTTP 1.1 client | ❌ |
HTTP/2 Client | HTTP 2.0 client | ❌ |
HTTP/3 Client | HTTP 3.0 with the QUIC protocol client | ❌ |
IO Task Scheduler | I/O task manager toolsets (io_uring, ...) | 10% |
Async tools | Multithreading, Parallelism, ... toolsets | 10% |
Base64 | Modified version of modp_b64 exists | ✅ |
GZip | Using zlib | ✅ |
Brotli | Using Google's brotli library | ✅ |
LRU Cache | LRU Cache | ✅ |
Caching | Some caching exists but not enough | 60% |
Strings | String utilities | 80% |
Unicode String | Needed Unicode string utilities (ustring, iterators, ...) | 40% |
HTTP Headers | HTTP Header Value Parsers/... for each HTTP header | 10% |
HTTP Cookies | Cookies APIs | 90% |
IP Address Utilities | IP Address Utilities (Parsers, APIs, ...) | ✅ |
Logging | Logging Concepts + multiple implementations exists | ✅ |
Validators | Validation APIs | 20% |
Socket Utilities | Socket APIs | 30% |
Database APIs | Database Utilities | 40% |
SQLite Wrapper | SQLite wrapper | ✅ |
SDK: Logging Viewer | Read and assess logs | ❌ |
SDK: Router Editor | An IDE for routes | ❌ |
SDK: Database Manager | An IDE for the databases | ❌ |
There are many other features that are not presented in the table and there are a lot more that we're dreaming on having, and God willing, we know we can do so given enough time.
The project is still in development, but this framework should be able to help you with these kinda projects someday:
The most question that I get while talking to other developers is why C++? Well there are multiple answers:
A Simple CGI application
auto page_one() {
return "Page 1";
}
struct web_app {
enable_owner_traits<default_traits> et; // holds the allocator, logger, ...
dynamic_router router{et}; // Helps with the routing, could be used as an app too
web_app() {
// register your routes
router += router / endpath >> []() noexcept {
return "main page";
};
router += router / "page" / "one" / endpath >> page_one; // free functions
router += router / "cgi-bin" % "cgi-hello-world" >> [] {
return "Hello world";
};
// "/about" or "/cgi-bin/cgi-hello-world/about"
router += (router % "about") || (router / "cgi-bin" / "cgi-hello-world" % "about") >>
[](context& ctx) {
return ctx.view("about.html");
};
}
auto operator()(auto&& req) {
return router(req);
}
};
int main() {
// CGI Protocol
webpp::http::cgi<web_app> cgi_application;
// run the app:
return cgi_application();
}
There are a lot more features, designed to be used in a modular way:
// Could be a sub-app of another sub-app that has no
// clue how the server works or what kinda protocol (CGI/FastCGI/Self Served/...) is being used
struct app {
using namespace webpp;
using namespace webpp::http;
app() {
// Tell the view manager where to look for the files
view_man.view_roots.emplace_back("./public");
view_man.view_roots.emplace_back("./static");
}
response index(context& ctx) {
return "Main Page";
}
response api(request const& req) {
json::document doc{req}; // You can choose which JSON lib you want to use in the background
doc["user"] = "username";
doc["token"] = "some token";
return doc;
}
response about(request const& req) {
response res{req};
res.headers = http::status_code::ok;
res.headers["Content-Type"] = "text/html";
res.body = "About Page";
return res;
}
auto page_one() {
return view_man.view("pages/page1.mustache"); // We have mustache built-in
}
auto hello() {
return view_man.view("pages/hello.html");
}
private:
enable_traits_for<views::view_manager<>> view_man;
};
// for demonstration purposes only, we could've done this a lot easier
// The Server calls this class (the operator() of this class) for every request
// BTW, the `router` can totally replace this, you can inherit from it even
struct app_controller {
using namespace webpp;
using namespace webpp::http;
private:
enable_traits_for<dynamic_router> router;
app my_app;
public:
app_controller() {
// register your app
router.objects.emplace_back(my_app);
// register the routes:
router += router / endpath >> &app::index;
router += router / "page" % "one" >> &app::page_one;
router += router / "api" / "v1" >> &app::api;
router += router / "cgi-bin" % "cgi-hello-world" >> &app::hello;
router += (router / "about") || (router / "cgi-bin" / "cgi-hello-world" / "about") >> &app::about;
}
// This operator will be called for each request
HTTPResponse auto operator()(HTTPRequest auto&& req) {
return router(req);
}
};
int main() {
webpp::beast<app_controller> server;
server
.enable_sync() // call the app in a thread-safe manner (might be removed in the future)
.address("127.0.0.1") // listen on localhost
.port(8080); // on http port
// Start the server and share your website to the world like there's no tomorrow
return server();
}
You can help us develop this project if you're familiar with C++ programming language and web development. Even if you're not really good at web development, but you know C++ very well, then we have lots of things that you can help with which doesn't have anything to do with web development directly.
In the examples directory you can find examples. That's not much but it'll give you they high level viewpoint. Take a look at them, and you can be sure that we'll try to write tests for all of them; so if you read tests, you'll learn even more about the project.
Benchmarks are done for us developers so we know which tool/class/implementation/library/framework/solution that we choose is the best. See some benchmarks in the benchmark directory.
We don't have a documentation/tutorial/guide at this point. You can help us write one. We're just too busy writing the code that we don't have much time writing documentations at this point. But you can be sure from the point that this project becomes production-ready, we'll have documentations.
# Download
git clone https://gitlab.com/webpp/webpp.git --depth=1
cd webpp/
# Configure CMake (default uses ninja and creates 'build' directory)
cmake --preset=default
# Build Examples (See /examples directory for the list of them)
cmake --build --preset=cgi-application
cmake --build --preset=beast-view
cmake --build --preset=cgi-hello-world
cmake --build --preset=beast-json
# Build Tests (See /tests directory for the list of tests, each file is a test)
cmake --build --preset=test-type-traits
cmake --build --preset=test-dynamic-router
cmake --build --preset=test-context
cmake --build --preset=test-cookies
cmake --build --preset=test-response
# Run the tests individually
./build/test-response
./build/test-type-traits
# Run all tests (Need to build first)
ctest --preset=tests
# install
cmake --install ./build --prefix=/usr