mirror of
https://github.com/zigzap/zap.git
synced 2025-10-20 23:24:09 +00:00
fix mem leaks in UserPassSessionAuth
This commit is contained in:
parent
a132b78b23
commit
48b399e056
2 changed files with 75 additions and 47 deletions
|
@ -85,6 +85,14 @@ fn on_request(r: zap.SimpleRequest) void {
|
||||||
return on_logout(r);
|
return on_logout(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /logout can be shown since we're still authenticated for this
|
||||||
|
// very request
|
||||||
|
if (std.mem.startsWith(u8, p, "/stop")) {
|
||||||
|
std.log.info(" + for /stop --> logout page", .{});
|
||||||
|
zap.stop();
|
||||||
|
return on_logout(r);
|
||||||
|
}
|
||||||
|
|
||||||
// any other paths will still show the normal page
|
// any other paths will still show the normal page
|
||||||
std.log.info(" + --> normal page", .{});
|
std.log.info(" + --> normal page", .{});
|
||||||
return on_normal_page(r);
|
return on_normal_page(r);
|
||||||
|
@ -100,48 +108,59 @@ pub fn main() !void {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{
|
var gpa = std.heap.GeneralPurposeAllocator(.{
|
||||||
.thread_safe = true,
|
.thread_safe = true,
|
||||||
}){};
|
}){};
|
||||||
var allocator = gpa.allocator();
|
|
||||||
|
|
||||||
var listener = zap.SimpleHttpListener.init(.{
|
// we start a block here so the defers will run before we call the gpa
|
||||||
.port = 3000,
|
// to detect leaks
|
||||||
.on_request = on_request,
|
{
|
||||||
.log = true,
|
var allocator = gpa.allocator();
|
||||||
.max_clients = 100000,
|
var listener = zap.SimpleHttpListener.init(.{
|
||||||
});
|
.port = 3000,
|
||||||
try listener.listen();
|
.on_request = on_request,
|
||||||
|
.log = true,
|
||||||
|
.max_clients = 100000,
|
||||||
|
});
|
||||||
|
try listener.listen();
|
||||||
|
|
||||||
zap.enableDebugLog();
|
zap.enableDebugLog();
|
||||||
|
|
||||||
// add a single user to our allowed users
|
// add a single user to our allowed users
|
||||||
var userpass = Lookup.init(allocator);
|
var userpass = Lookup.init(allocator);
|
||||||
try userpass.put("zap", "awesome");
|
defer userpass.deinit();
|
||||||
|
try userpass.put("zap", "awesome");
|
||||||
|
|
||||||
// init our auth
|
// init our auth
|
||||||
authenticator = try Authenticator.init(
|
authenticator = try Authenticator.init(
|
||||||
allocator,
|
allocator,
|
||||||
&userpass,
|
&userpass,
|
||||||
.{
|
.{
|
||||||
.usernameParam = "username",
|
.usernameParam = "username",
|
||||||
.passwordParam = "password",
|
.passwordParam = "password",
|
||||||
.loginPage = loginpath,
|
.loginPage = loginpath,
|
||||||
.cookieName = "zap-session",
|
.cookieName = "zap-session",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
defer authenticator.deinit();
|
||||||
|
|
||||||
// just some debug output: listing the session tokens the authenticator may
|
// just some debug output: listing the session tokens the authenticator may
|
||||||
// have generated already (if auth_lock_token_table == false).
|
// have generated already (if auth_lock_token_table == false).
|
||||||
const lookup = authenticator.sessionTokens;
|
const lookup = authenticator.sessionTokens;
|
||||||
std.debug.print("\nauth token list len: {d}\n", .{lookup.count()});
|
std.debug.print("\nauth token list len: {d}\n", .{lookup.count()});
|
||||||
var it = lookup.iterator();
|
var it = lookup.iterator();
|
||||||
while (it.next()) |item| {
|
while (it.next()) |item| {
|
||||||
std.debug.print(" {s}\n", .{item.key_ptr.*});
|
std.debug.print(" {s}\n", .{item.key_ptr.*});
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.print("Visit me on http://127.0.0.1:3000\n", .{});
|
||||||
|
|
||||||
|
// start worker threads
|
||||||
|
zap.start(.{
|
||||||
|
.threads = 2,
|
||||||
|
.workers = 1,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std.debug.print("Visit me on http://127.0.0.1:3000\n", .{});
|
// all defers should have run by now
|
||||||
|
std.debug.print("\n\nSTOPPED!\n\n", .{});
|
||||||
// start worker threads
|
const leaked = gpa.detectLeaks();
|
||||||
zap.start(.{
|
std.debug.print("Leaks detected: {}\n", .{leaked});
|
||||||
.threads = 2,
|
|
||||||
.workers = 1,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,12 +395,27 @@ pub fn UserPassSessionAuth(comptime Lookup: type, comptime lockedPwLookups: bool
|
||||||
while (it.next()) |kv| {
|
while (it.next()) |kv| {
|
||||||
// we iterate over all usernames and passwords, create tokens,
|
// we iterate over all usernames and passwords, create tokens,
|
||||||
// and memorize the tokens
|
// and memorize the tokens
|
||||||
_ = try ret.createAndStoreSessionToken(kv.key_ptr.*, kv.value_ptr.*);
|
const token = try ret.createAndStoreSessionToken(kv.key_ptr.*, kv.value_ptr.*);
|
||||||
|
allocator.free(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Self) void {
|
||||||
|
self.allocator.free(self.settings.usernameParam);
|
||||||
|
self.allocator.free(self.settings.passwordParam);
|
||||||
|
self.allocator.free(self.settings.loginPage);
|
||||||
|
self.allocator.free(self.settings.cookieName);
|
||||||
|
|
||||||
|
// clean up the session tokens: the key strings are duped
|
||||||
|
var key_it = self.sessionTokens.keyIterator();
|
||||||
|
while (key_it.next()) |key_ptr| {
|
||||||
|
self.allocator.free(key_ptr.*);
|
||||||
|
}
|
||||||
|
self.sessionTokens.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
/// Check for session token cookie, remove the token from the valid tokens
|
/// Check for session token cookie, remove the token from the valid tokens
|
||||||
/// Note: only valid if lockedTokenLookups == true
|
/// Note: only valid if lockedTokenLookups == true
|
||||||
pub fn logout(self: *Self, r: *const zap.SimpleRequest) void {
|
pub fn logout(self: *Self, r: *const zap.SimpleRequest) void {
|
||||||
|
@ -447,13 +462,6 @@ pub fn UserPassSessionAuth(comptime Lookup: type, comptime lockedPwLookups: bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *const Self) void {
|
|
||||||
self.allocator.free(self.settings.usernameParam);
|
|
||||||
self.allocator.free(self.settings.passwordParam);
|
|
||||||
self.allocator.free(self.settings.loginPage);
|
|
||||||
self.allocator.free(self.settings.cookieName);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn _internal_authenticateRequest(self: *Self, r: *const zap.SimpleRequest) AuthResult {
|
fn _internal_authenticateRequest(self: *Self, r: *const zap.SimpleRequest) AuthResult {
|
||||||
// if we're requesting the login page, let the request through
|
// if we're requesting the login page, let the request through
|
||||||
if (r.path) |p| {
|
if (r.path) |p| {
|
||||||
|
@ -521,6 +529,7 @@ pub fn UserPassSessionAuth(comptime Lookup: type, comptime lockedPwLookups: bool
|
||||||
if (std.mem.eql(u8, pw.str, correct_pw)) {
|
if (std.mem.eql(u8, pw.str, correct_pw)) {
|
||||||
// create session token
|
// create session token
|
||||||
if (self.createAndStoreSessionToken(username.str, pw.str)) |token| {
|
if (self.createAndStoreSessionToken(username.str, pw.str)) |token| {
|
||||||
|
defer self.allocator.free(token);
|
||||||
// now set the cookie header
|
// now set the cookie header
|
||||||
if (r.setCookie(.{
|
if (r.setCookie(.{
|
||||||
.name = self.settings.cookieName,
|
.name = self.settings.cookieName,
|
||||||
|
@ -594,11 +603,11 @@ pub fn UserPassSessionAuth(comptime Lookup: type, comptime lockedPwLookups: bool
|
||||||
defer self.tokenLookupLock.unlock();
|
defer self.tokenLookupLock.unlock();
|
||||||
|
|
||||||
if (!self.sessionTokens.contains(token)) {
|
if (!self.sessionTokens.contains(token)) {
|
||||||
try self.sessionTokens.put(token, {});
|
try self.sessionTokens.put(try self.allocator.dupe(u8, token), {});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!self.sessionTokens.contains(token)) {
|
if (!self.sessionTokens.contains(token)) {
|
||||||
try self.sessionTokens.put(token, {});
|
try self.sessionTokens.put(try self.allocator.dupe(u8, token), {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return token;
|
return token;
|
||||||
|
|
Loading…
Add table
Reference in a new issue