Webprogrammierung mit C++

Ein Überblick über die verfügbaren Frameworks von

Olaf Radicke

5/2014

Motivation

  • Reduktion der Unterhaltskosten
    • Weniger Hartware
    • Weniger Stromkosten
    • Weniger Platz
    • Weniger Personal
  • Investitionsschutz
    • Bestehenden C++-Code weiterverwenden
    • Von der C++-API-Stabilität profitieren
    • Aufgebautes Wissen weiterverwenden
  • Sicherheit
    • Code unterschieben ist schwierig ohne Source-Code, Compiler oder Interpreter
    • Strenge Typisierung
    • Strenger Compiler

C++ Open Source Web-Framwork

  1. Casablanca
  2. CppCMS
  3. CPPSP "C++ Server Pages"
  4. Duetto
  5. ffead-cpp
  6. NaCl
  7. Node.js mit C++
  8. okws
  9. QtWebApp
  10. Tntnet
  11. Treefrog
  12. Wt "witty"
  13. WSO2 Web Services Framework for C++

Casablanca

  • Projektstart: Vor 2013
  • Lizenz: Apache License
  • Philosoph: Will C++-Services/-Programme in die Cloud bringen
  • LoC: 100.000
  • Funktionsumfang
    • REST-Framework
  • Plattform-Unterstützung
    • Windows
    • Linux
    • Unix/MacOS(?)
  • Mailingliste: Nein, aber aktives Forum
  • Doku: Rudimentär
  • Homepage läuft mit der eigenen Software: Nein
  • Besonderheiten: Ein Projekt von MicroSoft

CppCMS I.

  • Projektstart: vor 2008
  • Lizenz: LGPLv3 oder alternativ Commercial License
  • Philosoph: full featured Framworks
  • LoC: 1.800.000
  • Funktionsumfang
    • URL-Routing
    • Session handling
    • Templates (mit MVC-Support)
    • Form-Generator
    • Form-Validation
    • Cross Site Request Forgery
    • Internationalization and Localization
    • JSON RPC
    • Ausgefeiltes Cacheing
    • SQL Connectivity
    • Text Conversions
    • Schwester-Projekt "cppcms-skeleton" für MVC

CppCMS II.

  • Plattform-Unterstützung
    • Linux
    • Unix
    • MacOS
    • Windows
  • Doku: Grundlagen (API-Doku lückenhaft)
  • Mailingliste: Nein
  • Homepage läuft mit der eigenen Software: Ja
  • Besonderheiten: Es gibt ein Wiki- und ein Weblog-Engines auf dieser Technologie basierend

CPPSP "C++ Server Pages"

  • Projektstart: 2011
  • Lizenz: GPLv2
  • Philosoph: in Anlehnung an ASP.NET
  • LoC: 120.000
  • Funktionsumfang
    • Automatisches parsing/compiling von C++-Code zur Laufzeit
    • Automatisches re-parsing/compiling zur Laufzeit, wenn verändert
    • API ist an ASP.NET angelehnt
    • Multi-Domain-Unterstützung
    • ARM-Unterstützung
  • Plattform-Unterstützung
    • ?
  • Doku: ( API-Doku )
  • Mailingliste:
  • Homepage läuft mit der eigenen Software: vermutlich nein.
  • Besonderheiten: Nur 30% sind C++ Code. Der Rest ist XML und JavaScript. Die Code Repos ist chaotisch.

Duetto I.

  • Projektstart: 2011
  • Lizenz: GPL, LGPL, NCSA Open Source License oder Commercial Licenses
  • Philosoph: (Zitat) Duetto is neither a new framework, nor a new language: it is an extension of C++11, that gives Web 2.0 programming new foundations, on which frameworks can be built easily.
  • LoC:
  • Funktionsumfang
    • Generierter JavaScript-Client
    • Callbacks
    • WebGL
    • JavaScript-Client kann C++-Code auf Server aufrufen.

Duetto II.

  • Plattform-Unterstützung
    • Linux (server-side und client)
    • Windows (client)
    • MacOS (client)
  • Doku: Grundlagen (+API-Doku )
  • Mailingliste:
  • Homepage läuft mit der eigenen Software: Ja, vermutlich
  • Besonderheiten: Spezieller angepasster Clang-Compiler Fork. Aussagen über Projektaktivität deshalb schwierig

Duetto III.

JavaScrip-Client

#include <duetto/client.h>
#include <duetto/clientlib.h>

using namespace client;

