Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,16 @@ zig-out/
.zig-cache/
perf*.data*
heaptrack*
/basic
/cookies
/form
/fs
/middleware
/rest
/sse
/tls
/unix
/ex_ws_1
/ex_ws_2
/ex_ws_3
/ex_ws_4
95 changes: 81 additions & 14 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ const std = @import("std");

pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const optimize = b.standardOptimizeOption(.{}); // -O Debug
//const optimize = std.builtin.OptimizeMode.ReleaseFast; // -O ReleaseFast

const zzz = b.addModule("zzz", .{
.root_source_file = b.path("src/lib.zig"),
.target = target,
Expand All @@ -24,18 +25,79 @@ pub fn build(b: *std.Build) void {

zzz.addImport("secsock", secsock);

add_example(b, "basic", false, target, optimize, zzz);
add_example(b, "cookies", false, target, optimize, zzz);
add_example(b, "form", false, target, optimize, zzz);
add_example(b, "fs", false, target, optimize, zzz);
add_example(b, "middleware", false, target, optimize, zzz);
add_example(b, "sse", false, target, optimize, zzz);
add_example(b, "tls", true, target, optimize, zzz);
const all_http_examples_step = b.step("examples_http", "Build all HTTP examples");
add_http_example(b, all_http_examples_step, "basic", false, target, optimize, zzz);
add_http_example(b, all_http_examples_step, "cookies", false, target, optimize, zzz);
add_http_example(b, all_http_examples_step, "form", false, target, optimize, zzz);
add_http_example(b, all_http_examples_step, "fs", false, target, optimize, zzz);
add_http_example(b, all_http_examples_step, "middleware", false, target, optimize, zzz);
add_http_example(b, all_http_examples_step, "sse", false, target, optimize, zzz);
add_http_example(b, all_http_examples_step, "tls", true, target, optimize, zzz);
add_http_example(b, all_http_examples_step, "rest", false, target, optimize, zzz);

if (target.result.os.tag != .windows) {
add_example(b, "unix", false, target, optimize, zzz);
add_http_example(b, all_http_examples_step, "unix", false, target, optimize, zzz);
}




const example1_ws_step = b.step("ex_ws_1", "Build ws example1");
const example2_ws_step = b.step("ex_ws_2", "Build ws example2");
const example3_ws_step = b.step("ex_ws_3", "Build ws example3");
const example4_ws_step = b.step("ex_ws_4", "Build ws example4");

const exe_ws1 = b.addExecutable(.{ // without C libs
.name = "ex_ws_1", // exe name
.root_source_file = b.path("examples_ws/example_ws_1.zig"), // b.path("src/test1.zig"), // main file
.target = target,
.optimize = optimize,
});
const exe_ws2 = b.addExecutable(.{ // without C libs
.name = "ex_ws_2", // exe name
.root_source_file = b.path("examples_ws/example_ws_2.zig"), // main file
.target = target,
.optimize = optimize,
});
const exe_ws3 = b.addExecutable(.{ // without C libs
.name = "ex_ws_3", // exe name
.root_source_file = b.path("examples_ws/example_ws_3.zig"), // main file
.target = target,
.optimize = optimize,
});
const exe_ws4 = b.addExecutable(.{ // without C libs
.name = "ex_ws_4", // exe name
.root_source_file = b.path("examples_ws/example_ws_4.zig"), // main file
.target = target,
.optimize = optimize,
});

exe_ws1.root_module.addImport("zzz", zzz);
exe_ws2.root_module.addImport("zzz", zzz);
exe_ws3.root_module.addImport("zzz", zzz);
exe_ws4.root_module.addImport("zzz", zzz);

const install_ws1 = b.addInstallBinFile(exe_ws1.getEmittedBin(), "../../ex_ws_1"); // b.addInstallBinFile(exe_ws1.getEmittedBin(), "ex_ws_1"); // -femit-bin=ex_ws_1 // to project root
b.getInstallStep().dependOn(&install_ws1.step);
example1_ws_step.dependOn(&install_ws1.step);
const install_ws2 = b.addInstallBinFile(exe_ws2.getEmittedBin(), "../../ex_ws_2"); // to project root
b.getInstallStep().dependOn(&install_ws2.step);
example2_ws_step.dependOn(&install_ws2.step);
const install_ws3 = b.addInstallBinFile(exe_ws3.getEmittedBin(), "../../ex_ws_3"); // to project root
b.getInstallStep().dependOn(&install_ws3.step);
example3_ws_step.dependOn(&install_ws3.step);
const install_ws4 = b.addInstallBinFile(exe_ws4.getEmittedBin(), "../../ex_ws_4"); // to project root
b.getInstallStep().dependOn(&install_ws4.step);
example4_ws_step.dependOn(&install_ws4.step);
b.default_step = b.getInstallStep();
//b.installArtifact(exe_test1); // saves to /zig-out/bin/test1

const all_ws_examples_step = b.step("examples_ws", "Build all WS examples");
all_ws_examples_step.dependOn(&install_ws1.step);
all_ws_examples_step.dependOn(&install_ws2.step);
all_ws_examples_step.dependOn(&install_ws3.step);
all_ws_examples_step.dependOn(&install_ws4.step);


const tests = b.addTest(.{
.name = "tests",
.root_source_file = b.path("./src/tests.zig"),
Expand All @@ -50,8 +112,9 @@ pub fn build(b: *std.Build) void {
test_step.dependOn(&run_test.step);
}

fn add_example(
fn add_http_example(
b: *std.Build,
all_http_examples_step: *std.Build.Step,
name: []const u8,
link_libc: bool,
target: std.Build.ResolvedTarget,
Expand All @@ -60,7 +123,7 @@ fn add_example(
) void {
const example = b.addExecutable(.{
.name = name,
.root_source_file = b.path(b.fmt("./examples/{s}/main.zig", .{name})),
.root_source_file = b.path(b.fmt("./examples_http/{s}/main.zig", .{name})),
.target = target,
.optimize = optimize,
.strip = false,
Expand All @@ -72,9 +135,12 @@ fn add_example(

example.root_module.addImport("zzz", zzz_module);

const install_artifact = b.addInstallArtifact(example, .{});
//const install_artifact = b.addInstallArtifact(example, .{});
const install_artifact = b.addInstallBinFile(example.getEmittedBin(), b.fmt("../../{s}", .{name})); // to project root
b.getInstallStep().dependOn(&install_artifact.step);

all_http_examples_step.dependOn(&install_artifact.step);

const build_step = b.step(b.fmt("{s}", .{name}), b.fmt("Build zzz example ({s})", .{name}));
build_step.dependOn(&install_artifact.step);

Expand All @@ -85,3 +151,4 @@ fn add_example(
run_step.dependOn(&install_artifact.step);
run_step.dependOn(&run_artifact.step);
}

16 changes: 10 additions & 6 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
.{
.name = .zzz,
.fingerprint = 0xc3273dca261a7ae0,
.fingerprint = 0xc3273dca46e69cd6,
.version = "0.3.0",
.minimum_zig_version = "0.14.0",
.minimum_zig_version = "0.14.1",
.dependencies = .{
.tardy = .{
.url = "git+https://github.com/tardy-org/tardy?ref=v0.3.0#cd454060f3b6006368d53c05ab96cd16c73c34de",
.hash = "tardy-0.3.0-69wrgi7PAwDFhO7m0aXae6N15s2b28VIOrnRrSHHake6",
//.url = "git+https://github.com/tardy-org/tardy?ref=v0.3.0#cd454060f3b6006368d53c05ab96cd16c73c34de",
//.hash = "tardy-0.3.0-69wrgi7PAwDFhO7m0aXae6N15s2b28VIOrnRrSHHake6",
.url = "git+https://github.com/221V/tardy?ref=zig-0.14#4e0e33d8c4bc666262ab8b1a11dccb2e6703ff78",
.hash = "tardy-0.3.0-zwolxQTOAwDsVB0HQYuUzUDDi8YzZApgKg7VXzQws9zq",
},
.secsock = .{
.url = "git+https://github.com/tardy-org/secsock?ref=v0.1.0#263dcd630e32c7a5c7a0522a8d1fd04e39b75c24",
.hash = "secsock-0.0.0-p0qurf09AQD95s1NQF2MGpBqMmFz7cKZWibsgv_SQBAr",
//.url = "git+https://github.com/tardy-org/secsock?ref=v0.1.0#263dcd630e32c7a5c7a0522a8d1fd04e39b75c24",
//.hash = "secsock-0.0.0-p0qurf09AQD95s1NQF2MGpBqMmFz7cKZWibsgv_SQBAr",
.url = "git+https://github.com/221V/secsock?ref=zig-0.14#3ee4405b051cbbb458a8f7ffaec305ea355a4ea2",
.hash = "secsock-0.0.0-p0qurcM-AQBHDulqDh4EfyXGzGEFmEOu06vI2HiajIQJ",
},
},

Expand Down
File renamed without changes.
File renamed without changes.
63 changes: 48 additions & 15 deletions examples/form/main.zig → examples_http/form/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const Respond = http.Respond;

fn base_handler(ctx: *const Context, _: void) !Respond {
const body =
\\<!DOCTYPE html>
\\<html>
\\<head><meta charset="UTF-8"></head>
\\<body>
\\<form>
\\ <label for="fname">First name:</label>
\\ <input type="text" id="fname" name="fname"><br><br>
Expand All @@ -30,7 +34,9 @@ fn base_handler(ctx: *const Context, _: void) !Respond {
\\ <input type="text" id="height" name="height"><br><br>
\\ <button formaction="/generate" formmethod="get">GET Submit</button>
\\ <button formaction="/generate" formmethod="post">POST Submit</button>
\\</form>
\\</form>
\\</body>
\\</html>
;

return ctx.response.apply(.{
Expand All @@ -41,37 +47,64 @@ fn base_handler(ctx: *const Context, _: void) !Respond {
}

const UserInfo = struct {
fname: []const u8,
mname: []const u8 = "Middle",
lname: []const u8,
age: u8,
height: f32,
weight: ?[]const u8,
fname: ?[]const u8 = null,
mname: ?[]const u8 = "Middle",
lname: ?[]const u8 = null,
age: ?[]const u8 = null,
height: ?[]const u8 = null,
weight: ?[]const u8 = null,
};

fn generate_handler(ctx: *const Context, _: void) !Respond {
//std.debug.print("Handler entered, method: {any}\n", .{ctx.request.method});
const info = switch (ctx.request.method.?) {
.GET => try Query(UserInfo).parse(ctx.allocator, ctx),
.POST => try Form(UserInfo).parse(ctx.allocator, ctx),
.GET => Query(UserInfo).parse(ctx.allocator, ctx) catch |err| {
std.debug.print("Query parse failed: {}\n", .{err});
return ctx.response.apply(.{
.status = .@"Bad Request",
.mime = http.Mime.TEXT,
.headers = &.{ .{ "Content-Type", "text/plain; charset=utf-8" } },
.body = "Invalid or empty query parameters",
});
},
.POST => Form(UserInfo).parse(ctx.allocator, ctx) catch |err| {
std.debug.print("Form parse failed: {}\n", .{err});
return ctx.response.apply(.{
.status = .@"Bad Request",
.mime = http.Mime.TEXT,
.headers = &.{ .{ "Content-Type", "text/plain; charset=utf-8" } },
.body = "Invalid or empty form data",
});
},
else => return error.UnexpectedMethod,
};

const fname = info.fname orelse "";
const mname = info.mname orelse "Middle";
const lname = info.lname orelse "";
const age = if (info.age) |v| std.fmt.parseInt(u8, v, 10) catch 0 else 0;
const height = if (info.height) |v| std.fmt.parseFloat(f32, v) catch 0.0 else 0.0;
const weight = if (info.weight) |w| if (w.len == 0) "none" else w else "none";

const body = try std.fmt.allocPrint(
ctx.allocator,
"First: {s} | Middle: {s} | Last: {s} | Age: {d} | Height: {d} | Weight: {s}",
.{
info.fname,
info.mname,
info.lname,
info.age,
info.height,
info.weight orelse "none",
if (fname.len == 0) "(empty)" else fname,
if (mname.len == 0) "Middle" else mname,
if (lname.len == 0) "(empty)" else lname,
age,
height,
weight,
},
);

return ctx.response.apply(.{
.status = .OK,
.mime = http.Mime.TEXT,
.headers = &.{
.{ "Content-Type", "text/plain; charset=utf-8" },
},
.body = body,
});
}
Expand Down
2 changes: 1 addition & 1 deletion examples/fs/main.zig → examples_http/fs/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub fn main() !void {
var t = try Tardy.init(allocator, .{ .threading = .auto });
defer t.deinit();

const static_dir = Dir.from_std(try std.fs.cwd().openDir("examples/fs/static", .{}));
const static_dir = Dir.from_std(try std.fs.cwd().openDir("examples_http/fs/static", .{}));

var router = try Router.init(allocator, &.{
Compression(.{ .gzip = .{} }),
Expand Down
File renamed without changes.
File renamed without changes.
Loading