I'm trying to craft a ScalaInterceptor that looks for an X-Forwarded-Proto
header, so basically if its in production or behind a proxy then Play! auto redirects to SSL.
I've run into issues with getting this code to compile, and I'm also not sure whether this will work with the SecureSocial plugin. There are specific reasons why we aren't setting SSL=true in SecureSocial.conf that I won't go into here.
Here's what I have in my Global.scala
def WithHttpsRedirect[A](action: Action[A]): Action[A] = {
Action(action.parser) { request =>
val result = action(request)
request.headers.get("X-Forwarded-Proto").collect {
case "https" =>
result
case "http" =>
val url = "https://"+request.host+request.uri
Redirect(url)
} getOrElse {
result
}
}
}
override def onRouteRequest(request: RequestHeader): Option[Handler] = {
super.onRouteRequest(request).map { handler =>
handler match {
case a: Action[_] => WithHttpsRedirect(a)
case _ => handler
}
}
}
I'm getting a compiler error after the getOrElse
:
[error] found : scala.concurrent.Future[play.api.mvc.SimpleResult]
[error] required: play.api.mvc.Result
[error] result
[error] ^
Your help is greatly appreciated!
Changed my method of attack, and instead implemented a filter instead of overriding onRouteRequest
:
In Global.scala:
object Global extends WithFilters(HttpsFilter) with GlobalSettings
then HttpsFilter.scala:
import play.api.mvc.Results._
import play.api.mvc.{SimpleResult, RequestHeader, Filter}
import scala.concurrent._
import ExecutionContext.Implicits.global
object HttpsFilter extends Filter {
def apply(next: (RequestHeader) => Future[SimpleResult])(request: RequestHeader): Future[SimpleResult] = {
request.headers.get("X-Forwarded-Proto").collect {
case "https" =>
next(request)
case "http" =>
val url = "https://"+request.host+request.uri
Future{ Redirect(url) }
} getOrElse {
next(request)
}
}
}