diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d0c757..4920787 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## v.3.7.0 - 2024-09-10 +- The `gleam/http/request` module gains the `remove_cookie` function. + ## v3.6.2 - 2024-03-12 - The `gleam/http/service` module has been deprecated in favour of other diff --git a/src/gleam/http/request.gleam b/src/gleam/http/request.gleam index b8d00ae..a992433 100644 --- a/src/gleam/http/request.gleam +++ b/src/gleam/http/request.gleam @@ -284,3 +284,28 @@ pub fn get_cookies(req) -> List(#(String, String)) { }) |> list.flatten() } + +/// Remove a cookie from a request +/// +/// Remove a cookie from the request. If no cookie is found return the request unchanged. +/// This will not remove the cookie from the client. +pub fn remove_cookie(req: Request(body), name: String) { + case list.key_pop(req.headers, "cookie") { + Ok(#(cookies_string, headers)) -> { + let new_cookies_string = + string.split(cookies_string, ";") + |> list.filter(fn(str) { + string.trim(str) + |> string.split_once("=") + // Keep cookie if name does not match + |> result.map(fn(tup) { tup.0 != name }) + // Don't do anything with malformed cookies + |> result.unwrap(True) + }) + |> string.join(";") + + Request(..req, headers: [#("cookie", new_cookies_string), ..headers]) + } + Error(_) -> req + } +} diff --git a/test/gleam/http/request_test.gleam b/test/gleam/http/request_test.gleam index d598c8f..69b81dd 100644 --- a/test/gleam/http/request_test.gleam +++ b/test/gleam/http/request_test.gleam @@ -450,3 +450,40 @@ pub fn set_req_cookies_test() { |> request.get_header("cookie") |> should.equal(Ok("k1=v1; k2=v2")) } + +pub fn remove_cookie_from_request_test() { + let req = + request.new() + |> request.set_cookie("FIRST_COOKIE", "first") + |> request.set_cookie("SECOND_COOKIE", "second") + |> request.set_cookie("THIRD_COOKIE", "third") + + req + |> request.get_header("cookie") + |> should.be_ok + |> should.equal( + "FIRST_COOKIE=first; SECOND_COOKIE=second; THIRD_COOKIE=third", + ) + + let modified_req = + req + |> request.remove_cookie("SECOND_COOKIE") + + modified_req + |> request.get_header("cookie") + |> should.be_ok + |> should.equal("FIRST_COOKIE=first; THIRD_COOKIE=third") +} + +pub fn only_remove_matching_cookies_test() { + request.new() + |> request.set_cookie("FIRST_COOKIE", "first") + |> request.set_cookie("SECOND_COOKIE", "second") + |> request.set_cookie("THIRD_COOKIE", "third") + |> request.remove_cookie("SECOND") + |> request.get_header("cookie") + |> should.be_ok + |> should.equal( + "FIRST_COOKIE=first; SECOND_COOKIE=second; THIRD_COOKIE=third", + ) +}