Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add header echoing server middleware
- Loading branch information
1 parent
867cb8c
commit ec94e18
Showing
2 changed files
with
86 additions
and
0 deletions.
There are no files selected for viewing
24 changes: 24 additions & 0 deletions
24
server/src/main/scala/org/http4s/server/middleware/HeaderEcho.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.http4s.server.middleware | ||
|
||
import cats.Functor | ||
import cats.data.Kleisli | ||
import org.http4s._ | ||
|
||
object HeaderEcho { | ||
|
||
private def isOneOf(headerKeys: Seq[HeaderKey])(header: Header): Boolean = | ||
headerKeys.exists(_.matchHeader(header).isDefined) | ||
|
||
/** | ||
* Simple server middleware that adds selected headers present on the request to the response. | ||
* | ||
* @param headerKeys the keys corresponding to the headers to echo on the response | ||
* @param http [[HttpRoutes]] to transform | ||
*/ | ||
def apply[F[_]: Functor](headerKeys: HeaderKey*)(http: HttpRoutes[F]): HttpRoutes[F] = | ||
Kleisli { req: Request[F] => | ||
val headersToEcho = req.headers.filter(isOneOf(headerKeys)) | ||
|
||
http(req).map(_.putHeaders(headersToEcho.toList: _*)) | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
server/src/test/scala/org/http4s/server/middleware/HeaderEchoSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package org.http4s.server.middleware | ||
|
||
import cats.effect.IO | ||
import org.http4s._ | ||
import org.http4s.dsl.io._ | ||
|
||
class HeaderEchoSpec extends Http4sSpec { | ||
|
||
object someHeaderKey extends HeaderKey.Default | ||
object anotherHeaderKey extends HeaderKey.Default | ||
|
||
val testService = HttpRoutes.of[IO] { | ||
case GET -> Root / "request" => Ok("request response") | ||
} | ||
|
||
"HeaderEcho" should { | ||
"echo a single header in addition to the defaults" in { | ||
val requestMatchingSingleHeaderKey = | ||
Request[IO]( | ||
uri = uri("/request"), | ||
headers = Headers(Header("someheaderkey", "someheadervalue"))) | ||
val testee = HeaderEcho(someHeaderKey)(testService) | ||
val responseHeaders = | ||
testee.orNotFound(requestMatchingSingleHeaderKey).unsafeRunSync().headers | ||
|
||
responseHeaders.exists(_.value == "someheadervalue") must_== true | ||
(responseHeaders must have).size(3) | ||
} | ||
|
||
"echo multiple headers" in { | ||
val requestMatchingMultipleHeaderKeys = | ||
Request[IO]( | ||
uri = uri("/request"), | ||
headers = Headers( | ||
Header("someheaderkey", "someheadervalue"), | ||
Header("anotherheaderkey", "anotherheadervalue"))) | ||
val testee = HeaderEcho(someHeaderKey, anotherHeaderKey)(testService) | ||
|
||
val responseHeaders = | ||
testee.orNotFound(requestMatchingMultipleHeaderKeys).unsafeRunSync().headers | ||
|
||
responseHeaders.exists(_.value == "someheadervalue") must_== true | ||
responseHeaders.exists(_.value == "anotherheadervalue") must_== true | ||
(responseHeaders must have).size(4) | ||
} | ||
|
||
"echo only the default headers where none match the key" in { | ||
val requestMatchingNotPresentHeaderKey = | ||
Request[IO]( | ||
uri = uri("/request"), | ||
headers = Headers(Header("someunmatchedheader", "someunmatchedvalue"))) | ||
|
||
val testee = HeaderEcho(someHeaderKey)(testService) | ||
val responseHeaders = | ||
testee.orNotFound(requestMatchingNotPresentHeaderKey).unsafeRunSync().headers | ||
|
||
responseHeaders.exists(_.value == "someunmatchedvalue") must_== false | ||
(responseHeaders must have).size(2) | ||
} | ||
} | ||
|
||
} |