play.api.mvc.Filter Scala Examples

The following examples show how to use play.api.mvc.Filter. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: KafkaManagerLoader.scala    From CMAK   with Apache License 2.0 5 votes vote down vote up
package loader

import controllers.{AssetsComponents, BasicAuthenticationFilter, KafkaManagerContext}
import features.ApplicationFeatures
import models.navigation.Menus
import play.api.{Application, ApplicationLoader, BuiltInComponentsFromContext, LoggerConfigurator}
import play.api.ApplicationLoader.Context
import play.api.i18n.I18nComponents
import play.api.mvc.Filter
import play.api.routing.Router
import router.Routes

import scala.concurrent.ExecutionContext



class KafkaManagerLoader extends ApplicationLoader {
  def load(context: Context): Application = {
    LoggerConfigurator(context.environment.classLoader).foreach {
      _.configure(context.environment, context.initialConfiguration, Map.empty)
    }
    new ApplicationComponents(context).application
  }
}

class ApplicationComponents(context: Context) extends BuiltInComponentsFromContext(context) with I18nComponents with AssetsComponents {
  implicit val applicationFeatures: ApplicationFeatures = ApplicationFeatures.getApplicationFeatures(context.initialConfiguration.underlying)
  implicit val menus: Menus = new Menus
  implicit val ec: ExecutionContext = controllerComponents.executionContext
  val kafkaManagerContext = new KafkaManagerContext(applicationLifecycle, context.initialConfiguration)
  private[this] val applicationC = new controllers.Application(controllerComponents, kafkaManagerContext)
  private[this] lazy val clusterC = new controllers.Cluster(controllerComponents, kafkaManagerContext)
  private[this] lazy val topicC = new controllers.Topic(controllerComponents, kafkaManagerContext)
  private[this] lazy val logKafkaC = new controllers.Logkafka(controllerComponents, kafkaManagerContext)
  private[this] lazy val consumerC = new controllers.Consumer(controllerComponents, kafkaManagerContext)
  private[this] lazy val preferredReplicaElectionC= new controllers.PreferredReplicaElection(controllerComponents, kafkaManagerContext)
  private[this] lazy val reassignPartitionsC = new controllers.ReassignPartitions(controllerComponents, kafkaManagerContext)
  lazy val kafkaStateCheckC = new controllers.api.KafkaStateCheck(controllerComponents, kafkaManagerContext)
  lazy val apiHealthC = new controllers.ApiHealth(controllerComponents)

  override lazy val httpFilters: Seq[Filter] = Seq(BasicAuthenticationFilter(context.initialConfiguration))


  override val router: Router = new Routes(
    httpErrorHandler, 
    applicationC, 
    clusterC, 
    topicC, 
    logKafkaC, 
    consumerC, 
    preferredReplicaElectionC,
    reassignPartitionsC, 
    kafkaStateCheckC, 
    assets,
    apiHealthC
  ).withPrefix(context.initialConfiguration.getOptional[String]("play.http.context").orNull)
} 
Example 2
Source File: MockFilters.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.scaladsl.server.mocks

import java.util.concurrent.atomic.AtomicInteger

import akka.stream.Materializer
import com.lightbend.lagom.scaladsl.api.transport.Forbidden
import com.lightbend.lagom.scaladsl.api.transport.HeaderFilter
import com.lightbend.lagom.scaladsl.api.transport.RequestHeader
import com.lightbend.lagom.scaladsl.api.transport.ResponseHeader
import play.api.mvc.Filter
import play.api.mvc.Result
import play.api.mvc.{ RequestHeader => PlayRequestHeader }
import play.api.mvc.{ ResponseHeader => PlayResponseHeader }

import scala.concurrent.ExecutionContext
import scala.concurrent.Future

