Skip to content

Commit

Permalink
access raw query params w/o allocator, close #40
Browse files Browse the repository at this point in the history
  • Loading branch information
renerocksai committed Feb 22, 2024
1 parent 92ad13d commit c919489
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 8 deletions.
32 changes: 24 additions & 8 deletions examples/http_params/http_params.zig
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ pub fn main() !void {
var 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();
Expand Down Expand Up @@ -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});
}
}
};
Expand Down
56 changes: 56 additions & 0 deletions src/request.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
44 changes: 44 additions & 0 deletions src/tests/test_http_params.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
}
};

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 => {
Expand Down

0 comments on commit c919489

Please sign in to comment.