void loadCallback() [[client]]
{
    HTMLElement* body=document.get_body();
    HTMLElement* newElement=document.createElement("h1");
    newElement->set_textContent("Hello World");
    body->appendChild(newElement);
}

void webMain() [[client]]
{
    document.addEventListener("DOMContentLoaded",Callback(loadCallback));
}
            

Duetto IV.

Server-Client-Kommunikation

#ifdef __DUETTO_CLIENT__
#include <duetto/client.h>
#else
#include <duetto/server.h>
#endif

#include <string>

#ifdef __DUETTO_CLIENT__
using namespace client;
#endif

int serverTest(int i, float f) [[server]]
{
        return f * 10 + i;
}

int serverTest(int i, int i2) [[server]]
{
        return i-i2;
}

void webMain() [[client]]
{
        const std::string str("Hello Server! ");
        int serverVal = serverTest(10, 0.2f);
        console.log(str.c_str(), serverVal);
}
            

ffead-cpp I.

  • Projektstart: 2012
  • Lizenz: Apache-2.0
  • Philosoph: (Zitat) "The framework is developed for rapid development of Enterprise application on the C++ platform."
  • LoC: 110.000
  • Plattform-Unterstürzung
    • Linux
    • Windows

ffead-cpp II.

  • Funktionsumfang
    • web-application framework
    • rest framework
    • SSL
    • EJB styled Beans
    • XML Serialisation
    • Dynamische C++ Seiten (HTML and C++ code Mix)
    • Template Engine
    • URL-Routing
    • C++ Interpreter (Limited support)
    • Database Connection Pooling
    • Internationalization support
    • Unterstützung für Timer, Logging, Property Files etc.
    • File Upload
    • FTP Server
    • Security features (ACLs)

ffead-cpp III.

  • Doku: Rudimentär ( keine API-Doku )
  • Mailingliste: Nein, Google-Gruppe
  • Homepage läuft mit der eigenen Software: Nein
  • Besonderheiten: Schon seit 2012 keine Release mehr

NaCl (Native Client SDK)

  • Projektstart: 2009
  • Lizenz: Google BSD License
  • Philosoph: C++ im Chrome Browser
  • LoC: 12.000
  • Funktionsumfang
    • ?
  • Plattform-Unterstützung
    • Chrome Browser (Windows, Linux, MacOS usw.)
  • Doku: Wirr ( API-Doku nicht gefunden )
  • Mailingliste: Nein/Nicht gefunden
  • Homepage läuft mit der eigenen Software: Nein
  • Besonderheiten: Scheint nur eine Machbarkeitsstudie zu sein

Node.js mit C++

  • Projektstart: 2009
  • Lizenz: Apache-2.0
  • Philosoph: ???
  • LoC: 1800000
  • Funktionsumfang
    • full stack
  • Plattform-Unterstützung
    • Linux
    • Windows
    • MacOS
    • Unix
  • Doku: Sehr gut (API-Doku: sehr gut)
  • Mailingliste: Google Groups (sehr aktiv)
  • Homepage läuft mit der eigenen Software: Ja
  • Besonderheiten: Ist zu 64% in C/C++ und zu 18% in JavaScript geschrieben. Module können leicht in C++ geschrieben werden. Fromtend-Sprache ist aber JavaScript/HTML. Die Typsicherheit der Javascript/C++ glue ist begrenzt

okws

  • Projektstart: 2003
  • Lizenz: GPLv2
  • Philosoph: unklar
  • LoC: 73.000
  • Funktionsumfang
    • Wrapper libraries für MySQL Datenbank
  • Plattform-Unterstützung
    • Linux
    • Unix?
  • Doku: Rudimentär ( API-Doku fehlt völlig )
  • Mailingliste: Nein, nur GitHub Issues-Tracker
  • Homepage läuft mit der eigenen Software: Ja
  • Besonderheiten: Etwas eigenwilliges Templating/MVC-Konzept. Hauptanwender und Entwickler sind das Dating-Portal www.okcupid.com

QtWebApp I.

  • Projektstart: unbekannt (vor 2012)
  • Lizenz: LGPL
  • Philosoph: Minimalistisch. Anlehnung an Java Servlet API
  • LoC: 10.000
  • Funktionsumfang
    • Sessions
    • Template engine
    • multi languages
    • optional file cache
    • Logger

QtWebApp II.

  • Plattform-Unterstützung
    • Linux
    • Windows
    • Mac OS
    • Android
  • Doku: Rudimentär ( API-Doku umfangreich)
  • Mailingliste: Nein
  • Homepage läuft mit der eigenen Software: Vermutlich nein
  • Besonderheiten: Kein öffentliches Code Repository. Code-Geschichte nicht analysierbar. Ein-Mann-Projekt

Tntnet I.

  • Projektstart: 2004
  • Lizenz: LGPL
  • Philosoph: Puristisch, "no magic", Keine Dogmen und Konzentration auf das Wesentliche
  • LoC: 260.000

Tntnet II.

  • Funktionsumfang: tntnet
    • Läuft in Applicationserver oder standalone
    • HTML-Template-Sprache
    • MVC
    • UML-Routing
    • Session-Handling
    • Statische Inhalte können einkompiliert werden (für Geschwindigkeit und Sicherheit)
    • Einbetten von Subcomponents
    • Savepoints (exception handling)
    • GD Graphics Library mit C++-Binding
    • ssl
    • Umfangreiches Konfiguration der Verbindungen (Timeous, Kompresion, Routing, Logfilepfad, buffer size, listener Eigenschaften, request size usw.)

Tntnet III.

  • Funktionsumfang: cxxtools
    • Effizientes Logging
    • Internationalization Support
    • Command Line Parser
    • json-, csv- und xml-(de)serializatio
    • dlloader (shared library laden und Funktionen aufrufen)
    • regex
    • md5sum
    • RPC-Clint/-Server (binary, jason, xml, csv)
    • signal/slot
    • Thread-safe event loop supporting
    • timer
    • Verzeichnis-Informationen abfragen

Tntnet IV.

  • Funktionsumfang: tntdb
    • Support für MySQL, Postgres, SQLite und Oracle
    • Database Connection Pool
    • SQL Injection Schutz
    • replace condition (Bedingte Select-Teile)
  • Plattform-Unterstützung
    • Linux
    • Unix
  • Doku: Sehr gut mit zahlreichen Beispielen ( API-Doku: Lückenhaft )
  • Mailingliste: Ja
  • Homepage läuft mit der eigenen Software: Ja
  • Besonderheiten: Benutzt ein Pre-Kompiler für das HTML-Template

Tntnet V.

RPC Server



#include <iostream>
#include <cxxtools/arg.h>
#include <cxxtools/xmlrpc/service.h>
#include <cxxtools/http/server.h>
#include <cxxtools/bin/rpcserver.h>
#include <cxxtools/json/rpcserver.h>
#include <cxxtools/json/httpservice.h>
#include <cxxtools/eventloop.h>
#include <cxxtools/posix/daemonize.h>


double add(double a1, double a2)
{
  return a1 + a2;
}


int main(int argc, char* argv[])
{
  try
  {

    // option -i <ip-address> defines the ip address of the interface, where the
    // server waits for connections. Default is empty, which tells the server to
    // listen on all local interfaces
    cxxtools::Arg<std::string> ip(argc, argv, 'i');

    // option -p <number> specifies the port, where http requests are expected.
    // This port is valid for xmlrpc and json over http. It defaults to 7002.
    cxxtools::Arg<unsigned short> port(argc, argv, 'p', 7002);

    // option -b <number> specifies the port, where the binary server waits for
    // requests. It defaults to port 7003.
    cxxtools::Arg<unsigned short> bport(argc, argv, 'b', 7003);

    // option -j <number> specifies the port, where the json server wait for
    // requests. It defaults to port 7004.
    cxxtools::Arg<unsigned short> jport(argc, argv, 'j', 7004);

    cxxtools::Arg<bool> daemonize(argc, argv, 'd');
    cxxtools::Arg<std::string> pidfile(argc, argv, "--pidfile");

    // create an event loop
    cxxtools::EventLoop loop;

    // the http server is instantiated with an ip address and a port number
    // It will be used for xmlrpc and json over http on different urls.
    cxxtools::http::Server httpServer(loop, ip, port);

    ////////////////////////////////////////////////////////////////////////
    // Xmlrpc

    // we create an instance of the service class
    cxxtools::xmlrpc::Service xmlrpcService;

    // we register our functions
    xmlrpcService.registerFunction("add", add);

    // ... and register the service under a url
    httpServer.addService("/xmlrpc", xmlrpcService);

    ////////////////////////////////////////////////////////////////////////
    // Binary rpc

    // for the binary rpc server we define a binary server
    cxxtools::bin::RpcServer binServer(loop, ip, bport);

    // and register the functions in the server
    binServer.registerFunction("add", add);

    ////////////////////////////////////////////////////////////////////////
    // Json rpc

    // for the json rpc server we define a json server
    cxxtools::json::RpcServer jsonServer(loop, ip, jport);

    // and register the functions in the server
    jsonServer.registerFunction("add", add);

    ////////////////////////////////////////////////////////////////////////
    // Json rpc over http

    // for json over http we need a service object
    cxxtools::json::HttpService jsonhttpService;

    // we register our functions
    jsonhttpService.registerFunction("add", add);
    // ... and register the service under a url
    httpServer.addService("/jsonrpc", jsonhttpService);

    // go to the background if requested
    if (daemonize)
      cxxtools::posix::daemonize(pidfile);

    ////////////////////////////////////////////////////////////////////////
    // Run

    // now start the servers by running the event loop
    loop.run();
  }
  catch (const std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }
}
                

