Skip to content

Commit a9557ab

Browse files
authored
Merge pull request #31 from BennyFranciscus/update-blitz-framework
Update blitz to modular framework architecture
2 parents e57172b + 50d3760 commit a9557ab

22 files changed

Lines changed: 9108 additions & 527 deletions

frameworks/blitz/README.md

Lines changed: 711 additions & 18 deletions
Large diffs are not rendered by default.

frameworks/blitz/build.zig

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,51 @@ pub fn build(b: *std.Build) void {
44
const target = b.standardTargetOptions(.{});
55
const optimize = b.standardOptimizeOption(.{});
66

7+
// Blitz framework module
8+
const blitz_mod = b.addModule("blitz", .{
9+
.root_source_file = b.path("src/blitz.zig"),
10+
.target = target,
11+
.optimize = optimize,
12+
});
13+
14+
// Example app (separate step — not built by default)
15+
const example = b.addExecutable(.{
16+
.name = "hello",
17+
.root_source_file = b.path("examples/hello.zig"),
18+
.target = target,
19+
.optimize = optimize,
20+
.single_threaded = false,
21+
});
22+
example.root_module.addImport("blitz", blitz_mod);
23+
example.linkLibC();
24+
const install_example = b.addInstallArtifact(example, .{});
25+
const example_step = b.step("example", "Build the example app");
26+
example_step.dependOn(&install_example.step);
27+
28+
// HttpArena benchmark server
729
const exe = b.addExecutable(.{
830
.name = "blitz",
931
.root_source_file = b.path("src/main.zig"),
1032
.target = target,
1133
.optimize = optimize,
1234
.single_threaded = false,
1335
});
14-
1536
exe.linkLibC();
16-
1737
b.installArtifact(exe);
1838

39+
// Run step
1940
const run_cmd = b.addRunArtifact(exe);
2041
run_cmd.step.dependOn(b.getInstallStep());
2142
const run_step = b.step("run", "Run the server");
2243
run_step.dependOn(&run_cmd.step);
44+
45+
// Tests
46+
const tests = b.addTest(.{
47+
.root_source_file = b.path("src/blitz.zig"),
48+
.target = target,
49+
.optimize = optimize,
50+
});
51+
const run_tests = b.addRunArtifact(tests);
52+
const test_step = b.step("test", "Run unit tests");
53+
test_step.dependOn(&run_tests.step);
2354
}

frameworks/blitz/meta.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"language": "Zig",
44
"type": "engine",
55
"engine": "epoll",
6-
"description": "Custom Zig HTTP server built on epoll with SO_REUSEPORT multi-threading. Zero allocations in the hot path, pre-computed responses, pipeline batching.",
6+
"description": "Custom Zig HTTP server with dual epoll/io_uring backends. Zero-copy parsing, pre-computed responses, pipeline batching.",
77
"repo": "https://github.com/BennyFranciscus/blitz",
88
"enabled": true,
99
"tests": [
@@ -12,6 +12,8 @@
1212
"noisy",
1313
"limited-conn",
1414
"json",
15-
"upload"
15+
"upload",
16+
"compression",
17+
"echo-ws"
1618
]
1719
}

