Ertser Commit
This commit is contained in:
33
.vscode/c_cpp_properties.json
vendored
Normal file
33
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Cygwin",
|
||||||
|
"compilerPath": "C:/cygwin64/bin/g++.exe",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}",
|
||||||
|
"C:/cygwin64/usr/lib/gcc/x86_64-pc-cygwin/13/include/c++",
|
||||||
|
"C:/cygwin64/usr/lib/gcc/x86_64-pc-cygwin/13/include/c++/x86_64-pc-cygwin",
|
||||||
|
"C:/cygwin64/usr/lib/gcc/x86_64-pc-cygwin/13/include/c++/backward",
|
||||||
|
"C:/cygwin64/usr/lib/gcc/x86_64-pc-cygwin/13/include",
|
||||||
|
"C:/cygwin64/usr/include",
|
||||||
|
"C:/cygwin64/usr/include/w32api"
|
||||||
|
],
|
||||||
|
"browse": {
|
||||||
|
"path": [
|
||||||
|
"${workspaceFolder}",
|
||||||
|
"C:/cygwin64/usr/lib/gcc/x86_64-pc-cygwin/13/include/c++",
|
||||||
|
"C:/cygwin64/usr/lib/gcc/x86_64-pc-cygwin/13/include/c++/x86_64-pc-cygwin",
|
||||||
|
"C:/cygwin64/usr/lib/gcc/x86_64-pc-cygwin/13/include/c++/backward",
|
||||||
|
"C:/cygwin64/usr/lib/gcc/x86_64-pc-cygwin/13/include",
|
||||||
|
"C:/cygwin64/usr/include",
|
||||||
|
"C:/cygwin64/usr/include/w32api"
|
||||||
|
],
|
||||||
|
"limitSymbolsToIncludedHeaders": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"ms-vscode.cpptools"
|
||||||
|
]
|
||||||
|
}
|
||||||
49
.vscode/launch.json
vendored
Normal file
49
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "(gdb) Starten",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "/cygdrive/c/Users/rexfu/Projekte/WebServer/webserver.exe",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "/cygdrive/c/Users/rexfu/Projekte/WebServer",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"miDebuggerPath": "/usr/bin/gdb",
|
||||||
|
"pipeTransport": {
|
||||||
|
"pipeProgram": "C:/cygwin64/bin/bash.exe",
|
||||||
|
"pipeArgs": [
|
||||||
|
"-lc"
|
||||||
|
],
|
||||||
|
"debuggerPath": "/usr/bin/gdb"
|
||||||
|
},
|
||||||
|
"sourceFileMap": {
|
||||||
|
"/cygdrive/c/Users/rexfu/Projekte/WebServer": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
"engineLogging": false,
|
||||||
|
"trace": false,
|
||||||
|
"traceResponse": false
|
||||||
|
},
|
||||||
|
"preLaunchTask": "C++ Build",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Automatische Strukturierung und Einrückung für gdb aktivieren",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Disassemblierungsvariante auf Intel festlegen",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
26
.vscode/tasks.json
vendored
Normal file
26
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "C++ Build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "C:/cygwin64/bin/bash.exe",
|
||||||
|
"args": [
|
||||||
|
"-lc",
|
||||||
|
"cd \"$(cygpath -u \"$WORKSPACE_FOLDER\")\"; g++ -std=c++17 -g -o webserver.exe webserver.cpp"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"env": {
|
||||||
|
"WORKSPACE_FOLDER": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": ["$gcc"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
207
webserver.cpp
Normal file
207
webserver.cpp
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstring>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
const int PORT = 8089;
|
||||||
|
|
||||||
|
std::string getHtmlPage(const std::string& path) {
|
||||||
|
if (path == "/" || path == "/index") {
|
||||||
|
return R"(<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>C++ Webserver</title>
|
||||||
|
<style>
|
||||||
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', sans-serif;
|
||||||
|
background: linear-gradient(135deg, #1a1a2e, #16213e, #0f3460);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
background: rgba(255,255,255,0.08);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(255,255,255,0.15);
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 50px 60px;
|
||||||
|
max-width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 20px 60px rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
.badge {
|
||||||
|
background: #e94560;
|
||||||
|
color: white;
|
||||||
|
padding: 6px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
h1 { font-size: 2.5em; margin-bottom: 15px; }
|
||||||
|
p { color: rgba(255,255,255,0.7); line-height: 1.7; margin-bottom: 25px; }
|
||||||
|
.links a {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 12px 28px;
|
||||||
|
background: #e94560;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
transition: transform 0.2s, background 0.2s;
|
||||||
|
}
|
||||||
|
.links a:hover { transform: translateY(-2px); background: #c73652; }
|
||||||
|
.links a.secondary {
|
||||||
|
background: rgba(255,255,255,0.1);
|
||||||
|
border: 1px solid rgba(255,255,255,0.2);
|
||||||
|
}
|
||||||
|
.links a.secondary:hover { background: rgba(255,255,255,0.2); }
|
||||||
|
code {
|
||||||
|
background: rgba(0,0,0,0.3);
|
||||||
|
padding: 3px 8px;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #7ec8e3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="card">
|
||||||
|
<div class="badge">C++ HTTP Server</div>
|
||||||
|
<h1>🌐 Hallo, Welt!</h1>
|
||||||
|
<p>
|
||||||
|
Dieser Webserver wurde komplett in <strong>reinem C++</strong> geschrieben —
|
||||||
|
ohne externe Bibliotheken. Er nutzt direkt die
|
||||||
|
<code>POSIX Socket API</code> des Betriebssystems.
|
||||||
|
</p>
|
||||||
|
<div class="links">
|
||||||
|
<a href="/">🏠 Startseite</a>
|
||||||
|
<a href="/info" class="secondary">ℹ️ Server-Info</a>
|
||||||
|
<a href="/zeit" class="secondary">🕐 Uhrzeit</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>)";
|
||||||
|
} else if (path == "/info") {
|
||||||
|
return R"(<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Server Info</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: monospace; background: #0d1117; color: #c9d1d9; padding: 40px; }
|
||||||
|
h1 { color: #58a6ff; }
|
||||||
|
table { border-collapse: collapse; margin-top: 20px; }
|
||||||
|
td, th { padding: 10px 20px; border: 1px solid #30363d; }
|
||||||
|
th { background: #161b22; color: #58a6ff; }
|
||||||
|
a { color: #58a6ff; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>🔧 Server-Informationen</h1>
|
||||||
|
<table>
|
||||||
|
<tr><th>Eigenschaft</th><th>Wert</th></tr>
|
||||||
|
<tr><td>Sprache</td><td>C++ (ISO C++17)</td></tr>
|
||||||
|
<tr><td>Bibliotheken</td><td>Nur POSIX Standard (sys/socket.h)</td></tr>
|
||||||
|
<tr><td>Port</td><td>8080</td></tr>
|
||||||
|
<tr><td>Protokoll</td><td>HTTP/1.0</td></tr>
|
||||||
|
<tr><td>Plattform</td><td>Linux</td></tr>
|
||||||
|
</table>
|
||||||
|
<p style="margin-top:20px"><a href="/">← Zurück</a></p>
|
||||||
|
</body>
|
||||||
|
</html>)";
|
||||||
|
} else if (path == "/zeit") {
|
||||||
|
time_t now = time(nullptr);
|
||||||
|
std::string zeit = std::string(ctime(&now));
|
||||||
|
return "<!DOCTYPE html><html lang='de'><head><meta charset='UTF-8'><title>Zeit</title>"
|
||||||
|
"<style>body{font-family:sans-serif;background:#0d1117;color:#c9d1d9;padding:40px;}"
|
||||||
|
"h1{color:#58a6ff;} a{color:#58a6ff;}</style></head><body>"
|
||||||
|
"<h1>🕐 Aktuelle Serverzeit</h1><p style='font-size:1.5em'>" + zeit + "</p>"
|
||||||
|
"<p><a href='/'>← Zurück</a></p></body></html>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return R"(<!DOCTYPE html>
|
||||||
|
<html lang="de"><head><meta charset="UTF-8"><title>404</title>
|
||||||
|
<style>body{font-family:sans-serif;background:#0d1117;color:#c9d1d9;
|
||||||
|
text-align:center;padding:80px;}h1{font-size:5em;color:#e94560;}
|
||||||
|
a{color:#58a6ff;}</style></head>
|
||||||
|
<body><h1>404</h1><p>Seite nicht gefunden.</p><p><a href="/">Startseite</a></p>
|
||||||
|
</body></html>)";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string buildResponse(const std::string& path) {
|
||||||
|
std::string body = getHtmlPage(path);
|
||||||
|
std::string status = (path == "/" || path == "/info" || path == "/zeit")
|
||||||
|
? "200 OK" : "404 Not Found";
|
||||||
|
|
||||||
|
std::ostringstream response;
|
||||||
|
response << "HTTP/1.0 " << status << "\r\n"
|
||||||
|
<< "Content-Type: text/html; charset=UTF-8\r\n"
|
||||||
|
<< "Content-Length: " << body.size() << "\r\n"
|
||||||
|
<< "Connection: close\r\n"
|
||||||
|
<< "\r\n"
|
||||||
|
<< body;
|
||||||
|
return response.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (server_fd < 0) { std::cerr << "Socket-Fehler\n"; return 1; }
|
||||||
|
|
||||||
|
int opt = 1;
|
||||||
|
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||||
|
|
||||||
|
sockaddr_in address{};
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
address.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
address.sin_port = htons(PORT);
|
||||||
|
|
||||||
|
if (bind(server_fd, (sockaddr*)&address, sizeof(address)) < 0) {
|
||||||
|
std::cerr << "Bind-Fehler\n"; return 1;
|
||||||
|
}
|
||||||
|
if (listen(server_fd, 10) < 0) {
|
||||||
|
std::cerr << "Listen-Fehler\n"; return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Server laeuft auf http://localhost:" << PORT << "\n";
|
||||||
|
std::cout << "Seiten: / /info /zeit\n";
|
||||||
|
std::cout << "Beenden mit Ctrl+C\n\n";
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int client_fd = accept(server_fd, nullptr, nullptr);
|
||||||
|
if (client_fd < 0) continue;
|
||||||
|
|
||||||
|
char buffer[4096] = {};
|
||||||
|
|
||||||
|
read(client_fd, buffer, sizeof(buffer) - 1);
|
||||||
|
|
||||||
|
// HTTP-Anfrage parsen: "GET /path HTTP/1.x"
|
||||||
|
std::string request(buffer);
|
||||||
|
std::string path = "/";
|
||||||
|
size_t start = request.find(' ');
|
||||||
|
if (start != std::string::npos) {
|
||||||
|
size_t end = request.find(' ', start + 1);
|
||||||
|
if (end != std::string::npos)
|
||||||
|
path = request.substr(start + 1, end - start - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Anfrage: " << path << "\n";
|
||||||
|
|
||||||
|
std::string response = buildResponse(path);
|
||||||
|
send(client_fd, response.c_str(), response.size(), 0);
|
||||||
|
close(client_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(server_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
webserver.exe
Normal file
BIN
webserver.exe
Normal file
Binary file not shown.
Reference in New Issue
Block a user