+htc #18898 modeledCustomHeader to ease matching on headers
This commit is contained in:
parent
644555a93f
commit
6f5d449bd0
6 changed files with 212 additions and 20 deletions
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.scaladsl.server
|
||||
|
||||
import akka.http.scaladsl.model.{ HttpHeader, StatusCodes }
|
||||
import akka.http.scaladsl.model.headers._
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.util.{ Success, Failure, Try }
|
||||
|
||||
object ModeledCustomHeaderSpec {
|
||||
|
||||
//#modeled-api-key-custom-header
|
||||
object ApiTokenHeader extends ModeledCustomHeaderCompanion[ApiTokenHeader] {
|
||||
override val name = "apiKey"
|
||||
override def parse(value: String) = Try(new ApiTokenHeader(value))
|
||||
}
|
||||
final class ApiTokenHeader(token: String) extends ModeledCustomHeader[ApiTokenHeader] {
|
||||
override val companion = ApiTokenHeader
|
||||
override def value: String = token
|
||||
}
|
||||
//#modeled-api-key-custom-header
|
||||
|
||||
object DifferentHeader extends ModeledCustomHeaderCompanion[DifferentHeader] {
|
||||
override val name = "different"
|
||||
override def parse(value: String) =
|
||||
if (value contains " ") Failure(new Exception("Contains illegal whitespace!"))
|
||||
else Success(new DifferentHeader(value))
|
||||
}
|
||||
final class DifferentHeader(token: String) extends ModeledCustomHeader[DifferentHeader] {
|
||||
override val companion = DifferentHeader
|
||||
override def value = token
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ModeledCustomHeaderSpec extends RoutingSpec {
|
||||
import ModeledCustomHeaderSpec._
|
||||
|
||||
"CustomHeader" should {
|
||||
|
||||
"be able to be extracted using expected syntax" in {
|
||||
//#matching-examples
|
||||
val ApiTokenHeader(t1) = ApiTokenHeader("token")
|
||||
t1 should ===("token")
|
||||
|
||||
val RawHeader(k2, v2) = ApiTokenHeader("token")
|
||||
k2 should ===("apiKey")
|
||||
v2 should ===("token")
|
||||
|
||||
// will match, header keys are case insensitive
|
||||
val ApiTokenHeader(v3) = RawHeader("APIKEY", "token")
|
||||
v3 should ===("token")
|
||||
|
||||
intercept[MatchError] {
|
||||
// won't match, different header name
|
||||
val ApiTokenHeader(v4) = DifferentHeader("token")
|
||||
}
|
||||
|
||||
intercept[MatchError] {
|
||||
// won't match, different header name
|
||||
val RawHeader("something", v5) = DifferentHeader("token")
|
||||
}
|
||||
|
||||
intercept[MatchError] {
|
||||
// won't match, different header name
|
||||
val ApiTokenHeader(v6) = RawHeader("different", "token")
|
||||
}
|
||||
//#matching-examples
|
||||
}
|
||||
|
||||
"be able to match from RawHeader" in {
|
||||
|
||||
//#matching-in-routes
|
||||
def extractFromCustomHeader = headerValuePF {
|
||||
case t @ ApiTokenHeader(token) ⇒ s"extracted> $t"
|
||||
case raw: RawHeader ⇒ s"raw> $raw"
|
||||
}
|
||||
|
||||
val routes = extractFromCustomHeader { s ⇒
|
||||
complete(s)
|
||||
}
|
||||
|
||||
Get().withHeaders(RawHeader("apiKey", "TheKey")) ~> routes ~> check {
|
||||
status should ===(StatusCodes.OK)
|
||||
responseAs[String] should ===("extracted> apiKey: TheKey")
|
||||
}
|
||||
|
||||
Get().withHeaders(RawHeader("somethingElse", "TheKey")) ~> routes ~> check {
|
||||
status should ===(StatusCodes.OK)
|
||||
responseAs[String] should ===("raw> somethingElse: TheKey")
|
||||
}
|
||||
|
||||
Get().withHeaders(ApiTokenHeader("TheKey")) ~> routes ~> check {
|
||||
status should ===(StatusCodes.OK)
|
||||
responseAs[String] should ===("extracted> apiKey: TheKey")
|
||||
}
|
||||
//#matching-in-routes
|
||||
}
|
||||
|
||||
"fail with useful message when unable to parse" in {
|
||||
val ex = intercept[Exception] {
|
||||
DifferentHeader("Hello world") // illegal " "
|
||||
}
|
||||
|
||||
ex.getMessage should ===("Unable to construct custom header by parsing: 'Hello world'")
|
||||
ex.getCause.getMessage should include("whitespace")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -92,9 +92,7 @@ class MultipartUnmarshallersSpec extends FreeSpec with Matchers with BeforeAndAf
|
|||
|filecontent
|
||||
|--12345--""".stripMarginWithNewline("\r\n"))).to[Multipart.General] should haveParts(
|
||||
Multipart.General.BodyPart.Strict(HttpEntity(ContentTypes.`text/plain(UTF-8)`, "first part, with a trailing newline\r\n")),
|
||||
Multipart.General.BodyPart.Strict(
|
||||
HttpEntity(`application/octet-stream`, "filecontent"),
|
||||
List(RawHeader("Content-Transfer-Encoding", "binary"))))
|
||||
Multipart.General.BodyPart.Strict(HttpEntity(`application/octet-stream`, "filecontent"), List(RawHeader("Content-Transfer-Encoding", "binary"))))
|
||||
}
|
||||
"illegal headers" in (
|
||||
Unmarshal(HttpEntity(`multipart/form-data` withBoundary "XYZABC",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue