Last active
April 21, 2025 16:29
-
-
Save michidk/b3676373c3514d36c6a7270be03c796a to your computer and use it in GitHub Desktop.
Dynamic Zig Webserver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const net = std.net; | |
const io = std.io; | |
const mem = std.mem; | |
const heap = std.heap; | |
const http = std.http; | |
const Response = struct { | |
status: []const u8, | |
headers: []const u8, | |
body: []const u8, | |
allocator: mem.Allocator, | |
fn init(allocator: mem.Allocator, name: ?[]const u8) !Response { | |
const name_to_greet = name orelse "Unbekannt"; | |
const body_str = try std.fmt.allocPrint(allocator, "<html><body><h1>Hallo {s}!</h1></body></html>", .{name_to_greet}); | |
return Response{ | |
.status = "200 OK", | |
.headers = "Content-Type: text/html; charset=utf-8\r\n", | |
.body = body_str, | |
.allocator = allocator, | |
}; | |
} | |
fn deinit(self: *Response) void { | |
self.allocator.free(self.body); | |
} | |
}; | |
pub fn main() !void { | |
var gpa = heap.GeneralPurposeAllocator(.{}){}; | |
const allocator = gpa.allocator(); | |
defer _ = gpa.deinit(); | |
const loopback = try net.Ip4Address.parse("127.0.0.1", 8080); | |
const localhost = net.Address{ .in = loopback }; | |
var server = try localhost.listen(); | |
defer server.deinit(); | |
std.debug.print("Server gestartet auf http://127.0.0.1:8080\n", .{}); | |
while (true) { | |
const client = try server.accept(); | |
defer client.stream.close(); | |
var buf: [1024]u8 = undefined; | |
const bytes_read = try client.stream.read(&buf); | |
const request_bytes = buf[0..bytes_read]; | |
const res = try http.Server.Request.Head.parse(request_bytes); | |
std.debug.print("Request target: {s}\n", .{res.target}); | |
// Parse the name parameter from the query string | |
var name: ?[]const u8 = null; | |
if (mem.indexOf(u8, res.target, "?name=")) |index| { | |
const name_start = index + "?name=".len; | |
const name_end = if (mem.indexOf(u8, res.target[name_start..], "&")) |end_index| | |
name_start + end_index | |
else | |
res.target.len; | |
name = res.target[name_start..name_end]; | |
} | |
var response = try Response.init(allocator, name); | |
defer response.deinit(); | |
try sendResponse(client.stream, &response); | |
} | |
} | |
fn sendResponse(stream: net.Stream, response: *Response) !void { | |
const writer = stream.writer(); | |
try writer.print("HTTP/1.1 {s}\r\n", .{response.status}); | |
try writer.writeAll(response.headers); | |
try writer.print("Content-Length: {d}\r\n", .{response.body.len}); | |
try writer.writeAll("\r\n"); | |
try writer.writeAll(response.body); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment