Skip to content

Instantly share code, notes, and snippets.

@renerocksai
Last active May 20, 2023 18:10
Show Gist options
  • Save renerocksai/c4e6f41dcb9f4c5b91d78cc8f5f1f2e0 to your computer and use it in GitHub Desktop.
Save renerocksai/c4e6f41dcb9f4c5b91d78cc8f5f1f2e0 to your computer and use it in GitHub Desktop.
Below file returns 2 cookies: one that's valid for 1min, one that's valid for 1h
const std = @import("std");
const zap = @import("zap");
// We send ourselves a request with a cookie
fn makeRequest(a: std.mem.Allocator, url: []const u8) !void {
const uri = try std.Uri.parse(url);
var h = std.http.Headers{ .allocator = a };
defer h.deinit();
var http_client: std.http.Client = .{ .allocator = a };
defer http_client.deinit();
var req = try http_client.request(.GET, uri, h, .{});
defer req.deinit();
try req.headers.append("cookie", "ZIG_ZAP=awesome");
try req.start();
try req.wait();
}
fn makeRequestThread(a: std.mem.Allocator, url: []const u8) !std.Thread {
return try std.Thread.spawn(.{}, makeRequest, .{ a, url });
}
// here we go
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{
.thread_safe = true,
}){};
var allocator = gpa.allocator();
const Handler = struct {
var alloc: std.mem.Allocator = undefined;
pub fn on_request(r: zap.SimpleRequest) void {
std.debug.print("\n=====================================================\n", .{});
defer std.debug.print("=====================================================\n\n", .{});
r.parseCookies(false);
var cookie_count = r.getCookiesCount();
std.log.info("cookie_count: {}", .{cookie_count});
// iterate over all cookies as strings
var strCookies = r.cookiesToOwnedStrList(alloc, false) catch unreachable;
defer strCookies.deinit();
std.debug.print("\n", .{});
for (strCookies.items) |kv| {
std.log.info("CookieStr `{s}` is `{s}`", .{ kv.key.str, kv.value.str });
}
std.debug.print("\n", .{});
r.setCookie(.{
.name = "zap-cookie_1min",
.value = "60",
.max_age_s = 60,
}) catch unreachable;
r.setCookie(.{
.name = "zap-cookie_1h",
.value = "3600",
.max_age_s = 3600,
}) catch unreachable;
r.sendBody("Hello") catch unreachable;
}
};
Handler.alloc = allocator;
// setup listener
var listener = zap.SimpleHttpListener.init(
.{
.port = 3000,
.on_request = Handler.on_request,
.log = false,
.max_clients = 10,
.max_body_size = 1 * 1024,
},
);
zap.enableDebugLog();
try listener.listen();
std.log.info("\n\nTerminate with CTRL+C", .{});
const thread = try makeRequestThread(allocator, "http://127.0.0.1:3000");
defer thread.join();
zap.start(.{
.threads = 1,
.workers = 0,
});
}
 curl http://localhost:3000 -v
*   Trying 127.0.0.1:3000...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.86.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< connection:keep-alive
< set-cookie:zap-cookie_1min=60; Max-Age=60; secure;
< set-cookie:zap-cookie_1h=3600; Max-Age=3600; secure;
< content-length:5
< date:Sat, 20 May 2023 17:56:28 GMT
< last-modified:Sat, 20 May 2023 17:56:28 GMT
< 
* Connection #0 to host localhost left intact
Hello

As you can see, the cookies are set correctly. However, my server reports its date timestamp, that's generated by facilio, with 2h behind my current local time. So it reports the time in UTC, not localtime.

Hence, Chrome shows the cookie as to expire in the past, because it displays server time. When I send a request to zap's cookie example, which prints all cookies, it shows: after 1min, the first cookie is gone, only the 1h cookie is sent by Chrome.

So it all works as expected. I had tested this before committing it to Zap. I use session cookies in my other projects, too, and they work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment