add Request cookies
This commit is contained in:
parent
464d8a2516
commit
112cc73168
3 changed files with 52 additions and 3 deletions
34
src/req_cookie.zig
Normal file
34
src/req_cookie.zig
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const trim = std.mem.trim;
|
||||||
|
const split = std.mem.split;
|
||||||
|
const olderVersion: bool = @import("builtin").zig_version.minor < 11;
|
||||||
|
|
||||||
|
pub const Cookie = struct {
|
||||||
|
name: []const u8,
|
||||||
|
value: []const u8,
|
||||||
|
|
||||||
|
pub fn parse(item2: []const u8, allocator: std.mem.Allocator) ![]const Cookie {
|
||||||
|
var items = split(u8, item2, ";");
|
||||||
|
var cookie_buffer = std.ArrayList(Cookie).init(allocator);
|
||||||
|
var cookie_string = split(u8, items.first(), "=");
|
||||||
|
const first_cookie = Cookie{ .name = trim(u8, cookie_string.first(), " "), .value = trim(u8, cookie_string.next().?, " ") };
|
||||||
|
try cookie_buffer.append(first_cookie);
|
||||||
|
|
||||||
|
while (items.next()) |item| {
|
||||||
|
cookie_string = split(u8, item, "=");
|
||||||
|
const name = trim(u8, cookie_string.first(), " ");
|
||||||
|
const value = if (cookie_string.next()) |v| trim(u8, v, " ") else "";
|
||||||
|
const cookie = Cookie{ .name = name, .value = value };
|
||||||
|
try cookie_buffer.append(cookie);
|
||||||
|
}
|
||||||
|
return if (olderVersion) cookie_buffer.toOwnedSlice() else try cookie_buffer.toOwnedSlice();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "Parse Request Cookie(s)" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const cookie_string = "test_cookie=successful; second_cookie: also successful!";
|
||||||
|
const cookie = try Cookie.parse(cookie_string, allocator);
|
||||||
|
defer allocator.free(cookie);
|
||||||
|
try std.testing.expect(std.mem.eql(u8, cookie[0].value, "successful"));
|
||||||
|
}
|
|
@ -50,6 +50,7 @@ pub const Server = struct {
|
||||||
defer allocator.free(req_stream);
|
defer allocator.free(req_stream);
|
||||||
var req = try buildRequest(client_ip, req_stream, allocator);
|
var req = try buildRequest(client_ip, req_stream, allocator);
|
||||||
defer allocator.free(req.headers);
|
defer allocator.free(req.headers);
|
||||||
|
defer allocator.free(req.cookies);
|
||||||
|
|
||||||
// if there ist a path set in the uri trim the trailing slash in order to accept it later during the matching check.
|
// if there ist a path set in the uri trim the trailing slash in order to accept it later during the matching check.
|
||||||
if (req.uri.len > 1) req.uri = std.mem.trimRight(u8, req.uri, "/");
|
if (req.uri.len > 1) req.uri = std.mem.trimRight(u8, req.uri, "/");
|
||||||
|
@ -89,6 +90,7 @@ fn buildRequest(client_ip: []const u8, bytes: []const u8, allocator: std.mem.All
|
||||||
const header = parts.first();
|
const header = parts.first();
|
||||||
var header_lines = std.mem.split(u8, header, "\n");
|
var header_lines = std.mem.split(u8, header, "\n");
|
||||||
var header_buffer = std.ArrayList(Header).init(allocator);
|
var header_buffer = std.ArrayList(Header).init(allocator);
|
||||||
|
var cookie_buffer = std.ArrayList(Request.Cookie).init(allocator);
|
||||||
|
|
||||||
var header_items = std.mem.split(u8, header_lines.first(), " ");
|
var header_items = std.mem.split(u8, header_lines.first(), " ");
|
||||||
req.method = Method.parse(header_items.first());
|
req.method = Method.parse(header_items.first());
|
||||||
|
@ -103,10 +105,19 @@ fn buildRequest(client_ip: []const u8, bytes: []const u8, allocator: std.mem.All
|
||||||
while (header_lines.next()) |line| {
|
while (header_lines.next()) |line| {
|
||||||
var headers = std.mem.split(u8, line, ": ");
|
var headers = std.mem.split(u8, line, ": ");
|
||||||
const item1 = headers.first();
|
const item1 = headers.first();
|
||||||
const item2 = if (headers.next()) |value| value else unreachable;
|
// Check if header is a cookie and parse it
|
||||||
|
if (eql(u8, item1, "Cookie") or eql(u8, item1, "cookie")) {
|
||||||
|
const item2 = if (headers.next()) |value| value else "";
|
||||||
|
const cookies = try Request.Cookie.parse(item2, allocator);
|
||||||
|
defer allocator.free(cookies);
|
||||||
|
try cookie_buffer.appendSlice(cookies);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const item2 = if (headers.next()) |value| value else "";
|
||||||
const header_pair = Header{ .key = item1, .value = item2 };
|
const header_pair = Header{ .key = item1, .value = item2 };
|
||||||
try header_buffer.append(header_pair);
|
try header_buffer.append(header_pair);
|
||||||
}
|
}
|
||||||
|
req.cookies = if (olderVersion) cookie_buffer.toOwnedSlice() else try cookie_buffer.toOwnedSlice();
|
||||||
req.headers = if (olderVersion) header_buffer.toOwnedSlice() else try header_buffer.toOwnedSlice();
|
req.headers = if (olderVersion) header_buffer.toOwnedSlice() else try header_buffer.toOwnedSlice();
|
||||||
req.body = if (parts.next()) |value| value else "";
|
req.body = if (parts.next()) |value| value else "";
|
||||||
return req;
|
return req;
|
||||||
|
@ -172,7 +183,6 @@ test "Run server" {
|
||||||
// Function for test "Run Server"
|
// Function for test "Run Server"
|
||||||
fn handlefn(_: *types.Request) types.Response {
|
fn handlefn(_: *types.Request) types.Response {
|
||||||
// create Response and add cookie to test cookie setting
|
// 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 = &[_]Response.Cookie{.{ .name = "Test-Cookie", .value = "Test", .domain = "localhost:8080" }} };
|
||||||
var res = types.Response{ .body = "<h1>Run Server Test OK!</h1>", .cookies = &[_]rc.Cookie{.{ .name = "Test-Cookie", .value = "Test", .domain = "localhost:8080" }} };
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ const allocator = std.heap.page_allocator;
|
||||||
const eql = std.mem.eql;
|
const eql = std.mem.eql;
|
||||||
const stat = @import("./status.zig");
|
const stat = @import("./status.zig");
|
||||||
const rescookie = @import("./res_cookie.zig");
|
const rescookie = @import("./res_cookie.zig");
|
||||||
|
const reqcookie = @import("./req_cookie.zig");
|
||||||
|
|
||||||
/// Route is a touple that consists of the path and the function that shall handle it.
|
/// Route is a touple that consists of the path and the function that shall handle it.
|
||||||
/// e.g. `const rt = Route{"/home", home};`
|
/// e.g. `const rt = Route{"/home", home};`
|
||||||
|
@ -90,10 +91,14 @@ pub const Request = struct {
|
||||||
ip: []const u8,
|
ip: []const u8,
|
||||||
/// Represents the request headers sent by the client
|
/// Represents the request headers sent by the client
|
||||||
headers: []const Header,
|
headers: []const Header,
|
||||||
|
/// Request Cookies
|
||||||
|
cookies: []const Cookie,
|
||||||
/// The Request URI
|
/// The Request URI
|
||||||
uri: []const u8,
|
uri: []const u8,
|
||||||
/// Represents the request body sent by the client
|
/// Represents the request body sent by the client
|
||||||
body: []const u8,
|
body: []const u8,
|
||||||
|
|
||||||
|
pub const Cookie = reqcookie.Cookie;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a standard http-Response sent by the webapp (server).
|
/// Represents a standard http-Response sent by the webapp (server).
|
||||||
|
|
Loading…
Reference in a new issue