// ------------------------------------------------------------------------------------------------------------
// This is a play filter that adds a header on the request and the adds a header on the response. Headers may only
// be added once so invoking this Filter twice breaks the test.
class VerboseHeaderPlayFilter(atomicInt: AtomicInteger, mt: Materializer)(implicit ctx: ExecutionContext)
    extends Filter {
  import VerboseHeaderPlayFilter._

  implicit override def mat: Materializer = mt

  override def apply(f: (PlayRequestHeader) => Future[Result])(rh: PlayRequestHeader): Future[Result] = {
    ensureMissing(rh.headers.toSimpleMap, addedOnRequest)
    val richerHeaders = rh.headers.add(addedOnRequest -> atomicInt.incrementAndGet().toString)
    val richerRequest = rh.withHeaders(richerHeaders)
    f(richerRequest).map {
      case result =>
        ensureMissing(result.header.headers, addedOnResponse)
        result.withHeaders(addedOnResponse -> atomicInt.incrementAndGet().toString)
    }
  }

  private def ensureMissing(headers: Map[String, String], key: String) =
    if (headers.get(key).isDefined) throw Forbidden(s"Header $key already exists.")
}

object VerboseHeaderPlayFilter {
  val addedOnRequest  = "addedOnRequest-play"
  val addedOnResponse = "addedOnResponse-play"
}

// ------------------------------------------------------------------------------------------------------------
// This is a Lagom HeaderFilter that adds a header on the request and the adds a header on the response.
class VerboseHeaderLagomFilter(atomicInteger: AtomicInteger) extends HeaderFilter {
  override def transformServerRequest(request: RequestHeader): RequestHeader =
    request.addHeader(VerboseHeaderLagomFilter.addedOnRequest, atomicInteger.incrementAndGet().toString)

  override def transformServerResponse(response: ResponseHeader, request: RequestHeader): ResponseHeader =
    response.addHeader(VerboseHeaderLagomFilter.addedOnResponse, atomicInteger.incrementAndGet().toString)

  override def transformClientResponse(response: ResponseHeader, request: RequestHeader): ResponseHeader = ???
  override def transformClientRequest(request: RequestHeader): RequestHeader                             = ???
}

object VerboseHeaderLagomFilter {
  val addedOnRequest  = "addedOnRequest-Lagom"
  val addedOnResponse = "addedOnResponse-Lagom"
} 
Example 3
Source File: OnlyHttpsFilter.scala    From get-you-a-license   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package filters

import akka.stream.Materializer
import play.api.{Environment, Mode}
import play.api.http.HeaderNames
import play.api.mvc.{Filter, RequestHeader, Result, Results}

import scala.concurrent.{ExecutionContext, Future}

class OnlyHttpsFilter(environment: Environment)(implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
  def apply(nextFilter: (RequestHeader) => Future[Result])(requestHeader: RequestHeader): Future[Result] = {
    nextFilter(requestHeader).map { result =>
      if (requestHeader.secure || environment.mode == Mode.Dev) {
        result
      }
      else {
        Results.MovedPermanently("https://" + requestHeader.host + requestHeader.uri)
      }
    }
  }
} 
Example 4
Source File: LoggingFilter.scala    From HAT2.0   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.hatdex.hat.utils

import javax.inject.{ Inject, Singleton }
import akka.stream.Materializer
import com.nimbusds.jose.JWSObject
import com.nimbusds.jwt.JWTClaimsSet
import play.api.http.HttpErrorHandler
import play.api.mvc.{ Filter, RequestHeader, Result }
import play.api.{ Configuration, Logger }

import scala.concurrent.{ ExecutionContext, Future }
import scala.util.Try

@Singleton
class ActiveHatCounter() {
  // Careful! Mutable state
  private var count: Long = 0

  def get(): Long = count
  def increase(): Unit = this.synchronized(count += 1)
  def decrease(): Unit = this.synchronized(count -= 1)
}

