【问题标题】:Play[2.5.x] custom body parser to get raw body and bundle it with requestPlay[2.5.x] 自定义正文解析器以获取原始正文并将其与请求捆绑
【发布时间】:2016-04-14 20:14:28
【问题描述】:

我有一个带有 hmac 标头的 post 请求,我需要匹配正文。此标头是使用请求的原始正文创建的,我无法更改它。请求的内容类型为 application/json。目前似乎无法访问请求的原始正文以及请求的 json 编码正文,因此我正在尝试创建自定义正文解析器和操作以将原始正文和原始请求捆绑在一起并通过他们在。

我正在尝试复制这些家伙的实现https://victorops.com/blog/capturing-raw-requests-play/,但它是预播放 2.5,因此使用迭代器而不是 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)
    }

【问题讨论】:

    标签: scala playframework playframework-2.5


    【解决方案1】:

    我是 Play 新手,但是如何使用更简单的 raw 正文解析器。我做了一个快速测试。

    class Tester extends Controller {
      def handleRaw = Action(parse.raw) { implicit request =>
        request.body.asBytes().map(b => Ok(s"Request body has ${b.size} bytes")).getOrElse(NoContent)
      }
    }
    

    curl -v --data "a=b&c=d" http://localhost:9000/test/raw

    *   Trying ::1...
    * Connected to localhost (::1) port 9000 (#0)
    > POST /test/raw HTTP/1.1
    > Host: localhost:9000
    > User-Agent: curl/7.43.0
    > Accept: */*
    > Content-Length: 7
    > Content-Type: application/x-www-form-urlencoded
    > 
    * upload completely sent off: 7 out of 7 bytes
    < HTTP/1.1 200 OK
    < Content-Length: 85
    < Content-Type: text/plain; charset=utf-8
    < Date: Mon, 15 Aug 2016 09:41:30 GMT
    < 
    Request body has 7 bytes
    * Connection #0 to host localhost left intact
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 2013-09-13
      • 1970-01-01
      • 2018-06-24
      相关资源
      最近更新 更多