Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play 2.4 disable certain filters set based on request path or method

In Play 2.3, I can disable certain filters based on different request path or method. However, I can't find a way to do it in Play 2.4. https://www.playframework.com/documentation/2.4.x/ScalaHttpFilters. How can I achieve similar result in Play 2.4 HttpFilters.

Here is how I did it in Play 2.3.

object CacheCtrlHeadersFilter extends EssentialFilter {
  def apply(action: EssentialAction) = new EssentialAction {
    def apply(requestHeader: RequestHeader) = {
      action(requestHeader).map { result =>
        result.withHeaders(
            CACHE_CONTROL -> "no-cache, no-store, must-revalidate, private",
            PRAGMA -> "no-cache"
          )
      }
    }
  }
}

import play.api.libs.iteratee._
object FilterChainByRequestHeader {
  def apply[A](action: EssentialAction, filtersFun: (RequestHeader) => List[EssentialFilter]): EssentialAction = new EssentialAction {
    def apply(rh: RequestHeader): Iteratee[Array[Byte], Result] = {
      val chain = filtersFun(rh).reverse.foldLeft(action) { (a, i) => i(a) }
      chain(rh)
    }
  }
}

object Global extends GlobalSettings {

  val securityFilter = SecurityHeadersFilter()
  val defaultFilters = List(securityFilter,
                            CacheCtrlHeadersFilter)

  def filters(rh: RequestHeader) = {
    if (rh.method == "OPTIONS")                       <----------- by method
      defaultFilters.filterNot(_.eq(securityFilter))
    else if (rh.path.startsWith("/apps/google"))      <----------- by path
      defaultFilters.filterNot(_.eq(securityFilter))
    else defaultFilters
  }
  override def doFilter(a: EssentialAction): EssentialAction = {
    FilterChainByRequestHeader(super.doFilter(a), filters)
  }

}

There is no RequestHeader available in HttpFilters in Play 2.4

class Filters @Inject() (
  securityHeadersFilter: SecurityHeadersFilter,
  cacheCtrlHeadersFilter: CacheCtrlHeadersFilter
) extends HttpFilters {

  val filters = Seq(securityHeadersFilter, cacheCtrlHeadersFilter)
}
like image 413
angelokh Avatar asked Dec 23 '15 07:12

angelokh


1 Answers

My implementation:

class Filters @Inject() (corsFilter: CORSFilter,coreActionFilter: CoreActionFilter) extends HttpFilters { def filters = Seq(corsFilter, coreActionFilter) }

class CoreActionFilter extends Filter { def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader) = {

if(/*yourContidion*/) {

  nextFilter(requestHeader).map { result =>

    val action = requestHeader.path match {
      case "/favicon.ico" => s"[ ${requestHeader.remoteAddress.toString}]"
      case _ => s"[ ${requestHeader.remoteAddress.toString}]" + ("[") + requestHeader.tags(Tags.RoutePattern) + ("]") + ("[") + requestHeader.tags(Tags.RouteController) + "." + requestHeader.tags(Tags.RouteActionMethod) + ("]")
    }

    val startTime = System.currentTimeMillis
    val endTime = System.currentTimeMillis
    val requestTime = endTime - startTime
    val token = requestHeader.headers.get("X-Auth-Token")
    serviceLogger.info(s"[$token]" + s"${action}[${requestTime}ms]" + s"[${result.header.status}]")
    result.withHeaders("Request-Time" -> requestTime.toString)

  }(CoreContexts.simpleSqlQuery)
}
nextFilter(requestHeader)

} }

like image 134
YouXiang-Wang Avatar answered Oct 31 '22 19:10

YouXiang-Wang