2016-04-14 4 views
2

Ich habe eine Post-Anfrage mit einem hmac-Header kommen, die ich mit dem Körper gegen übereinstimmen muss. Dieser Header wird mit dem rohen Hauptteil der Anfrage erstellt, und ich habe keine Möglichkeit, dies zu ändern. Der Inhaltstyp der Anfrage lautet application/json. Derzeit scheint es keine Möglichkeit zu geben, auf den rohen Hauptteil der Anfrage zuzugreifen, und auch einen JSON-kodierten Körper der Anfrage, so dass ich versuche, einen benutzerdefinierten Körperparser und eine Aktion zu erstellen, um den Rohkörper und die ursprüngliche Anfrage zusammen zu bündeln und zu übergeben sie auf.Play [2.5.x] benutzerdefinierte Körper-Parser zu rohen Körper und bündeln Sie es mit Anfrage

Ich versuche, diese Jungs Implementierung https://victorops.com/blog/capturing-raw-requests-play/ zu kopieren, aber es ist Pre Play 2.5 so verwendet iterates anstelle von akka Streams. Hier

ist das, was ich bisher:

BodyParser und Fallklassen

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 
    } 
} 

Dies kompiliert nicht mit einem Fehler

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 
    ^

Jetzt kann ich sehen, was das versucht, Sag es mir und ich verstehe, dass ich einfach nicht weiß, wie ich es beheben kann. Ich stelle mir die Lösung zwischen der Linie 15 und 24 von victorops Beispiel in der Verbindung ist, aber ich weiß nicht, wie diese Zeilen in eine 2.5-Version

Die benutzerdefinierte Aktion für den Fall, schalten Sie es ankommt

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) 
    } 

Antwort

0

I bin neu zu spielen, aber wie wäre es mit dem raw Body-Parser, der viel einfacher ist. Ich habe einen schnellen Test gemacht.

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 
Verwandte Themen