2016-04-14 6 views
2

私はボディと一致させるために必要なhmacヘッダを持つ投稿要求を受け取りました。このヘッダーは要求の元のボディを使用して作成されており、変更する方法はありません。要求のコンテンツタイプはapplication/jsonです。現在、要求の元のボディとjsonでエンコードされたリクエストのボディにアクセスする方法はないようです。したがって、元のボディと元のリクエストを一緒にバンドルして渡すカスタムボディパーサーとアクションを作成しようとしていますそれらに。[2.5.x]カスタムボディパーサを実行して、未処理のボディを取得し、リクエストと共にバンドルします。

私はこの男の実装https://victorops.com/blog/capturing-raw-requests-play/をコピーしようとしていますが、これはプレ・プレイ2.5ですので、akkaストリームの代わりにiterateesを使用しています。

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 
    ^

私はそれをしようとしているかを見ることができますエラーでコンパイルできない

BodyParserとケースクラス:ここ

は、私がこれまで持っているものです私に教えてください。私はそれを修正する方法がわかりません。私は解決策は、リンクで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) 
    } 

答えて

0

私を大事にこれらの行をオンにする方法がわかりません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 
関連する問題