add Response cookie
This commit is contained in:
parent
a820ef1f91
commit
64ace43684
3 changed files with 50 additions and 2 deletions
35
src/res_cookie.zig
Normal file
35
src/res_cookie.zig
Normal file
|
@ -0,0 +1,35 @@
|
|||
const std = @import("std");
|
||||
const types = @import("types.zig");
|
||||
|
||||
pub const Cookie = struct {
|
||||
name: []const u8,
|
||||
value: []const u8,
|
||||
path: []const u8 = "/",
|
||||
domain: []const u8 = "",
|
||||
maxAge: i64 = 0,
|
||||
secure: bool = true,
|
||||
httpOnly: bool = true,
|
||||
sameSite: SameSite = .lax,
|
||||
|
||||
pub fn stringify(self: Cookie, allocator: std.mem.Allocator) ![]const u8 {
|
||||
const domain = if (std.mem.eql(u8, self.domain, "")) self.domain else try std.fmt.allocPrint(allocator, "Domain={s}; ", .{self.domain});
|
||||
defer allocator.free(domain);
|
||||
const secure = if (self.secure) "Secure; " else "";
|
||||
const httpOnly = if (self.httpOnly) "HttpOnly; " else "";
|
||||
return try std.fmt.allocPrint(allocator, "Set-Cookie: {s}={s}; {s}Max-Age={}; {s}{s}{s}\n", .{ self.name, self.value, domain, self.maxAge, secure, httpOnly, getSameSite(&self) });
|
||||
}
|
||||
};
|
||||
|
||||
pub const SameSite = enum {
|
||||
lax,
|
||||
strict,
|
||||
none,
|
||||
};
|
||||
|
||||
pub fn getSameSite(c: *const Cookie) []const u8 {
|
||||
switch (c.sameSite) {
|
||||
.lax => return "SameSite=Lax;",
|
||||
.strict => return "SameSite=Strict;",
|
||||
.none => return "SameSite=None;",
|
||||
}
|
||||
}
|
|
@ -136,13 +136,19 @@ fn stringifyResponse(r: Response, allocator: std.mem.Allocator) ![]const u8 {
|
|||
try res.append(' ');
|
||||
try res.appendSlice(r.status.stringify());
|
||||
try res.appendSlice("\r\n");
|
||||
|
||||
// Add headers
|
||||
for (r.headers) |header| {
|
||||
try res.appendSlice(header.key);
|
||||
try res.appendSlice(": ");
|
||||
try res.appendSlice(header.value);
|
||||
try res.appendSlice("\n");
|
||||
}
|
||||
// Add cookie-headers
|
||||
for (r.cookies) |cookie| {
|
||||
const c = try cookie.stringify(allocator);
|
||||
defer allocator.free(c);
|
||||
if (!eql(u8, cookie.name, "") and !eql(u8, cookie.value, "")) try res.appendSlice(c);
|
||||
}
|
||||
try res.appendSlice("\r\n\r\n");
|
||||
try res.appendSlice(r.body);
|
||||
|
||||
|
@ -159,10 +165,14 @@ test "stringify Response" {
|
|||
}
|
||||
|
||||
test "Run server" {
|
||||
// Set route
|
||||
const rt = [_]types.Route{.{ "/", handlefn }};
|
||||
try Server.listen("0.0.0.0", 8080, &rt, std.testing.allocator);
|
||||
}
|
||||
// Function for test "Run Server"
|
||||
fn handlefn(_: *types.Request) types.Response {
|
||||
return types.Response.write("<h1>Run Server Test OK!</h1>");
|
||||
// create Response and add cookie to test cookie setting
|
||||
const rc = @import("./res_cookie.zig");
|
||||
var res = types.Response{ .body = "<h1>Run Server Test OK!</h1>", .cookies = &[_]rc.Cookie{.{ .name = "Test-Cookie", .value = "Test", .domain = "localhost:8080" }} };
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ const tuple = std.meta.Tuple;
|
|||
const allocator = std.heap.page_allocator;
|
||||
const eql = std.mem.eql;
|
||||
const stat = @import("./status.zig");
|
||||
const rc = @import("./res_cookie.zig");
|
||||
|
||||
/// Route is a touple that consists of the path and the function that shall handle it.
|
||||
/// e.g. `const rt = Route{"/home", home};`
|
||||
|
@ -103,6 +104,8 @@ pub const Response = struct {
|
|||
status: stat.Status = stat.Status.OK,
|
||||
/// Response eaders sent by the server
|
||||
headers: []const Header = &[_]Header{.{ .key = "Content-Type", .value = "text/html; charset=utf-8" }},
|
||||
/// Cookies to be sent
|
||||
cookies: []const rc.Cookie = &[_]rc.Cookie{.{ .name = "", .value = "" }},
|
||||
/// Response body sent by the server
|
||||
body: []const u8 = "",
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue