C++ Webprogrammierung mit CGI: Vom ersten Skript bis zu Cookies & Datei-Upload
Was ist CGI?
Das Common Gateway Interface (CGI) definiert einen Standard für den Datenaustausch zwischen Webserver und benutzerdefinierten Skripten/Programmen. CGI-Programme können in C++, Python, Perl, Shell u. v. m. geschrieben sein. Die aktuelle Version ist CGI/1.1.
Funktionsweise beim Web-Browsing
- Browser fordert eine URL beim HTTP-Server an.
- Server sucht die Datei. Existiert sie, wird sie ausgeliefert; andernfalls Fehler.
- Bei CGI-Konfiguration wird die Datei nicht ausgeliefert, sondern ausgeführt – die stdout-Ausgabe geht an den Browser zurück.
Webserver-Konfiguration (Apache)
Standard-CGI-Verzeichnis: /var/www/cgi-bin. CGI-Dateien enden konventionell auf .cgi (sind aber kompilierte Executables). In httpd.conf:
<Directory "/var/www/cgi-bin">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>
Wichtig: Datei ausführbar machen: chmod 755 meinprogramm.cgi.
Erstes CGI-Programm (C++)
#include <iostream>
using namespace std;
int main() {
// HTTP-Header: Content-Type ist Pflicht!
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n<head><title>Erstes CGI-Programm</title></head>\n";
cout << "<body><h2>Hallo Welt! Mein erstes C++ CGI-Programm</h2></body></html>\n";
return 0;
}
Die erste Ausgabezeile Content-type:text/html\r\n\r\n ist der HTTP-Header, der dem Browser den Inhaltstyp mitteilt.
Wichtige HTTP-Header
| Header | Beschreibung |
|---|---|
Content-type |
MIME-Typ der Rückgabe (z. B. text/html). |
Expires |
Datum, ab dem Inhalt ungültig ist (Format: 01 Jan 2025 12:00:00 GMT). |
Location |
URL für Umleitung. |
Last-modified |
Letztes Änderungsdatum der Ressource. |
Content-length |
Länge der Daten in Bytes. |
Set-Cookie |
Setzt ein Cookie (Name=Wert). |
CGI-Umgebungsvariablen
CGI-Programme erhalten Zugriff auf Umgebungsvariablen wie QUERY_STRING (GET-Daten), CONTENT_LENGTH (POST-Länge), REQUEST_METHOD (GET/POST), REMOTE_ADDR (Client-IP), HTTP_USER_AGENT, HTTP_COOKIE u. v. m.
C++ CGI Library (cgicc)
Für produktive Anwendungen empfiehlt sich die Bibliothek cgicc (GNU): ftp://ftp.gnu.org/gnu/cgicc/. Installation:
tar xzf cgicc-X.X.X.tar.gz
cd cgicc-X.X.X/
./configure --prefix=/usr
make && make install
Kompilieren mit: g++ -o mein.cgi mein.cpp -lcgicc
GET- vs. POST-Methode
- GET: Daten im URL (
?key=val&key2=val2), limitiert (~1024 Zeichen), nicht für Passwörter geeignet. Daten inQUERY_STRING. - POST: Daten im Request-Body (stdin), keine Größenbeschränkung, sicherer für sensible Daten.
Beispiel: GET-Parameter mit cgicc auslesen
#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
using namespace std;
using namespace cgicc;
int main() {
Cgicc formData;
cout << HTTPHTMLHeader() << endl;
cout << "<html><body>\n";
form_iterator fi = formData.getElement("first_name");
if (fi != formData.getElements().end() && !fi->isEmpty())
cout << "Vorname: " << **fi << "<br/>\n";
else
cout << "Kein Vorname eingegeben<br/>\n";
fi = formData.getElement("last_name");
if (fi != formData.getElements().end() && !fi->isEmpty())
cout << "Nachname: " << **fi << "<br/>\n";
else
cout << "Kein Nachname eingegeben<br/>\n";
cout << "</body></html>\n";
return 0;
}
Formularelemente verarbeiten
- Checkbox:
formData.queryCheckbox("name")→bool - Radio-Button:
formData.getElement("name")→ Wert des gewählten Buttons - Textarea:
formData.getElement("name")→ Textinhalt - Dropdown (
<select>):formData.getElement("name")→ gewählter Wert
Cookies in CGI
HTTP ist zustandslos. Cookies speichern Client-seitig Daten (Name=Wert, Domain, Pfad, Expires, Secure).
Cookie setzen (vor Content-type!)
cout << "Set-Cookie:UserID=XYZ\r\n";
cout << "Set-Cookie:Password=XYZ123\r\n";
cout << "Set-Cookie:Domain=example.com\r\n";
cout << "Set-Cookie:Path=/cgi-bin\r\n";
cout << "Content-type:text/html\r\n\r\n";
Cookies auslesen
Cookies liegen in HTTP_COOKIE als key1=val1; key2=val2. Mit cgicc:
const CgiEnvironment& env = cgi.getEnvironment();
for (auto it = env.getCookieList().begin(); it != env.getCookieList().end(); ++it) {
cout << it->getName() << " = " << it->getValue() << "<br/>\n";
}
Datei-Upload
HTML-Formular benötigt enctype="multipart/form-data" und <input type="file">. Serverseitig mit cgicc:
const_file_iterator file = cgi.getFile("userfile");
if (file != cgi.getFiles().end()) {
cout << HTTPContentHeader(file->getDataType());
file->writeToStream(cout); // oder in Datei speichern
}
Fazit
CGI mit C++ ist leistungsfähig für performante Webanwendungen. Für komplexere Projekte bieten sich jedoch moderne Frameworks (FastCGI, Wt, Crow, oatpp) oder Sprachen mit reichhaltigerem Web-Ökosystem an.
C Sprache
- Namespaces in C# meistern: Organisation, Gültigkeitsbereich und Best Practices
- C++-Operatoren meistern: Ein vollständiger Leitfaden mit praktischen Beispielen
- C++-Kommentare: Best Practices für lesbaren, wartbaren Code
- Arrays an Funktionen in C++ übergeben: Ein praktischer Leitfaden
- C-Programmierung meistern: Umfassendes Tutorial für Einsteiger
- C++ Programmiersprache: Überblick & Kernfeatures
- C++ Konstanten & Literale: Typen, Syntax & Best Practices
- C++ Operatoren: Typen, Nutzung & Best Practices
- C++ Numerische Typen: Praktischer Leitfaden
- C++ Referenzen: Konzepte & Unterschiede zu Pointern