class LoggingFilter @Inject() (
    errorHandler: HttpErrorHandler,
    configuration: Configuration,
    hatCounter: ActiveHatCounter)(
    implicit
    ec: ExecutionContext,
    val mat: Materializer) extends Filter {
  private val logger = Logger("api")

  def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader): Future[Result] = {

    val startTime = System.currentTimeMillis

    nextFilter(requestHeader)
      .recoverWith({
        case e ⇒ errorHandler.onServerError(requestHeader, e)
      })
      .map { result =>
        val active = hatCounter.get()
        val requestTime = System.currentTimeMillis - startTime
        logger.info(s"[${requestHeader.remoteAddress}] [${requestHeader.method}:${requestHeader.host}:${requestHeader.uri}] " +
          s"[${result.header.status}] [$requestTime:ms] [hats:$active] ${tokenInfo(requestHeader)}")

        result.withHeaders("Request-Time" -> requestTime.toString)
      }
  }

  private val authTokenFieldName: String = configuration.get[String]("silhouette.authenticator.fieldName")
  private def tokenInfo(requestHeader: RequestHeader): String = {
    requestHeader.queryString.get(authTokenFieldName).flatMap(_.headOption)
      .orElse(requestHeader.headers.get(authTokenFieldName))
      .flatMap(t ⇒ if (t.isEmpty) { None } else { Some(t) })
      .flatMap(t ⇒ Try(JWSObject.parse(t)).toOption)
      .map(o ⇒ JWTClaimsSet.parse(o.getPayload.toJSONObject))
      .map { claimSet =>
        s"[${Option(claimSet.getStringClaim("application")).getOrElse("api")}@" +
          s"${Option(claimSet.getStringClaim("applicationVersion")).getOrElse("_")}]"
      }
      .getOrElse("[unauthenticated@_]")
  }
} 
Example 5
Source File: AddFormatParameterIfOnlyAcceptHeaderProvidedFilter.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package filters

import akka.stream.Materializer
import com.typesafe.scalalogging.LazyLogging
import javax.inject._
import play.api.http.MediaType
import play.api.mvc.{Filter, RequestHeader, Result}

import scala.concurrent.Future

class AddFormatParameterIfOnlyAcceptHeaderProvidedFilter @Inject()(implicit val mat: Materializer) extends Filter {
  //MediaType2Format
  private[this] val mt2f: PartialFunction[String, PartialFunction[String, String]] = (mt: String) =>
    mt match {
      case "text" => {
        case "yaml"       => "yaml"
        case "json"       => "json"
        case "rdf+n3"     => "n3"
        case "n3"         => "n3"
        case "plain"      => "ntriples"
        case "ntriples"   => "ntriples"
        case "turtle"     => "ttl"
        case "ttl"        => "ttl"
        case "rdf+turtle" => "ttl"
        case "rdf+ttl"    => "ttl"
        case "n-quads"    => "nquads"
      }
      case "application" => {
        case "json"     => "jsonl"
        case "ld+json"  => "jsonld"
        case "rdf+xml"  => "rdfxml"
        case "x-nquads" => "nquads"
      }
      //    case "xml" => {
      //      case "rdf" => "rdfxml"
      //    }
  }

  private def formatToValidType(mt: MediaType): String = mt2f(mt.mediaType)(mt.mediaSubType)

  private def isCMWellAccepted(mt: MediaType): Boolean =
    mt2f.isDefinedAt(mt.mediaType) && mt2f(mt.mediaType).isDefinedAt(mt.mediaSubType)

  override def apply(next: (RequestHeader) => Future[Result])(request: RequestHeader): Future[Result] = {
    val withFormat =
      if ((request.getQueryString("format").isDefined || request.acceptedTypes.isEmpty) && Set("post", "get")(
            request.method.toLowerCase
          )) request
      else
        request.acceptedTypes.find(isCMWellAccepted(_)) match {
          case Some(mt) =>
            val newTarget = request.target.withQueryString(request.target.queryMap + ("format" -> Seq(formatToValidType(mt))))
            request.withTarget(newTarget)
          case None     => request
        }
    next(withFormat)
  }
} 
Example 6
Source File: AuthFilter.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package filters

import akka.stream.Materializer
import play.api.libs.json.Json
import play.api.mvc.{Filter, RequestHeader, Result, Results}
import security.PermissionLevel._
import security._
import wsutil._
import javax.inject._
import cmwell.ws.Settings

import scala.concurrent.{ExecutionContext, Future}

