Repository navigation
Expand file tree
/
Copy pathstaticEmbedded.zig
More file actions
86 lines (69 loc) · 3.27 KB
/
Copy pathstaticEmbedded.zig
File metadata and controls
86 lines (69 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! Example: Single-File Server with Embedded Static Assets & Templates
//!
//! Demonstrates:
//! 1. Embedding static files into the .exe with @embedFile (zero disk I/O)
//! 2. Registering them in httpx.assets so server.static serves from memory
//! 3. Rendering a template resolved from the embedded registry
//! 4. Identical handler API as filesystem mode (see staticSite.zig)
//!
//! Run with: `zig build run-static-embedded`
const std = @import("std");
const httpx = @import("httpx");
const indexHtml = @embedFile("static/index.html");
const stylesCss = @embedFile("static/styles.css");
const appJs = @embedFile("static/app.js");
fn hello(ctx: *httpx.router.Context) anyerror!httpx.router.Response {
return ctx.render("greet.html", .{ .name = "Embedded" });
}
pub fn main() !void {
var gpa: std.heap.DebugAllocator(.{}) = .init;
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const io = std.Io.Threaded.global_single_threaded.io();
std.debug.print("==> HTTPX Single-File Embedded Server Demo\n\n", .{});
// 1. Register embedded assets (logical web paths, served from memory).
try httpx.assets.registerEmbedded(allocator, "index.html", indexHtml, null);
try httpx.assets.registerEmbedded(allocator, "styles.css", stylesCss, null);
try httpx.assets.registerEmbedded(allocator, "app.js", appJs, null);
try httpx.assets.registerEmbedded(allocator, "greet.html", "<h1>Hello, {{ name }}!</h1>", null);
std.debug.print("Registered {d} embedded assets\n", .{httpx.assets.globalStore(allocator).count()});
// 2. Same server API as filesystem mode; embedded hits resolve first.
// Explicit .templates keeps the engine alive even without a templates/
// directory on disk: the loader consults the embedded registry first.
var server = try httpx.Server.init(allocator, io, .{
.host = "127.0.0.1",
.port = 0,
.enableDocs = false,
.maxConnections = 4,
.templates = .{ .enabled = true },
});
defer server.deinit();
try server.static("/", "examples/static");
try server.get("/hello", hello);
const port = server.localPort();
const ServerThread = struct {
fn run(s: *httpx.Server) void {
s.run();
}
};
const t = try std.Thread.spawn(.{}, ServerThread.run, .{&server});
defer t.join();
var client = httpx.Client.init(allocator, io, .{});
defer client.deinit();
// 3. Verify embedded static file serving.
const rootUrl = try std.fmt.allocPrint(allocator, "http://127.0.0.1:{d}/", .{port});
defer allocator.free(rootUrl);
var res = try client.get(rootUrl, .{});
defer res.deinit();
std.debug.print("GET / -> Status: {d}, Length: {d}\n", .{ res.status, res.body.len });
// 4. Verify embedded template rendering.
const helloUrl = try std.fmt.allocPrint(allocator, "http://127.0.0.1:{d}/hello", .{port});
defer allocator.free(helloUrl);
var res2 = try client.get(helloUrl, .{});
defer res2.deinit();
std.debug.print("GET /hello -> Status: {d}, Body: {s}\n", .{ res2.status, res2.body });
std.debug.print("\nSingle-file embedded verification successful.\n", .{});
server.stop();
// Release global registry keys/etags owned by the debug allocator.
httpx.assets.globalStore(allocator).deinit();
}