mirror of
https://github.com/zigzap/zap.git
synced 2025-10-20 23:24:09 +00:00
200 lines
6.9 KiB
Zig
200 lines
6.9 KiB
Zig
const std = @import("std");
|
|
const zap = @import("zap");
|
|
|
|
fn makeRequest(a: std.mem.Allocator, url: []const u8) !void {
|
|
var http_client: std.http.Client = .{ .allocator = a };
|
|
defer http_client.deinit();
|
|
|
|
_ = try http_client.fetch(.{
|
|
.location = .{ .url = url },
|
|
});
|
|
|
|
zap.stop();
|
|
}
|
|
|
|
fn makeRequestThread(a: std.mem.Allocator, url: []const u8) !std.Thread {
|
|
return try std.Thread.spawn(.{}, makeRequest, .{ a, url });
|
|
}
|
|
|
|
test "http parameters" {
|
|
const allocator = std.testing.allocator;
|
|
|
|
const Handler = struct {
|
|
var alloc: std.mem.Allocator = undefined;
|
|
var ran: bool = false;
|
|
var param_count: isize = 0;
|
|
|
|
var strParams: ?zap.Request.HttpParamStrKVList = null;
|
|
var params: ?zap.Request.HttpParamKVList = null;
|
|
var paramOneStr: ?[]const u8 = null;
|
|
var paramOneSlice: ?[]const u8 = null;
|
|
var paramSlices: zap.Request.ParamSliceIterator = undefined;
|
|
|
|
pub fn on_request(r: zap.Request) !void {
|
|
ran = true;
|
|
r.parseQuery();
|
|
param_count = r.getParamCount();
|
|
|
|
// true -> make copies of temp strings
|
|
strParams = r.parametersToOwnedStrList(alloc) catch unreachable;
|
|
|
|
// true -> make copies of temp strings
|
|
params = r.parametersToOwnedList(alloc) catch unreachable;
|
|
|
|
paramOneStr = r.getParamStr(alloc, "one") catch unreachable;
|
|
|
|
// we need to dupe it here because the request object r will get
|
|
// invalidated at the end of the function but we need to check
|
|
// its correctness later in the test
|
|
paramOneSlice = if (r.getParamSlice("one")) |slice| alloc.dupe(u8, slice) catch unreachable else null;
|
|
|
|
paramSlices = r.getParamSlices();
|
|
}
|
|
};
|
|
|
|
Handler.alloc = allocator;
|
|
|
|
// setup listener
|
|
var listener = zap.HttpListener.init(
|
|
.{
|
|
.port = 3001,
|
|
.on_request = Handler.on_request,
|
|
.log = false,
|
|
.max_clients = 10,
|
|
.max_body_size = 1 * 1024,
|
|
},
|
|
);
|
|
zap.enableDebugLog();
|
|
try listener.listen();
|
|
|
|
const thread = try makeRequestThread(allocator, "http://127.0.0.1:3001/?one=1&two=2&string=hello+world&float=6.28&bool=true");
|
|
defer thread.join();
|
|
zap.start(.{
|
|
.threads = 1,
|
|
.workers = 1,
|
|
});
|
|
|
|
defer {
|
|
if (Handler.strParams) |*p| {
|
|
p.deinit();
|
|
}
|
|
if (Handler.params) |*p| {
|
|
p.deinit();
|
|
}
|
|
|
|
if (Handler.paramOneStr) |p| {
|
|
allocator.free(p);
|
|
}
|
|
|
|
if (Handler.paramOneSlice) |p| {
|
|
allocator.free(p);
|
|
}
|
|
}
|
|
|
|
try std.testing.expectEqual(true, Handler.ran);
|
|
try std.testing.expectEqual(5, Handler.param_count);
|
|
try std.testing.expect(Handler.paramOneStr != null);
|
|
try std.testing.expectEqualStrings("1", Handler.paramOneStr.?);
|
|
try std.testing.expect(Handler.paramOneSlice != null);
|
|
try std.testing.expectEqualStrings("1", Handler.paramOneSlice.?);
|
|
try std.testing.expect(Handler.strParams != null);
|
|
for (Handler.strParams.?.items, 0..) |kv, i| {
|
|
switch (i) {
|
|
0 => {
|
|
try std.testing.expectEqualStrings("one", kv.key);
|
|
try std.testing.expectEqualStrings("1", kv.value);
|
|
},
|
|
1 => {
|
|
try std.testing.expectEqualStrings("two", kv.key);
|
|
try std.testing.expectEqualStrings("2", kv.value);
|
|
},
|
|
2 => {
|
|
try std.testing.expectEqualStrings("string", kv.key);
|
|
try std.testing.expectEqualStrings("hello world", kv.value);
|
|
},
|
|
3 => {
|
|
try std.testing.expectEqualStrings("float", kv.key);
|
|
try std.testing.expectEqualStrings("6.28", kv.value);
|
|
},
|
|
4 => {
|
|
try std.testing.expectEqualStrings("bool", kv.key);
|
|
try std.testing.expectEqualStrings("true", kv.value);
|
|
},
|
|
else => return error.TooManyArgs,
|
|
}
|
|
}
|
|
|
|
var pindex: usize = 0;
|
|
while (Handler.paramSlices.next()) |param| {
|
|
switch (pindex) {
|
|
0 => {
|
|
try std.testing.expectEqualStrings("one", param.name);
|
|
try std.testing.expectEqualStrings("1", param.value);
|
|
},
|
|
1 => {
|
|
try std.testing.expectEqualStrings("two", param.name);
|
|
try std.testing.expectEqualStrings("2", param.value);
|
|
},
|
|
2 => {
|
|
try std.testing.expectEqualStrings("string", param.name);
|
|
try std.testing.expectEqualStrings("hello+world", param.value);
|
|
},
|
|
3 => {
|
|
try std.testing.expectEqualStrings("float", param.name);
|
|
try std.testing.expectEqualStrings("6.28", param.value);
|
|
},
|
|
4 => {
|
|
try std.testing.expectEqualStrings("bool", param.name);
|
|
try std.testing.expectEqualStrings("true", param.value);
|
|
},
|
|
else => return error.TooManyArgs,
|
|
}
|
|
pindex += 1;
|
|
}
|
|
|
|
for (Handler.params.?.items, 0..) |kv, i| {
|
|
switch (i) {
|
|
0 => {
|
|
try std.testing.expectEqualStrings("one", kv.key);
|
|
try std.testing.expect(kv.value != null);
|
|
switch (kv.value.?) {
|
|
.Int => |n| try std.testing.expectEqual(1, n),
|
|
else => return error.InvalidHttpParamType,
|
|
}
|
|
},
|
|
1 => {
|
|
try std.testing.expectEqualStrings("two", kv.key);
|
|
try std.testing.expect(kv.value != null);
|
|
switch (kv.value.?) {
|
|
.Int => |n| try std.testing.expectEqual(2, n),
|
|
else => return error.InvalidHttpParamType,
|
|
}
|
|
},
|
|
2 => {
|
|
try std.testing.expectEqualStrings("string", kv.key);
|
|
try std.testing.expect(kv.value != null);
|
|
switch (kv.value.?) {
|
|
.String => |s| try std.testing.expectEqualStrings("hello world", s),
|
|
else => return error.InvalidHttpParamType,
|
|
}
|
|
},
|
|
3 => {
|
|
try std.testing.expectEqualStrings("float", kv.key);
|
|
try std.testing.expect(kv.value != null);
|
|
switch (kv.value.?) {
|
|
.Float => |f| try std.testing.expectEqual(6.28, f),
|
|
else => return error.InvalidHttpParamType,
|
|
}
|
|
},
|
|
4 => {
|
|
try std.testing.expectEqualStrings("bool", kv.key);
|
|
try std.testing.expect(kv.value != null);
|
|
switch (kv.value.?) {
|
|
.Bool => |b| try std.testing.expectEqual(true, b),
|
|
else => return error.InvalidHttpParamType,
|
|
}
|
|
},
|
|
else => return error.TooManyArgs,
|
|
}
|
|
}
|
|
}
|