我有一个带有 hmac 标头的发布请求,我需要匹配正文。此标头是使用请求的原始正文创建的,我无法更改它。请求的内容类型是 application/json。目前似乎无法访问请求的原始正文以及请求的 json 编码正文,因此我正在尝试创建自定义正文解析器和操作以将原始正文和原始请求捆绑在一起并通过他们上。
我正在尝试复制这些人的实现https://victorops.com/blog/capturing-raw-requests-play/但它是预播放 2.5,因此使用 iteratees 而不是 akka 流。
这是我到目前为止所拥有的:
BodyParser 和案例类
object RequestArchiver {
case class RawRequest[A](request: Request[A], raw: ByteString) extends WrappedRequest[A](request)
case class WrappedPayload[A](wrapped: A, raw: ByteString)
def wrappedBodyParser[B](wrapped: BodyParser[B]) (implicit exCtx: ExecutionContext): BodyParser[WrappedPayload[B]] =
BodyParser("raw-memo") { (request: RequestHeader) =>
val raw: Accumulator[ByteString, Either[Result, RawBuffer]] = BodyParsers.parse.raw(request)
val ret = raw.map {
case Left(result) =>
Left(result)
case Right(buffer: RawBuffer) =>
val bytes = buffer.asBytes().getOrElse(ByteString.empty)
Right(WrappedPayload(wrapped(request), bytes))
}
ret
}
}
这不会编译错误
Error:(33, 5) type mismatch;
found : play.api.libs.streams.Accumulator[akka.util.ByteString,Product with Serializable with scala.util.Either[play.api.mvc.Result,controllers.RequestArchiver.WrappedPayload[play.api.libs.streams.Accumulator[akka.util.ByteString,Either[play.api.mvc.Result,B]]]]]
required: play.api.libs.streams.Accumulator[akka.util.ByteString,Either[play.api.mvc.Result,controllers.RequestArchiver.WrappedPayload[B]]]
ret
^
现在我可以看到它试图告诉我什么,并且我明白我只是不知道如何解决它。我想解决方案在链接中 victorops 示例的第 15 行和第 24 行之间,但我不知道如何将这些行转换为 2.5 版本
重要的自定义操作
def extractRaw[A](parser: BodyParser[A])(block: (RawRequest[A]) => Future[Result])(implicit ctx: ExecutionContext) =
Action.async(RequestArchiver.wrappedBodyParser(parser)) { implicit request =>
val rawRequest = RawRequest(Request(request, request.body.wrapped), request.body.raw)
block(rawRequest)
}