Using Scala and Play 2.5.10 I implemented the following reusable action for composition and with the aim of disabling caching in the browser by changing the response headers:
import play.api.http.HeaderNames
import play.api.mvc._
import scala.concurrent.Future
import scala.util.{Failure, Success}
import scala.concurrent.ExecutionContext.Implicits.global
case class NoCache[A](action: Action[A]) extends Action[A] with HeaderNames {
def apply(request: Request[A]): Future[Result] = {
action(request).andThen {
case Success(result) => result.withHeaders(
(CACHE_CONTROL -> "no-cache, no-store, must-revalidate"),
(PRAGMA -> "no-cache"),
(EXPIRES -> "0")
)
case Failure(result) => result
}
}
lazy val parser = action.parser
}
I then reuse it in my controller action implementations like this:
def link = NoCache {
deadbolt.SubjectPresent()() { implicit request =>
Future {
Ok(views.html.account.link(userService, auth))
}
}
}
I breakpoint into the NoCache implementation and it gets executed correctly, however, using the Web Developer Firefox plugin to monitor the network traffic I see that the response headers do not contain the "no cache" modifications ... what'm I doing wrong?
Problem with your code
The problem is with
andThen.andThendiscards the return value. So the transformedresultwith new headers is getting discarded.Remove
andThenand make it amap.andThenis used for running side effecting computation just after the completion of the future on which it is invoked.The computation of
andThenreturns a Future with the same result that of original future and discards the return type of the computation insideandThen.Here is the implementation of
andThenfrom standard lib.Correcting your code
Other way to do that same
You can use Play filters
Filterto change the headers and also can be used for doing some pre processing and post processing work.You can target only specific routes by checking the uri of the request.
In the above example for the
/fooroute cache_control will be set and for the other routes same headers will be propagated.Note create Filters inside the root folder of the play app if not you have add the filters to the application.conf
Never run heavy running computation inside the Filters, make Filters as light as possible.