mirror of
https://github.com/zigzap/zap.git
synced 2025-10-20 15:14:08 +00:00
access raw query params w/o allocator, close #40
This commit is contained in:
parent
42e96b4875
commit
680e981d13
3 changed files with 124 additions and 8 deletions
|
@ -47,6 +47,27 @@ pub fn main() !void {
|
|||
const param_count = r.getParamCount();
|
||||
std.log.info("param_count: {}", .{param_count});
|
||||
|
||||
// ================================================================
|
||||
// Access RAW params from querystring
|
||||
// ================================================================
|
||||
|
||||
// let's get param "one" by name
|
||||
std.debug.print("\n", .{});
|
||||
if (r.getParamSlice("one")) |maybe_str| {
|
||||
std.log.info("Param one = {s}", .{maybe_str});
|
||||
} else {
|
||||
std.log.info("Param one not found!", .{});
|
||||
}
|
||||
|
||||
var arg_it = r.getParamSlices();
|
||||
while (arg_it.next()) |param| {
|
||||
std.log.info("ParamStr `{s}` is `{s}`", .{ param.name, param.value });
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Access DECODED and typed params
|
||||
// ================================================================
|
||||
|
||||
// iterate over all params as strings
|
||||
var strparams = r.parametersToOwnedStrList(alloc, false) catch unreachable;
|
||||
defer strparams.deinit();
|
||||
|
@ -82,15 +103,10 @@ pub fn main() !void {
|
|||
}
|
||||
|
||||
// check if we received a terminate=true parameter
|
||||
if (r.getParamStr(alloc, "terminate", false)) |maybe_str| {
|
||||
if (maybe_str) |*s| {
|
||||
defer s.deinit();
|
||||
if (std.mem.eql(u8, s.str, "true")) {
|
||||
zap.stop();
|
||||
}
|
||||
if (r.getParamSlice("terminate")) |maybe_str| {
|
||||
if (std.mem.eql(u8, maybe_str, "true")) {
|
||||
zap.stop();
|
||||
}
|
||||
} else |err| {
|
||||
std.log.err("cannot check for terminate param: {any}\n", .{err});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -737,3 +737,59 @@ pub fn getParamStr(self: *const Self, a: std.mem.Allocator, name: []const u8, al
|
|||
}
|
||||
return try util.fio2strAllocOrNot(a, value, always_alloc);
|
||||
}
|
||||
|
||||
/// similar to getParamStr, except it will return the part of the querystring
|
||||
/// after the equals sign, non-decoded, and always as character slice.
|
||||
/// - no allocation!
|
||||
/// - does not requre parseQuery() or anything to be called in advance
|
||||
pub fn getParamSlice(self: *const Self, name: []const u8) ?[]const u8 {
|
||||
if (self.query) |query| {
|
||||
var amp_it = std.mem.tokenizeScalar(u8, query, '&');
|
||||
while (amp_it.next()) |maybe_pair| {
|
||||
if (std.mem.indexOfScalar(u8, maybe_pair, '=')) |pos_of_eq| {
|
||||
const pname = maybe_pair[0..pos_of_eq];
|
||||
if (std.mem.eql(u8, pname, name)) {
|
||||
if (maybe_pair.len > pos_of_eq) {
|
||||
const pval = maybe_pair[pos_of_eq + 1 ..];
|
||||
return pval;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub const ParameterSlices = struct { name: []const u8, value: []const u8 };
|
||||
|
||||
pub const ParamSliceIterator = struct {
|
||||
amp_it: std.mem.TokenIterator(u8, .scalar),
|
||||
|
||||
pub fn init(query: []const u8) @This() {
|
||||
// const query = r.query orelse "";
|
||||
return .{
|
||||
.amp_it = std.mem.tokenizeScalar(u8, query, '&'),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn next(self: *@This()) ?ParameterSlices {
|
||||
while (self.amp_it.next()) |maybe_pair| {
|
||||
if (std.mem.indexOfScalar(u8, maybe_pair, '=')) |pos_of_eq| {
|
||||
const pname = maybe_pair[0..pos_of_eq];
|
||||
if (maybe_pair.len > pos_of_eq) {
|
||||
const pval = maybe_pair[pos_of_eq + 1 ..];
|
||||
return .{ .name = pname, .value = pval };
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/// Returns an iterator that yields all query parameters on next() in the
|
||||
/// form of a ParameterSlices struct { .name, .value }
|
||||
/// As with getParamSlice(), the value is not decoded
|
||||
pub fn getParamSlices(self: *const Self) ParamSliceIterator {
|
||||
const query = self.query orelse "";
|
||||
return ParamSliceIterator.init(query);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ test "http parameters" {
|
|||
var strParams: ?zap.Request.HttpParamStrKVList = null;
|
||||
var params: ?zap.Request.HttpParamKVList = null;
|
||||
var paramOneStr: ?zap.FreeOrNot = null;
|
||||
var paramOneSlice: ?[]const u8 = null;
|
||||
var paramSlices: zap.Request.ParamSliceIterator = undefined;
|
||||
|
||||
pub fn on_request(r: zap.Request) void {
|
||||
ran = true;
|
||||
|
@ -49,6 +51,14 @@ test "http parameters" {
|
|||
if (maybe_str) |*s| {
|
||||
paramOneStr = s.*;
|
||||
}
|
||||
|
||||
paramOneSlice = blk: {
|
||||
if (r.getParamSlice("one")) |val| break :blk alloc.dupe(u8, val) catch unreachable;
|
||||
break :blk null;
|
||||
};
|
||||
|
||||
// paramSlices = zap.Request.ParamSliceIterator.init(r);
|
||||
paramSlices = r.getParamSlices();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -85,12 +95,18 @@ test "http parameters" {
|
|||
// allocator.free(p);
|
||||
p.deinit();
|
||||
}
|
||||
|
||||
if (Handler.paramOneSlice) |p| {
|
||||
Handler.alloc.free(p);
|
||||
}
|
||||
}
|
||||
|
||||
try std.testing.expectEqual(Handler.ran, true);
|
||||
try std.testing.expectEqual(Handler.param_count, 5);
|
||||
try std.testing.expect(Handler.paramOneStr != null);
|
||||
try std.testing.expectEqualStrings(Handler.paramOneStr.?.str, "1");
|
||||
try std.testing.expect(Handler.paramOneSlice != null);
|
||||
try std.testing.expectEqualStrings(Handler.paramOneSlice.?, "1");
|
||||
try std.testing.expect(Handler.strParams != null);
|
||||
for (Handler.strParams.?.items, 0..) |kv, i| {
|
||||
switch (i) {
|
||||
|
@ -118,6 +134,34 @@ test "http parameters" {
|
|||
}
|
||||
}
|
||||
|
||||
var pindex: usize = 0;
|
||||
while (Handler.paramSlices.next()) |param| {
|
||||
switch (pindex) {
|
||||
0 => {
|
||||
try std.testing.expectEqualStrings(param.name, "one");
|
||||
try std.testing.expectEqualStrings(param.value, "1");
|
||||
},
|
||||
1 => {
|
||||
try std.testing.expectEqualStrings(param.name, "two");
|
||||
try std.testing.expectEqualStrings(param.value, "2");
|
||||
},
|
||||
2 => {
|
||||
try std.testing.expectEqualStrings(param.name, "string");
|
||||
try std.testing.expectEqualStrings(param.value, "hello+world");
|
||||
},
|
||||
3 => {
|
||||
try std.testing.expectEqualStrings(param.name, "float");
|
||||
try std.testing.expectEqualStrings(param.value, "6.28");
|
||||
},
|
||||
4 => {
|
||||
try std.testing.expectEqualStrings(param.name, "bool");
|
||||
try std.testing.expectEqualStrings(param.value, "true");
|
||||
},
|
||||
else => return error.TooManyArgs,
|
||||
}
|
||||
pindex += 1;
|
||||
}
|
||||
|
||||
for (Handler.params.?.items, 0..) |kv, i| {
|
||||
switch (i) {
|
||||
0 => {
|
||||
|
|
Loading…
Add table
Reference in a new issue