class AuthFilter @Inject()(authCache: EagerAuthCache, authUtils: AuthUtils, authorization: Authorization)(
  implicit override val mat: Materializer,
  ec: ExecutionContext
) extends Filter {

  private val useAuthorizationParam = java.lang.Boolean.getBoolean("use.authorization")
  private val irrelevantPaths = Set("/ii/", "/_")

  def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader): Future[Result] = {
    isAuthenticatedAndAuthorized(requestHeader) match {
      case Allowed(username) =>
        nextFilter(requestHeader.addAttr(Attrs.UserName, username))
      case NotAllowed(msg) if PermissionLevel(requestHeader.method) == PermissionLevel.Read =>
        Future(Results.Forbidden(msg))
      case NotAllowed(msg) =>
        Future(Results.Forbidden(Json.obj("success" -> false, "message" -> msg)))
    }
  }

  private def isAuthenticatedAndAuthorized(requestHeader: RequestHeader): AuthResponse = {
    def isRequestWriteToMeta = authUtils.isWriteToMeta(PermissionLevel(requestHeader.method), requestHeader.path)

    val tokenOpt = requestHeader.headers
      .get("X-CM-WELL-TOKEN2")
      . // todo TOKEN2 is only supported for backward compatibility. one day we should stop supporting it
      orElse(requestHeader.headers.get("X-CM-WELL-TOKEN"))
      .orElse(requestHeader.getQueryString("token"))
      .orElse(requestHeader.cookies.get("X-CM-WELL-TOKEN2").map(_.value))
      . // todo TOKEN2 is only supported for backward compatibility. one day we should stop supporting it
      orElse(requestHeader.cookies.get("X-CM-WELL-TOKEN").map(_.value))
      .flatMap(Token(_, authCache))

    val modifier = tokenOpt.fold("anonymous")(_.username) + requestHeader.getQueryString("modifier").fold("")("/".+)

    if ((!useAuthorizationParam && !isRequestWriteToMeta) || irrelevantPaths.exists(requestHeader.path.startsWith))
      Allowed(modifier)
    else {
      val request =
        (normalizePath(requestHeader.path), PermissionLevel(requestHeader.method, requestHeader.getQueryString("op")))

      tokenOpt match {
        case Some(token) if token.isValid => {
          authCache.getUserInfoton(token.username) match {
            case Some(user) =>
              AuthResponse(authorization.isAllowedForUser(request, user, Some(token.username)),
                "Authenticated but not authorized", modifier)
            case None if token.username == "root" || token.username == "pUser" =>
              Allowed(modifier) // special case only required for cases when CRUD is not yet ready
            case None => NotAllowed(s"Username ${token.username} was not found in CM-Well")
          }
        }
        case Some(_) => NotAllowed("given token is not valid (not signed or expired)")
        case None => AuthResponse(authorization.isAllowedForAnonymousUser(request), "Not authorized, please login first", modifier)
      }
    }
  }

  sealed trait AuthResponse
  case class Allowed(modifier: String) extends AuthResponse
  case class NotAllowed(msg: String) extends AuthResponse

  object AuthResponse {
    def apply(allowed: Boolean, msg: String, modifier: String): AuthResponse =
      if(allowed) Allowed(modifier) else NotAllowed(msg)
  }
} 
Example 7
Source File: TrafficShapingFilter.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package filters

import javax.inject._

import akka.stream.Materializer
import play.api.mvc.{Filter, RequestHeader, Result, Results}

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration._
import scala.util.{Success, Try}
import cmwell.ws.Settings._
import trafficshaping._


class TrafficShapingFilter @Inject()(implicit override val mat: Materializer, ec: ExecutionContext) extends Filter {

  def reqType(req: RequestHeader): String = {
    val opOpt = req.getQueryString("op")
    val segs = req.path.split("/")
    val path = Try(req.path.split("/")(1))

    (opOpt, path) match {
      case (Some(op), _)                           => op
      case (None, Success(p)) if p.startsWith("_") => p
      case _                                       => "get"
    }
  }

  def collectData(resultFuture: Future[Result], ip: String, requestType: String, startTime: Long): Unit = {
    if (ip != "127.0.0.1") {
      resultFuture.foreach { r =>
        val requestDuration = System.currentTimeMillis() - startTime
        TrafficShaper.addRequest(ip, requestType, requestDuration)
      }

    }
  }