Treefrog I.

  • Projektstart: 2012
  • Lizenz: New BSD License
  • Philosoph: RubyOnRails für C++ mit viel "magic".
  • LoC: 51.000
  • Funktionsumfang
    • Template systeme
      • Otama (JavaServer Faces angelehnt mit Pre-Kompiler)
      • ERB (An Ruby angelehnt)
    • Form Validator
    • Full-stack (durch Qt)
    • MVC
    • O/R mapping
    • Routing system
    • Generator für scaffolds und Makefiles
    • MongoDB support (NoSQL database support)

Treefrog II.

  • Plattform-Unterstützung
    • Linux
    • Windows
    • MacOS
    • Unix
  • Doku: Grundlagen ( API-Doku lückenhaft)
  • Mailingliste: Ja
  • Homepage läuft mit der eigenen Software: Nein
  • Besonderheiten: Basiert auf Qt, MOC und Template Pre-Converter

Wt "witty" I.

  • Projektstart: vor 2009
  • Lizenz: GPL oder Commercial License
  • Philosoph: Webproramierung wie GUI-Programmierung umsetzen
  • LoC: 210.00
  • Funktionsumfang
    • Localization
    • Clean URLs
    • Suchmaschinenoptimierung
    • Intrigierte abstrahierte JavaScript libraries/API
    • 2d-Grafik-Support (als eingebettetem SVG, oder HTML5 canvas). Oder rendern von Bildern (PNG, GIF, ...). Vector Generierung (SVG, PDF).
    • WebGL im Browser oder Serverseitig

Wt "witty" II.

  • Funktionsumfang
    • Sessionhandling
      • HTML und Ajax sessions
      • Browser history navigation (back/forward buttons and bookmarks)
      • Event-driven async I/O (Session haben keine eigenen Threads)
      • Listener für Kastatur-, Maus-, Fokus-, Scroll- oder drag&drop-Events(einschließlich Mausposition, Button-Veränderung, oder Tastenanschlag).
      • Zeitgesteuerte und serverseitige Updates ("server push")
      • WebSockets

Wt "witty" III.

  • Funktionsumfang
    • Sicherheitsfunktionen
      • SSL-Support
      • Cross-Site Scripting (XSS): Potenzieller Schadcode kann herausgefiltert werden.
      • Schutz gegen Cross-site Request Forgery (CSRF)
      • DoS-Schutz

Wt "witty" IV.

  • Funktionsumfang
    • Authentifizierungsverfahren
      • Third party Authentifizierungsverfahren (OAuth 2.0 und OpenID)
      • gegen Google
      • gegen Facebook
      • md5
      • sha1
      • bcrypt
      • Validation für starke Passwörter

Wt "witty" V.

  • Funktionsumfang
    • ORM (Object Relational Mapping library)
      • n-1 und n-m Relationen
      • Einzelverbindung oder geteilter Verbindungs-Pool für mehrere Sessions
      • Unterstützung für Sqlite3, Firebird, MariaDB/MySQL und PostgreSQL. Oracle auf Nachfrage
    • Test-Environment
    • Lässt sich betreiben als Standalone hinter einem Proxy, oder als CGI oder mit ISAPI im Microsoft IIS server
    • Json-Unterstützung
    • PayPal API Support

Wt "witty" VI.

  • Plattform-Unterstützung
    • Windows
    • Linux
  • Doku: Gut ( API-Doku: komplett)
  • Mailingliste: Ja (aktiv)
  • Homepage läuft mit der eigenen Software: Ja
  • Besonderheiten: Kein klassisches MVC-Konzept

