Repository: ring-clojure/ring (clojure)

Issue:
Add support for Partitioned cookies (CHIPS)
Hey friends!

I'm looking to use [CHIPS](https://developer.mozilla.org/en-US/docs/Web/Privacy/Partitioned_cookies) in `:cookies`, but because the `set-cookie-attrs` is a private var, I can't add support for it myself:

https://github.com/ring-clojure/ring/blob/76e5d29128661225a08a9f8dfa7b07c83b6ed4da/ring-core/src/ring/middleware/cookies.clj#L21-L24

At the moment I'm using `alter-var-root` and `alter-meta` to gain access and insert it (see below), but that feels less good than maybe making it an atom and allowing it to be edited by users, or some other system that I trust y'all to come up with.

```clojure
(alter-meta! #'ring.middleware.cookies/set-cookie-attrs assoc :private false)
(alter-var-root #'ring.middleware.cookies/set-cookie-attrs assoc :partitioned "Partitioned")
```

Pull request description:
Adds simple support for [Partitioned cookies](https://developer.mozilla.org/en-US/docs/Web/Privacy/Partitioned_cookies). Does no validation (requiring `:secure`). I briefly considered it, but that felt like a step too far.

Closes #492

Patch:
diff --git a/ring-core/src/ring/middleware/cookies.clj b/ring-core/src/ring/middleware/cookies.clj
index 860f5053..c082cb9a 100644
--- a/ring-core/src/ring/middleware/cookies.clj
+++ b/ring-core/src/ring/middleware/cookies.clj
@@ -21,7 +21,7 @@
 (def ^:private set-cookie-attrs
   {:domain "Domain", :max-age "Max-Age", :path "Path"
    :secure "Secure", :expires "Expires", :http-only "HttpOnly"
-   :same-site "SameSite"})
+   :same-site "SameSite", :partitioned "Partitioned"})
 
 (def ^:private same-site-values
   {:strict "Strict", :lax "Lax", :none "None"})


Test patch:
diff --git a/ring-core/test/ring/middleware/test/cookies.clj b/ring-core/test/ring/middleware/test/cookies.clj
index f19a3afb..4463f28e 100644
--- a/ring-core/test/ring/middleware/test/cookies.clj
+++ b/ring-core/test/ring/middleware/test/cookies.clj
@@ -103,6 +103,13 @@
     (is (= {"Set-Cookie" (list "a=b" "c=d")}
            (:headers resp)))))
 
+(deftest wrap-cookies-set-partitioned
+  (let [response {:cookies {"a" {:value "foo" :partitioned true}}}
+        handler  (constantly response)
+        resp     ((wrap-cookies handler) {})]
+    (is (= {"Set-Cookie" #{"a=foo" "Partitioned"}}
+           (split-set-cookie (:headers resp))))))
+
 (deftest wrap-cookies-invalid-attrs
   (let [response {:cookies {"a" {:value "foo" :invalid true}}}
         handler  (wrap-cookies (constantly response))]