  def collectData(ip: String, requestType: String, startTime: Long): Unit = {
    if (ip != "127.0.0.1") {
      val requestDuration = System.currentTimeMillis() - startTime
      TrafficShaper.addRequest(ip, requestType, requestDuration)
    }
  }

  def isNeedTrafficShapping(ip: String, requestType: String): Boolean = {
    val untrackedRequests = Vector("_in", "_ow")
    !untrackedRequests.contains(requestType)
  }

  override def apply(next: (RequestHeader) => Future[Result])(request: RequestHeader): Future[Result] = {
    import Math._

    val ip = request.attrs(Attrs.UserIP)
    lazy val resultFuture = next(request)
    val startTime = request.attrs(Attrs.RequestReceivedTimestamp)
    val maxDurationMillis = maxRequestTimeSec * 1000
    val penalty = TrafficShaper.penalty(ip)
    val requestType = reqType(request)

    if (TrafficShaper.isEnabled && isNeedTrafficShapping(ip, requestType))
      penalty match {
        case NoPenalty =>
          collectData(resultFuture, ip, requestType, startTime)
          resultFuture
        case DelayPenalty =>
          collectData(resultFuture, ip, requestType, startTime)
          resultFuture.flatMap { res =>
            val currentTime = System.currentTimeMillis()
            val reqDurationMillis = currentTime - startTime
            val penalty = min(reqDurationMillis, maxDurationMillis - reqDurationMillis).max(0)
            cmwell.util.concurrent.delayedTask(penalty.millis) { res }
          }
        case FullBlockPenalty =>
          cmwell.util.concurrent.delayedTask(maxDurationMillis.millis) {
            collectData(ip, requestType, startTime)
            Results.ServiceUnavailable("Please reduce the amount of requests")
          }
      } else
      resultFuture
  }
} 
Example 8
Source File: AddCharsetIfNotExistFilter.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package filters

import javax.inject._

import akka.stream.Materializer
import controllers.XCmWellType
import play.api.http.HeaderNames
import play.api.mvc.{Filter, Headers, RequestHeader, Result}
import scala.concurrent.Future

class AddCharsetIfNotExistFilter @Inject()(implicit override val mat: Materializer) extends Filter {
  def apply(next: (RequestHeader) => Future[Result])(request: RequestHeader): Future[Result] = request match {
    case XCmWellType.File()             => next(request)
    case _ if request.charset.isDefined => next(request)
    case _ => {
      val charset = request.charset.getOrElse("UTF-8")
      val contentType = request.contentType.getOrElse("text/plain")

      val headers = request.headers.headers.filterNot(_._1 == HeaderNames.CONTENT_TYPE) ++ Seq(
        HeaderNames.CONTENT_TYPE -> s"$contentType;charset=$charset"
      )
      val modifiedRequestHeader = request.withHeaders(Headers(headers: _*))

      next(modifiedRequestHeader)
    }
  }
} 
Example 9
Source File: AccessLoggingFilter.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package filters

import akka.stream.Materializer
import javax.inject.Inject
import org.slf4j.LoggerFactory
import play.api.mvc.{Filter, RequestHeader, Result}
import play.mvc.Http

import scala.concurrent.{ExecutionContext, Future}

class AccessLoggingFilter @Inject() (
    implicit val mat: Materializer,
    executionContext: ExecutionContext
) extends Filter {

  private val logger = LoggerFactory.getLogger(classOf[AccessLoggingFilter])

  def apply(next: RequestHeader => Future[Result])(request: RequestHeader): Future[Result] = {
    val resultFuture = next(request)

    resultFuture.foreach(result => {
      if (!request.uri.contains("/public") && !request.uri.contains("/assets")) {
        val msg = s"Request: method=${request.method}, path=${request.uri}, " +
          s"remote_address=${request.remoteAddress}, " +
          s"user_agent=${request.headers.get(Http.HeaderNames.USER_AGENT).getOrElse("unknown")} " +
          s"| Response: status_code=${result.header.status} "
        logger.info(msg)
      }
    })

    resultFuture
  }
} 
Example 10
Source File: MetricsFilter.scala    From play-prometheus-filters   with MIT License 5 votes vote down vote up
package com.github.stijndehaes.playprometheusfilters.filters
import akka.stream.Materializer
import com.github.stijndehaes.playprometheusfilters.metrics.RequestMetric
import io.prometheus.client.Collector
import play.api.Configuration
import play.api.mvc.{Filter, RequestHeader, Result}

