From a74507cff4d5cae57157f16d14adef4c465fc3bb Mon Sep 17 00:00:00 2001 From: Nathan Hamblen Date: Tue, 27 Mar 2012 23:19:09 -0400 Subject: [PATCH] secure port handling and tests --- filter/src/test/scala/SslServerSpec.scala | 50 +++++++++++++++++------ library/src/main/scala/kit/secure.scala | 11 ++++- library/src/test/scala/SecureSpec.scala | 33 --------------- 3 files changed, 47 insertions(+), 47 deletions(-) delete mode 100644 library/src/test/scala/SecureSpec.scala diff --git a/filter/src/test/scala/SslServerSpec.scala b/filter/src/test/scala/SslServerSpec.scala index f1fcfda82..c55e477e9 100644 --- a/filter/src/test/scala/SslServerSpec.scala +++ b/filter/src/test/scala/SslServerSpec.scala @@ -3,11 +3,13 @@ package unfiltered.server import unfiltered.spec import org.specs._ -object SslServerSpec extends Specification with spec.jetty.Served with spec.SecureClient { +object SslServerSpec extends Specification with unfiltered.spec.Hosted with spec.SecureClient { + shareVariables() + import unfiltered.response._ import unfiltered.request._ import unfiltered.request.{Path => UFPath} - import unfiltered.jetty.Https + import unfiltered.jetty.{Https,Http=>UFHttp} import unfiltered.util.Port import org.apache.http.client.ClientProtocolException @@ -18,24 +20,48 @@ object SslServerSpec extends Specification with spec.jetty.Served with spec.Secu val keyStorePath = getClass.getResource("/keystore").getPath val keyStorePasswd = "unfiltered" val securePort = Port.any + val httpPort = Port.any - override val host = :/("localhost", securePort) + override val host = :/("localhost", httpPort) - override lazy val server = setup(new Https(securePort, "0.0.0.0") { + lazy val server = new Https(securePort, "0.0.0.0") { + filter(filt) override lazy val keyStore = keyStorePath override lazy val keyStorePassword = keyStorePasswd - }) + } - def setup = { _.filter(unfiltered.filter.Planify { - case GET(UFPath("/")) => ResponseString("secret") ~> Ok - })} + lazy val httpServer = new UFHttp(httpPort, "0.0.0.0").filter(filt) + + doBeforeSpec { server.start(); httpServer.start() } + doAfterSpec { + server.stop() + server.destroy() + httpServer.stop() + httpServer.destroy() + } + + val filt = unfiltered.filter.Planify(secured.onPass(whatever)) + def secured = + unfiltered.kit.Secure.redir[Any,Any]( { + case req @ UFPath(Seg("unprotected" :: Nil)) => + Pass + case req @ UFPath(Seg("protected" :: Nil)) => + ResponseString(req.isSecure.toString) ~> Ok + }, securePort) + def whatever = unfiltered.Cycle.Intent[Any,Any] { + case req => + ResponseString(req.isSecure.toString) ~> Ok + } "A Secure Server" should { - "respond to secure requests" in { - https(host.secure as_str) must_== "secret" + "redirect and serve to secure requests" in { + https(host / "protected" as_str) must_== "true" + } + "explicit pass to insecure" in { + https(host / "unprotected" as_str) must_== "false" } - "refuse connection to unsecure requests" in { - https(host as_str) must throwA[ClientProtocolException] + "nonmatching pass to insecure" in { + https(host as_str) must_== "false" } } } diff --git a/library/src/main/scala/kit/secure.scala b/library/src/main/scala/kit/secure.scala index b30efc05d..36910b8ad 100644 --- a/library/src/main/scala/kit/secure.scala +++ b/library/src/main/scala/kit/secure.scala @@ -4,13 +4,20 @@ import unfiltered.request._ import unfiltered.response._ object Secure { - def redir[A,B](intent: unfiltered.Cycle.Intent[A,B]) = { + def redir[A,B](intent: unfiltered.Cycle.Intent[A,B], + port: Int = -1) = { intent.fold( { _ => Pass }, { case (HTTPS(req), rf) => rf case (req @ Host(host), rf) => - Redirect("https://%s%s".format(host, req.uri)) + val h = host.split(':')(0) + Redirect( + if (port > -1) + "https://%s:%d%s".format(h, port, req.uri) + else + "https://%s%s".format(h, req.uri) + ) } ) } diff --git a/library/src/test/scala/SecureSpec.scala b/library/src/test/scala/SecureSpec.scala deleted file mode 100644 index 58ff96e18..000000000 --- a/library/src/test/scala/SecureSpec.scala +++ /dev/null @@ -1,33 +0,0 @@ -package unfiltered.kit - -import org.specs._ -import unfiltered.spec - -object SecureSpecJetty -extends spec.jetty.Planned -with SecureSpec - -object SecureSpecNetty -extends spec.netty.Planned -with SecureSpec - -trait SecureSpec extends spec.Hosted { - import unfiltered.response._ - import unfiltered.request._ - import unfiltered.request.{Path => UFPath} - - import dispatch._ - - def intent[A,B]: unfiltered.Cycle.Intent[A,B] = - unfiltered.kit.Secure.redir { - case req@UFPath(Seg("a" :: "b" :: Nil)) => - ResponseString(req.isSecure.toString) - } - - "Secure.redir should" should { - "redirect a insecure request" in { - http((host / "a" / "b") as_str) must_== "true" - } - } - -}