frameworks/blitz/src/blitz.zig

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
//! # blitz ⚡
2+
//!
3+
//! A blazing-fast HTTP/1.1 micro web framework for Zig.
4+
//!
5+
//! Built on epoll with SO_REUSEPORT multi-threading, zero-copy parsing,
6+
//! and a radix-trie router with path parameters.
7+
//!
8+
//! ## Quick Start
9+
//!
10+
//! ```zig
11+
//! const blitz = @import("blitz");
12+
//!
13+
//! fn hello(_: *blitz.Request, res: *blitz.Response) void {
14+
//! _ = res.text("Hello, World!");
15+
//! }
16+
//!
17+
//! fn greet(req: *blitz.Request, res: *blitz.Response) void {
18+
//! const name = req.params.get("name") orelse "stranger";
19+
//! // Use name to build response...
20+
//! _ = res.text(name);
21+
//! }
22+
//!
23+
//! pub fn main() !void {
24+
//! var router = blitz.Router.init(std.heap.c_allocator);
25+
//! router.get("/", hello);
26+
//! router.get("/hello/:name", greet);
27+
//!
28+
//! var server = blitz.Server.init(&router, .{ .port = 8080 });
29+
//! try server.listen();
30+
//! }
31+
//! ```
32+
33+
pub const types = @import("blitz/types.zig");
34+
pub const router_mod = @import("blitz/router.zig");
35+
pub const parser_mod = @import("blitz/parser.zig");
36+
pub const server_mod = @import("blitz/server.zig");
37+
pub const json_mod = @import("blitz/json.zig");
38+
pub const errors_mod = @import("blitz/errors.zig");
39+
pub const static_mod = @import("blitz/static.zig");
40+
pub const query_mod = @import("blitz/query.zig");
41+
pub const pool_mod = @import("blitz/pool.zig");
42+
pub const body_mod = @import("blitz/body.zig");
43+
pub const cookie_mod = @import("blitz/cookie.zig");
44+
pub const compress_mod = @import("blitz/compress.zig");
45+
pub const log_mod = @import("blitz/log.zig");
46+
pub const uring_mod = @import("blitz/uring.zig");
47+
pub const websocket_mod = @import("blitz/websocket.zig");
48+
pub const spsc_mod = @import("blitz/spsc.zig");
49+
50+
// Re-export main types for convenience
51+
pub const Request = types.Request;
52+
pub const Response = types.Response;
53+
pub const Method = types.Method;
54+
pub const StatusCode = types.StatusCode;
55+
pub const Headers = types.Headers;
56+
pub const HandlerFn = types.HandlerFn;
57+
pub const MiddlewareFn = types.MiddlewareFn;
58+
pub const Router = router_mod.Router;
59+
pub const Group = router_mod.Group;
60+
pub const Server = server_mod.Server;
61+
pub const Config = server_mod.Config;
62+
63+
// JSON
64+
pub const Json = json_mod.Json;
65+
pub const JsonObject = json_mod.JsonObject;
66+
pub const JsonArray = json_mod.JsonArray;
67+
68+
// Static file serving
69+
pub const serveFile = static_mod.serveFile;
70+
pub const mimeFromPath = static_mod.mimeFromPath;
71+
pub const mimeFromExt = static_mod.mimeFromExt;
72+
pub const sanitizePath = static_mod.sanitizePath;
73+
pub const StaticDirConfig = static_mod.StaticDirConfig;
74+
75+
// Error handling
76+
pub const sendError = errors_mod.sendError;
77+
pub const badRequest = errors_mod.badRequest;
78+
pub const unauthorized = errors_mod.unauthorized;
79+
pub const forbidden = errors_mod.forbidden;
80+
pub const notFound = errors_mod.notFound;
81+
pub const methodNotAllowed = errors_mod.methodNotAllowed;
82+
pub const internalError = errors_mod.internalError;
83+
pub const jsonNotFoundHandler = errors_mod.jsonNotFoundHandler;
84+
pub const jsonMethodNotAllowedHandler = errors_mod.jsonMethodNotAllowedHandler;
85+
86+
// Query string parsing
87+
pub const Query = query_mod.Query;
88+
pub const urlDecode = query_mod.urlDecode;
89+
90+
// Body parsing
91+
pub const FormData = body_mod.FormData;
92+
pub const parseForm = body_mod.parseForm;
93+
pub const ContentType = body_mod.ContentType;
94+
pub const detectContentType = body_mod.detectContentType;
95+
pub const extractBoundary = body_mod.extractBoundary;
96+
pub const MultipartPart = body_mod.MultipartPart;
97+
pub const MultipartResult = body_mod.MultipartResult;
98+
pub const parseMultipart = body_mod.parseMultipart;
99+
100+
// Connection pooling
101+
pub const ConnPool = pool_mod.ConnPool;
102+
pub const ConnState = pool_mod.ConnState;
103+
104+
// Cookies
105+
pub const CookieJar = cookie_mod.CookieJar;
106+
pub const Cookie = cookie_mod.Cookie;
107+
pub const parseCookies = cookie_mod.parseCookies;
108+
pub const SetCookieOpts = cookie_mod.SetCookieOpts;
109+
pub const SameSite = cookie_mod.SameSite;
110+
pub const buildSetCookie = cookie_mod.buildSetCookie;
111+
pub const buildDeleteCookie = cookie_mod.buildDeleteCookie;
112+
113+
// Compression
114+
pub const Encoding = compress_mod.Encoding;
115+
pub const acceptedEncoding = compress_mod.acceptedEncoding;
116+
pub const shouldCompress = compress_mod.shouldCompress;
117+
pub const compressResponse = compress_mod.compressResponse;
118+
pub const gzipCompressSlice = compress_mod.gzipCompressSlice;
119+
pub const deflateCompressSlice = compress_mod.deflateCompressSlice;
120+
121+
// Logging
122+
pub const LogConfig = log_mod.LogConfig;
123+
pub const LogFormat = log_mod.Format;
124+
pub const LogLevel = log_mod.Level;
125+
pub const logRequest = log_mod.logRequest;
126+
pub const logNow = log_mod.now;
127+
pub const logMsg = log_mod.log;
128+
129+
// WebSocket
130+
pub const websocket = websocket_mod;
131+
pub const WebSocket = websocket_mod;
132+
pub const WsOpcode = websocket_mod.Opcode;
133+
pub const WsCloseCode = websocket_mod.CloseCode;
134+
pub const WsFrame = websocket_mod.Frame;
135+
pub const wsParseFrame = websocket_mod.parseFrame;
136+
pub const wsBuildFrame = websocket_mod.buildFrame;
137+
pub const wsBuildCloseFrame = websocket_mod.buildCloseFrame;
138+
pub const wsIsUpgradeRequest = websocket_mod.isUpgradeRequest;
139+
pub const wsBuildUpgradeResponse = websocket_mod.buildUpgradeResponse;
140+
pub const wsAcceptKey = websocket_mod.acceptKey;
141+
142+
// io_uring backend
143+
pub const UringServer = uring_mod.UringServer;
144+
pub const UringConfig = uring_mod.Config;
145+
146+
// Graceful shutdown
147+
pub const isShuttingDown = server_mod.isShuttingDown;
148+
149+
// Utilities
150+
pub const writeUsize = types.writeUsize;
151+
pub const writeI64 = types.writeI64;
152+
pub const asciiEqlIgnoreCase = types.asciiEqlIgnoreCase;
153+
154+
// Parser
155+
pub const parse = parser_mod.parse;
156+
157+
// SPSC Queue
158+
pub const SpscQueue = spsc_mod.SpscQueue;
159+
160+
// Tests (pulled in by `zig build test`)
161+
test {
162+
_ = @import("blitz/tests.zig");
163+
_ = @import("blitz/static.zig");
164+
_ = @import("blitz/query.zig");
165+
_ = @import("blitz/pool.zig");
166+
_ = @import("blitz/body.zig");
167+
_ = @import("blitz/cookie.zig");
168+
_ = @import("blitz/compress.zig");
169+
_ = @import("blitz/log.zig");
170+
_ = @import("blitz/websocket.zig");
171+
_ = @import("blitz/spsc.zig");
172+
}

0 commit comments

Comments
 (0)