From 4143b422c32f65d9bc06da2c9d25b623197ccb2c Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Fri, 18 Sep 2026 20:44:23 +0200 Subject: Fehlerbehandlung überarbeitet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- makefile | 2 +- server.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 83 insertions(+), 18 deletions(-) diff --git a/makefile b/makefile index 9fee06a..2a708bf 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ all: server server: server.cpp - c++ -Wall -std=c++20 -pedantic -O2 -lfcgi -o $@ $< + c++ -Wall -std=c++20 -pedantic -O2 -o $@ $< -lfcgi diff --git a/server.cpp b/server.cpp index a454b68..4ad0a3f 100644 --- a/server.cpp +++ b/server.cpp @@ -1,8 +1,15 @@ // Standard C++ #include +#include #include #include +#include +#include #include +#include +#include +#include +#include // FastCGI #include @@ -10,10 +17,14 @@ using namespace std; namespace { -static atomic_bool quit; -static atomic_bool reload; +struct Configuration { + int value; +}; -static void +atomic_bool quit{ false }; +atomic_bool reload{ false }; + +void handler(int signal) { if ( signal == SIGINT || signal == SIGTERM ) { @@ -24,7 +35,7 @@ handler(int signal) } } -static void +void init_signal_handler() { struct sigaction sa; @@ -36,19 +47,48 @@ init_signal_handler() sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); + + signal(SIGPIPE, SIG_IGN); } -static void -load_configuration() +bool +load_configuration(Configuration& configuration) { cerr << "Load configuration ...\n"; + configuration.value = 1; + return true; +} + +void +handle_request(char** env, const Configuration&, string_view body, ostream& out) +{ + const char* methode = FCGX_GetParam("REQUEST_METHOD", env); + + out << "Content-Type: text/html; charset=utf-8\r\n\r\n"; + out << "

Verbindung erfolgreich verarbeitet!

"; + out << "

Methode: " << (methode ? methode : "?") << ", Body: " << body.size() << " Bytes

"; } -static void -handle_request(const FCGX_Request& request) +void +send_internal_error(const FCGX_Request& request) { - FCGX_FPrintF(request.out, "Content-type: text/html\r\n\r\n"); - FCGX_FPrintF(request.out, "

Verbindung erfolgreich verarbeitet!

"); + FCGX_FPrintF(request.out, "Status: 500 Internal Server Error\r\n"); + FCGX_FPrintF(request.out, "Content-Type: text/plain; charset=utf-8\r\n\r\n"); + FCGX_FPrintF(request.out, "Die Anfrage konnte nicht verarbeitet werden.\n"); +} + +string +read_request_body(const FCGX_Request& request) +{ + string body; + char buffer[8192]; + int gelesen; + + while ( (gelesen = FCGX_GetStr(buffer, sizeof buffer, request.in)) > 0 ) { + body.append(buffer, gelesen); + } + + return body; } } // namespace @@ -70,26 +110,51 @@ main() } init_signal_handler(); - load_configuration(); - quit = false; - reload = false; + Configuration configuration{}; + if ( !load_configuration(configuration) ) { + cerr << "Die Konfiguration konnte nicht geladen werden.\n"; + return EXIT_FAILURE; + } cout << "Handle Requests...\n"; while ( !quit ) { - if ( reload ) { - load_configuration(); - reload = false; + if ( reload.exchange(false) ) { + Configuration new_configuration{}; + + if ( load_configuration(new_configuration) ) { + configuration = std::move(new_configuration); + } + else { + cerr << "Neue Konfiguration nicht lesbar, die bisherige bleibt in Kraft.\n"; + } } if ( FCGX_Accept_r(&request) < 0 ) { + if ( errno != EINTR ) { + cerr << "Fehler beim Annehmen der Verbindung: " << strerror(errno) << '\n'; + break; + } continue; } - handle_request(request); + try { + const string body = read_request_body(request); + + ostringstream response; + handle_request(request.envp, configuration, body, response); + + const string_view text = response.view(); + FCGX_PutStr(text.data(), static_cast(text.size()), request.out); + } + catch ( const exception& e ) { + FCGX_FPrintF(request.err, "Fehler beim Verarbeiten der Anfrage: %s\n", e.what()); + send_internal_error(request); + } FCGX_Finish_r(&request); } + cout << "shutdown...\n"; } -- cgit v1.3