Skip to content

Commit

Permalink
Merge pull request #3587 from nelusnegur/headers/access-control-allow…
Browse files Browse the repository at this point in the history
…-headers-model

Model Access-Control-Allow-Headers header
  • Loading branch information
rossabaker committed Aug 6, 2020
2 parents ba182c3 + b5e1685 commit bed89dd
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,28 @@
package org.http4s
package headers

object `Access-Control-Allow-Headers` extends HeaderKey.Default
import org.typelevel.ci.CIString
import org.http4s.parser.HttpHeaderParser
import org.http4s.util._
import cats.data.NonEmptyList

object `Access-Control-Allow-Headers`
extends HeaderKey.Internal[`Access-Control-Allow-Headers`]
with HeaderKey.Recurring {

override def parse(s: String): ParseResult[`Access-Control-Allow-Headers`] =
HttpHeaderParser.ACCESS_CONTROL_ALLOW_HEADERS(s)

private val ciStringRenderer: Renderer[CIString] = new Renderer[CIString] {
override def render(writer: Writer, ciString: CIString): writer.type =
writer << ciString
}
}

final case class `Access-Control-Allow-Headers`(values: NonEmptyList[CIString])
extends Header.RecurringRenderer {
override type Value = CIString

override implicit def renderer: Renderer[Value] = `Access-Control-Allow-Headers`.ciStringRenderer
override def key: `Access-Control-Allow-Headers`.type = `Access-Control-Allow-Headers`
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ object HttpHeaderParser
addParser_(CIString("ACCEPT-LANGUAGE"), `ACCEPT_LANGUAGE`)
addParser_(CIString("ACCEPT-RANGES"), `ACCEPT_RANGES`)
addParser_(CIString("ACCESS-CONTROL-ALLOW-CREDENTIALS"), `ACCESS_CONTROL_ALLOW_CREDENTIALS`)
addParser_(CIString("ACCESS-CONTROL-ALLOW-HEADERS"), `ACCESS_CONTROL_ALLOW_HEADERS`)
addParser_(CIString("AGE"), `AGE`)
addParser_(CIString("ALLOW"), `ALLOW`)
addParser_(CIString("AUTHORIZATION"), `AUTHORIZATION`)
Expand Down
12 changes: 12 additions & 0 deletions core/src/main/scala/org/http4s/parser/SimpleHeaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ private[parser] trait SimpleHeaders {
}
}.parse

def ACCESS_CONTROL_ALLOW_HEADERS(value: String): ParseResult[`Access-Control-Allow-Headers`] =
new Http4sHeaderParser[`Access-Control-Allow-Headers`](value) {
def entry =
rule {
oneOrMore(Token).separatedBy(ListSep) ~ EOL ~> { (tokens: Seq[String]) =>
`Access-Control-Allow-Headers`(
NonEmptyList.of(CIString(tokens.head), tokens.tail.map(CIString(_)): _*)
)
}
}
}.parse

def ALLOW(value: String): ParseResult[Allow] =
new Http4sHeaderParser[Allow](value) {
def entry =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,14 @@ private[http4s] trait ArbitraryInstances {
} yield headers.Accept(NonEmptyList.of(values.head, values.tail: _*))
}

implicit val http4sTestingArbitraryForAccessControlAllowHeaders
: Arbitrary[headers.`Access-Control-Allow-Headers`] =
Arbitrary {
for {
values <- nonEmptyListOf(genToken.map(CIString(_)))
} yield headers.`Access-Control-Allow-Headers`(NonEmptyList.of(values.head, values.tail: _*))
}

implicit val http4sTestingArbitraryForRetryAfterHeader: Arbitrary[headers.`Retry-After`] =
Arbitrary {
for {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright 2013-2020 http4s.org
*
* SPDX-License-Identifier: Apache-2.0
*/

package org.http4s
package headers

final class AccessControlAllowHeadersSpec extends HeaderLaws {
checkAll("Access-Control-Allow-Headers", headerLaws(`Access-Control-Allow-Headers`))
}
15 changes: 15 additions & 0 deletions tests/src/test/scala/org/http4s/parser/SimpleHeadersSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ class SimpleHeadersSpec extends Http4sSpec {
HttpHeaderParser.parseHeader(bad) must beLeft
}

"parse Access-Control-Allow-Headers" in {
val header = `Access-Control-Allow-Headers`(
NonEmptyList.of(
CIString("Accept"),
CIString("Expires"),
CIString("X-Custom-Header"),
CIString("*")
)
)
HttpHeaderParser.parseHeader(header.toRaw) must beRight(header)

val invalidHeader = Header(header.name.toString, "(non-token-name), non[&token]name")
HttpHeaderParser.parseHeader(invalidHeader) must beLeft
}

"parse Connection" in {
val header = Connection(CIString("closed"))
HttpHeaderParser.parseHeader(header.toRaw) must beRight(header)
Expand Down

0 comments on commit bed89dd

Please sign in to comment.