Wt "witty" VII.

Code-Beispiel

/*
 * Copyright (C) 2008 Emweb bvba, Heverlee, Belgium.
 *
 * See the LICENSE file for terms of use.
 */

#include <Wt/WApplication>
#include <Wt/WBreak>
#include <Wt/WContainerWidget>
#include <Wt/WLineEdit>
#include <Wt/WPushButton>
#include <Wt/WText>

// c++0x only, for std::bind
// #include <functional>

using namespace Wt;

/*
 * A simple hello world application class which demonstrates how to react
 * to events, read input, and give feed-back.
 */
class HelloApplication : public WApplication
{
public:
  HelloApplication(const WEnvironment& env);

private:
  WLineEdit *nameEdit_;
  WText *greeting_;

  void greet();
};

/*
 * The env argument contains information about the new session, and
 * the initial request. It must be passed to the WApplication
 * constructor so it is typically also an argument for your custom
 * application constructor.
*/
HelloApplication::HelloApplication(const WEnvironment& env)
  : WApplication(env)
{
  setTitle("Hello world");                               // application title

  root()->addWidget(new WText("Your name, please ? "));  // show some text
  nameEdit_ = new WLineEdit(root());                     // allow text input
  nameEdit_->setFocus();                                 // give focus

  WPushButton *button
    = new WPushButton("Greet me.", root());              // create a button
  button->setMargin(5, Left);                            // add 5 pixels margin

  root()->addWidget(new WBreak());                       // insert a line break

  greeting_ = new WText(root());                         // empty text

  /*
   * Connect signals with slots
   *
   * - simple Wt-way
   */
  button->clicked().connect(this, &HelloApplication::greet);

  /*
   * - using an arbitrary function object (binding values with boost::bind())
   */
  nameEdit_->enterPressed().connect
    (boost::bind(&HelloApplication::greet, this));

  /*
   * - using a c++0x lambda:
   */
  // b->clicked().connect(std::bind([=]() {
  //       greeting_->setText("Hello there, " + nameEdit_->text());
  // }));
}

void HelloApplication::greet()
{
  /*
   * Update the text, using text input into the nameEdit_ field.
   */
  greeting_->setText("Hello there, " + nameEdit_->text());
}

WApplication *createApplication(const WEnvironment& env)
{
  /*
   * You could read information from the environment to decide whether
   * the user has permission to start a new application
   */
  return new HelloApplication(env);
}

int main(int argc, char **argv)
{
  /*
   * Your main method may set up some shared resources, but should then
   * start the server application (FastCGI or httpd) that starts listening
   * for requests, and handles all of the application life cycles.
   *
   * The last argument to WRun specifies the function that will instantiate
   * new application objects. That function is executed when a new user surfs
   * to the Wt application, and after the library has negotiated browser
   * support. The function should return a newly instantiated application
   * object.
   */
  return WRun(argc, argv, &createApplication);
}
            

WSO2 Web Services Framework for C++ I.

  • Projektstart: 2007
  • Lizenz: Apache-2.0
  • Philosoph: Versteht sich als Teil eines Middleware
  • LoC: 93.000
  • Funktionsumfang
    • SOAP 1.1
    • SOAP 1.2
    • MTOM
    • WS-Addressing
    • WS-Policy
    • WS-Security
    • WS-SecurityPolicy

WSO2 Web Services Framework for C++ II.

  • Plattform-Unterstützung
    • Windows
    • Linux
    • Unix (Solaris)
    • MacOS
  • Doku: Umfangreich ( API-Doku umfangreich )
  • Mailingliste: Ja, aber seit 2009 keine Beiträge mehr zu C++.
  • Homepage läuft mit der eigenen Software: Ja und Nein
  • Besonderheiten: Nur 32% sind in C++ geschrieben. Projekt zeigt keine Aktivitäten mehr. Firma dahinter existiert noch

Commits pro Monat

Anzahl Entwickler pro Monat

Code Base (LoC)

Persönliches Fazit

  • Es gibt erstaunlich viele C++-WabFramewoks
  • Viele Projekte sind sehr klein (geblieben)
  • Einige Projekte sind recht jung
  • Die meisten Projekte haben ein Problem mit der Kommunikation nach Außen
  • Es gib nur wenige Anwender

Mehr Infos auf meinem Blog

cPlusPlusInWeb.wordpress.com
Made with Slides.com