Scala Play在Filter Middleware中获取响应头?

igsr9ssn  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(64)

我想捕获我的服务器将要与响应头一起发送到浏览器的响应头。检查后,我可以看到这些:

然而,当我尝试使用我的过滤器中间件时:

class CustomFilter @Inject()(implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
  private val logger = Logger(this.getClass)

  private def getRequestContext(ctx: RequestContext):String = {
    val RequestContext(userAgent, remoteAddress) = ctx
    // Log request context information based on availability of remoteAddress, appToken and appVersion
    s"NRS Request [User-Agent=$userAgent] [Remote-Address=$remoteAddress]"
  }

  private def getResponseContext(resCtx: ResponseContext): String = {
    val ResponseContext(duration, statusCode, appToken, appVersion, requestID, clientID, redirect, via) = resCtx
    s"NRS Response [DurationInMs=$duration] [Status=$statusCode] [App-Token=$appToken] [App-Version=$appVersion] [Request-ID=$requestID] [Client-ID=$clientID] [Redirect=$redirect] [Via=$via]"
  }

  private def getCompleteContext(reqCtx: RequestContext, resCtx: ResponseContext):String =
    s"{{${getRequestContext(reqCtx)}::${getResponseContext(resCtx)}}}"

  override def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader): Future[Result] = {
    val startTime = System.currentTimeMillis()

    // Extract request context information
    val userAgent = requestHeader.headers.get("User-Agent").getOrElse("")
    val remoteAddress = requestHeader.headers.get("Remote-Address")

    nextFilter(requestHeader).flatMap { result =>
      val endTime = System.currentTimeMillis()
      val duration = endTime - startTime
      val status = result.header.status
      val appToken = result.header.headers.get("X-App-Token")
      val appVersion = result.header.headers.get("X-App-Version")
      val requestID = result.header.headers.get("X-Request-ID")
      val clientID = result.header.headers.get("X-Client-ID")
      val redirect = result.header.headers.get("X-Redirect")
      val via = result.header.headers.get("Via")

      println(s"""Headers: ${result.header.headers.mkString(",")}::${requestHeader.headers.headers.mkString(",")}""")

      if (userAgent.nonEmpty) {
        logger.warn(
          getCompleteContext(
            RequestContext(userAgent, remoteAddress),
            ResponseContext(duration, status, appToken, appVersion, requestID, clientID, redirect, via)
          )
        )
      }

      Future.successful(result)
    } recoverWith {
      case e: Throwable =>
        val endTime = System.currentTimeMillis()
        val duration = endTime - startTime

        if (userAgent.nonEmpty) {
          logger.warn(getCompleteContext(RequestContext(userAgent, remoteAddress), ResponseContext(duration, 500, None, None, None, None, None, None)))
        }

        // Propagate the exception
        Future.failed(e)
    }
  }
}

字符串
很遗憾,我在中间件中看不到这些响应头。有人能帮助我理解我做错了什么吗?
我可以设置新的标题,但不能获取旧的标题:Future.successful(result.withHeaders("X-Request-ID-022" -> requestID.getOrElse("dvcsdf")))
我得到这些响应日志:

Response Header 121 - Access-Control-Allow-Origin: *
Response Header 121 - ETag: "XXXXXXX"


以下是我使用的常用过滤器:

class Filters @Inject()(corsFilter: CORSFilter,
                        clientIdFilter: ClientIdFilter,
                        requestIdFilter: RequestIdFilter,
                        processingTimeFilter: ProcessingTimeFilter,
                        host: HostFilter,
                        date: DateFilter,
                        head: HeadFilter,
                        gzipFilter: GzipFilter,
                        customFilter: CustomFilter
                       )
  extends DefaultHttpFilters(Seq(corsFilter, processingTimeFilter,
      clientIdFilter, requestIdFilter, host, date, head, gzipFilter,customFilter):_*)

irlmq6kh

irlmq6kh1#

你的过滤器需要在列表的开头。应用过滤器的代码按照列表的顺序 Package 它们,所以基本上扩展到这样:

firstFilter.apply(secondFilter.apply(thirdFilter.apply(action))))

字符串
所以,第一个过滤器是最外层的过滤器,所以当它得到一个响应时,它将从所有内部过滤器中得到它,其中所有内部过滤器都设置了头部。

相关问题