diff options
| author | Ibrahim Muftee <ibrahim@muftee.net> | 2026-08-22 02:33:43 +0000 |
|---|---|---|
| committer | Ibrahim Muftee <ibrahim@muftee.net> | 2026-08-22 02:33:43 +0000 |
| commit | dcd4483c277e6de60a94ed284f927e60511bf4cc (patch) | |
| tree | ebdb499ca3b6dd4fb1ba8b8f10d63af6a1a20bab | |
Begin basic HTTP server
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | build.zig | 14 | ||||
| -rw-r--r-- | http.zig | 54 |
3 files changed, 70 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ea71a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.zig-cache/ +zig-out/
\ No newline at end of file diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..51e049f --- /dev/null +++ b/build.zig @@ -0,0 +1,14 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const exe = b.addExecutable(.{ + .name = "http", + .root_module = b.createModule(.{ .root_source_file = b.path("http.zig"), .target = b.graph.host }), + }); + + b.installArtifact(exe); + + const run_exe = b.addRunArtifact(exe); + const run_step = b.step("run", "Run the application"); + run_step.dependOn(&run_exe.step); +} diff --git a/http.zig b/http.zig new file mode 100644 index 0000000..74a1341 --- /dev/null +++ b/http.zig @@ -0,0 +1,54 @@ +const std = @import("std"); +const log = std.log; +const net = std.Io.net; +const Io = std.Io; +const Request = std.http.Server.Request; + +const MAX_BUF = 1024; + +pub fn main(init: std.process.Init) !void { + const io = init.io; + + const addr = try net.IpAddress.parse("127.0.0.1", 8080); + var server = try addr.listen(io, .{ .reuse_address = true }); + defer server.deinit(io); + + log.info("Start HTTP server at {f}", .{addr}); + + while (true) { + const stream = server.accept(io) catch |err| { + log.err("failed to accept connection: {s}", .{@errorName(err)}); + continue; + }; + const thread = std.Thread.spawn(.{}, accept, .{ stream, io }) catch |err| { + log.err("unable to spawn connection thread: {s}", .{@errorName(err)}); + stream.close(io); + continue; + }; + thread.detach(); + } +} + +fn accept(stream: net.Stream, io: Io) !void { + defer stream.close(io); + + log.info("Got new client!", .{}); + + var recv_buffer: [1024]u8 = undefined; + var send_buffer: [100]u8 = undefined; + var stream_reader = stream.reader(io, &recv_buffer); + var stream_writer = stream.writer(io, &send_buffer); + var server = std.http.Server.init(&stream_reader.interface, &stream_writer.interface); + while (server.reader.state == .ready) { + var request = server.receiveHead() catch |err| switch (err) { + error.HttpConnectionClosing => return, + else => return err, + }; + try serveHTTP(&request); + } +} + +fn serveHTTP(request: *Request) !void { + log.info("Received request: {s}", .{request.head.target}); + try request.respond("Welcome to Coinvane!\n", .{}); +} |
