Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do we have a cookie parser? #83

Closed
gyongph opened this issue Dec 13, 2024 · 5 comments
Closed

Do we have a cookie parser? #83

gyongph opened this issue Dec 13, 2024 · 5 comments

Comments

@gyongph
Copy link

gyongph commented Dec 13, 2024

No description provided.

@karlseguin
Copy link
Owner

No. If you come up with a nice struct + function to parse (and generate), you can send a PR and we can add them..either directly on Req/Res, or as utility.

@gyongph
Copy link
Author

gyongph commented Dec 14, 2024

What do you think?

const std = @import("std");

pub fn getCookie(string: []const u8, key: []const u8) ?[]const u8 {
    const key_index = std.mem.lastIndexOf(u8, string, key);
    if (key_index == null) return null;
    const val_start_index = key_index.? + key.len + 1; // +1 to include the "=" char
    const val_end_index: ?usize = blk: {
        for (string[val_start_index..], 0..) |char, pos| {
            if (char == ';') break :blk pos + val_start_index - 1 // dont include the ';' char;
            else if (pos + val_start_index == string.len - 1) break :blk pos + val_start_index;
        }
        break :blk null;
    };
    if (val_end_index == null) return null;
    return string[val_start_index .. val_end_index.? + 1];
}

test getCookie {
    const access_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
    const refresh_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MTAyMn0.CVOeLalihoWYCzThD64fQTHxfechEMt16kmCghaxSI4";
    const alloc = std.testing.allocator;
    const cookie_string = try std.fmt.allocPrint(alloc, "access_token={s};refresh_token={s}", .{ access_token, refresh_token });
    defer alloc.free(cookie_string);
    const got_access_token = getCookie(cookie_string, "access_token");
    const got_refresh_token = getCookie(cookie_string, "refresh_token");
    try std.testing.expect(got_access_token != null);
    try std.testing.expect(got_refresh_token != null);
    try std.testing.expectEqualStrings(access_token, got_access_token.?);
    try std.testing.expectEqualStrings(refresh_token, got_refresh_token.?);
}

karlseguin added a commit that referenced this issue Dec 15, 2024
@karlseguin
Copy link
Owner

In master, there's now a cookie method:

const cookies = req.cookies();
if (cookies.get("access_token")) |token| {
 ...
}

Your implementation was pretty close, but if you change the refresh token value to: "access_token", it crashes.

const access_token = "ey..."
const refresh_token = "access_token"
...

I had to use a mem.splitScalar on ; to correctly split the cookies

@gyongph
Copy link
Author

gyongph commented Dec 15, 2024

I provided the wrong example for the cookie. It's actually separated by a semicolon and a space, not just a semicolon.

karlseguin added a commit that referenced this issue Dec 16, 2024
Allows having leading whitespace in cookie name.

#83
@karlseguin
Copy link
Owner

Latest version left trim's space from the raw cookie record.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants