Skip to content

Commit

Permalink
added cookie helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
TomTriple committed Sep 10, 2023
1 parent 8780eb9 commit 64e128c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
16 changes: 15 additions & 1 deletion docs/dsl/cookies.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,21 @@ It updates the response header `Set-Cookie` as ```Set-Cookie: <cookie-name>=<coo

## Getting Cookie from Request

In HTTP requests, cookies are stored in the `cookie` header. `cookiesDecoded` can be used to get all the cookies in the request:
From HTTP requests, a single cookie can be retrieved with `cookie`.

```scala mdoc
private val app4 =
Routes(
Method.GET / "cookie" -> handler { (req: Request) =>
val cookieContent = req.cookie("sessionId").map(_.content)
Response.text(s"cookie content: $cookieContent")
}
)
```

## Getting Cookie from Header

In HTTP requests, cookies are stored in the `cookie` header.

```scala mdoc
private val app3 =
Expand Down
35 changes: 34 additions & 1 deletion zio-http/src/main/scala/zio/http/Request.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package zio.http
import java.net.InetAddress

import zio.stacktracer.TracingImplicits.disableAutoTrace
import zio.{Trace, ZIO}
import zio.{NonEmptyChunk, Trace, ZIO}

import zio.http.internal.HeaderOps

Expand Down Expand Up @@ -106,6 +106,39 @@ final case class Request(
*/
def unnest(prefix: Path): Request =
copy(url = self.url.copy(path = self.url.path.unnest(prefix)))

/**
* Returns the cookie with the given name if it exists.
*/
def cookie(name: String): Option[Cookie] =
cookies.flatMap(_.filter(_.name == name).headOption)

/**
* Uses the cookie with the given name if it exists and runs `f` afterwards.
*/
def cookieWith[R, A](name: String)(f: Cookie => ZIO[R, Throwable, A])(implicit trace: Trace): ZIO[R, Throwable, A] =
cookieWithOrFailImpl(name)(identity)(f)

/**
* Uses the cookie with the given name if it exists and runs `f` afterwards.
*
* Also, you can replace a `NoSuchElementException` from an absent cookie with
* `E`.
*/
def cookieWithOrFail[R, E, A](name: String)(e: E)(f: Cookie => ZIO[R, E, A])(implicit trace: Trace): ZIO[R, E, A] =
cookieWithOrFailImpl(name)(_ => e)(f)

private def cookieWithOrFailImpl[R, E, A](name: String)(e: Throwable => E)(f: Cookie => ZIO[R, E, A])(implicit
trace: Trace,
): ZIO[R, E, A] =
ZIO.getOrFailWith(e(new java.util.NoSuchElementException(s"cookie doesn't exist: $name")))(cookie(name)).flatMap(f)

/**
* Returns all cookies from the request.
*/
def cookies: Option[NonEmptyChunk[Cookie]] =
header(Header.Cookie).map(_.value)

}

object Request {
Expand Down

0 comments on commit 64e128c

Please sign in to comment.