import scala.concurrent.{ExecutionContext, Future}


abstract class MetricsFilter(configuration: Configuration)(implicit val mat: Materializer, ec: ExecutionContext) extends Filter {

  val metrics: List[RequestMetric[_, RequestHeader, Result]]

  val excludePaths = {
    import collection.JavaConverters._
    Option(configuration.underlying)
      .map(_.getStringList("play-prometheus-filters.exclude.paths"))
      .map(_.asScala.toSet)
      .map(_.map(_.r))
      .getOrElse(Set.empty)
  }

  def apply(nextFilter: RequestHeader => Future[Result])
           (requestHeader: RequestHeader): Future[Result] = {

    // check if current uri is excluded from metrics
    def urlIsExcluded = excludePaths.exists(_.findFirstMatchIn(requestHeader.uri).isDefined)

    val startTime = System.nanoTime

    nextFilter(requestHeader).map { implicit result =>
      implicit val rh = requestHeader

      if (!urlIsExcluded) {
        val endTime = System.nanoTime
        val requestTime = (endTime - startTime) / Collector.NANOSECONDS_PER_SECOND

        metrics.foreach(_.mark(requestTime))
      }

      result
    }
  }
} 
Example 11
Source File: ZipkinTraceFilter.scala    From play-zipkin-tracing   with Apache License 2.0 5 votes vote down vote up
package brave.play.filter

import javax.inject.Inject

import akka.stream.Materializer
import brave.play.ZipkinTraceServiceLike
import play.api.mvc.{Filter, Headers, RequestHeader, Result}
import play.api.routing.Router

import scala.concurrent.Future
import scala.util.Failure


class ZipkinTraceFilter @Inject() (tracer: ZipkinTraceServiceLike)(implicit val mat: Materializer) extends Filter {

  import tracer.executionContext
  private val reqHeaderToSpanName: RequestHeader => String = ZipkinTraceFilter.ParamAwareRequestNamer

  def apply(nextFilter: RequestHeader => Future[Result])(req: RequestHeader): Future[Result] = {
    val serverSpan = tracer.serverReceived(
      spanName = reqHeaderToSpanName(req),
      span = tracer.newSpan(req.headers)((headers, key) => headers.get(key))
    )
    val result = nextFilter(req.withHeaders(new Headers(
      (req.headers.toMap.mapValues(_.headOption getOrElse "") ++ tracer.toMap(serverSpan)).toSeq
    )))
    result.onComplete {
      case Failure(t) => tracer.serverSend(serverSpan, "failed" -> s"Finished with exception: ${t.getMessage}")
      case _ => tracer.serverSend(serverSpan)
    }
    result
  }
}

object ZipkinTraceFilter {
  val ParamAwareRequestNamer: RequestHeader => String = { reqHeader =>
    import org.apache.commons.lang3.StringUtils
    val pathPattern = StringUtils.replace(
      reqHeader.attrs.get(Router.Attrs.HandlerDef).map(_.path).getOrElse(reqHeader.path),
      "<[^/]+>", ""
    )
    s"${reqHeader.method} - $pathPattern"
  }
} 
Example 12
Source File: HttpsFilter.scala    From scala-clippy   with Apache License 2.0 5 votes vote down vote up
package controllers

import play.api.http.Status
import play.api.mvc.{Filter, RequestHeader, Result, Results}

import scala.concurrent.Future

class HttpsFilter extends Filter {
  def apply(nextFilter: (RequestHeader) => Future[Result])(requestHeader: RequestHeader): Future[Result] =
    requestHeader.headers.get("x-forwarded-proto") match {
      case Some(header) =>
        if (header == "https") {
          nextFilter(requestHeader)
        } else {
          Future.successful(
            Results.Redirect("https://" + requestHeader.host + requestHeader.uri, Status.MOVED_PERMANENTLY)
          )
        }
      case None => nextFilter(requestHeader)
    }
}