+htp #15919 import CookieDirectives

This commit is contained in:
Johannes Rudolph 2014-10-17 10:42:54 +02:00
parent 37da572d2d
commit 8116d2b9bb
3 changed files with 155 additions and 1 deletions

View file

@ -0,0 +1,96 @@
/*
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.http.server
package directives
import akka.http.model._
import StatusCodes.OK
import headers._
import akka.http.util.DateTime
class CookieDirectivesSpec extends RoutingSpec {
val deletedTimeStamp = DateTime.fromIsoDateTimeString("1800-01-01T00:00:00")
"The 'cookie' directive" should {
"extract the respectively named cookie" in {
Get() ~> addHeader(Cookie(HttpCookie("fancy", "pants"))) ~> {
cookie("fancy") { echoComplete }
} ~> check { responseAs[String] shouldEqual "fancy=pants" }
}
"reject the request if the cookie is not present" in {
Get() ~> {
cookie("fancy") { echoComplete }
} ~> check { rejection shouldEqual MissingCookieRejection("fancy") }
}
"properly pass through inner rejections" in {
Get() ~> addHeader(Cookie(HttpCookie("fancy", "pants"))) ~> {
cookie("fancy") { c reject(ValidationRejection("Dont like " + c.content)) }
} ~> check { rejection shouldEqual ValidationRejection("Dont like pants") }
}
}
"The 'deleteCookie' directive" should {
"add a respective Set-Cookie headers to successful responses" in {
Get() ~> {
deleteCookie("myCookie", "test.com") { completeOk }
} ~> check {
status shouldEqual OK
header[`Set-Cookie`] shouldEqual Some(`Set-Cookie`(HttpCookie("myCookie", "deleted", expires = deletedTimeStamp,
domain = Some("test.com"))))
}
}
"support deleting multiple cookies at a time" in {
Get() ~> {
deleteCookie(HttpCookie("myCookie", "test.com"), HttpCookie("myCookie2", "foobar.com")) { completeOk }
} ~> check {
status shouldEqual OK
headers.collect { case `Set-Cookie`(x) x } shouldEqual List(
HttpCookie("myCookie", "deleted", expires = deletedTimeStamp),
HttpCookie("myCookie2", "deleted", expires = deletedTimeStamp))
}
}
}
"The 'optionalCookie' directive" should {
"produce a `Some(cookie)` extraction if the cookie is present" in {
Get() ~> Cookie(HttpCookie("abc", "123")) ~> {
optionalCookie("abc") { echoComplete }
} ~> check { responseAs[String] shouldEqual "Some(abc=123)" }
}
"produce a `None` extraction if the cookie is not present" in {
Get() ~> optionalCookie("abc") { echoComplete } ~> check { responseAs[String] shouldEqual "None" }
}
"let rejections from its inner route pass through" in {
Get() ~> {
optionalCookie("test-cookie") { _
validate(false, "ouch") { completeOk }
}
} ~> check { rejection shouldEqual ValidationRejection("ouch") }
}
}
"The 'setCookie' directive" should {
"add a respective Set-Cookie headers to successful responses" in {
Get() ~> {
setCookie(HttpCookie("myCookie", "test.com")) { completeOk }
} ~> check {
status shouldEqual OK
header[`Set-Cookie`] shouldEqual Some(`Set-Cookie`(HttpCookie("myCookie", "test.com")))
}
}
"support setting multiple cookies at a time" in {
Get() ~> {
setCookie(HttpCookie("myCookie", "test.com"), HttpCookie("myCookie2", "foobar.com")) { completeOk }
} ~> check {
status shouldEqual OK
headers.collect { case `Set-Cookie`(x) x } shouldEqual List(
HttpCookie("myCookie", "test.com"), HttpCookie("myCookie2", "foobar.com"))
}
}
}
}

View file

@ -12,7 +12,7 @@ trait Directives extends RouteConcatenation
with BasicDirectives
with CacheConditionDirectives
//with ChunkingDirectives
//with CookieDirectives
with CookieDirectives
//with DebuggingDirectives
with CodingDirectives
with ExecutionDirectives

View file

@ -0,0 +1,58 @@
/*
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.http.server
package directives
import akka.http.model._
import headers._
import akka.http.util._
trait CookieDirectives {
import HeaderDirectives._
import RespondWithDirectives._
import RouteDirectives._
/**
* Extracts an HttpCookie with the given name. If the cookie is not present the
* request is rejected with a respective [[spray.routing.MissingCookieRejection]].
*/
def cookie(name: String): Directive1[HttpCookie] =
headerValue(findCookie(name)) | reject(MissingCookieRejection(name))
/**
* Extracts an HttpCookie with the given name.
* If the cookie is not present a value of `None` is extracted.
*/
def optionalCookie(name: String): Directive1[Option[HttpCookie]] =
optionalHeaderValue(findCookie(name))
private def findCookie(name: String): HttpHeader Option[HttpCookie] = {
case Cookie(cookies) cookies.find(_.name == name)
case _ None
}
/**
* Adds a Set-Cookie header with the given cookies to all responses of its inner route.
*/
def setCookie(first: HttpCookie, more: HttpCookie*): Directive0 =
respondWithHeaders((first :: more.toList).map(`Set-Cookie`(_)))
/**
* Adds a Set-Cookie header expiring the given cookies to all responses of its inner route.
*/
def deleteCookie(first: HttpCookie, more: HttpCookie*): Directive0 =
respondWithHeaders((first :: more.toList).map { c
`Set-Cookie`(c.copy(content = "deleted", expires = Some(DateTime.MinValue)))
})
/**
* Adds a Set-Cookie header expiring the given cookie to all responses of its inner route.
*/
def deleteCookie(name: String, domain: String = "", path: String = ""): Directive0 =
deleteCookie(HttpCookie(name, "", domain = domain.toOption, path = path.toOption))
}
object CookieDirectives extends CookieDirectives