Wednesday, 1 April 2015

Scala-Play filter that just dumps everything (body too)

The key thing to get body from stream is a proper Iteratee, as a bonus here is URI-decoding parsing any data.

import java.net.URLDecoder
import play.api.Logger
import play.api.libs.iteratee.Iteratee
import play.api.mvc.{ Result, RequestHeader, Filter }
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.concurrent.Future
object LoggingFilter extends Filter {
override def apply(nextFilter: (RequestHeader) => Future[Result])(rh: RequestHeader): Future[Result] = {
val startTime = System.currentTimeMillis()
nextFilter(rh).map { result =>
val endTime = System.currentTimeMillis()
val requestTime = endTime - startTime
// additionally, "uncrypt" URL-encoded input
def decoder(s: String) = URLDecoder.decode(s, "US-ASCII")
val decoded = rh.queryString.map {
case (s, ss) =>
(decoder(s),
ss.map {
decoder(_)
})
}
Logger.info(s"LF: ${rh.method} ${rh.uri} DEC:${decoded}} took ${requestTime}ms, ret: [${result.header.status}]")
val consumeForeach = Iteratee.foreach[Array[Byte]](s => Logger.debug("BChunk: " + s.map(_.toChar).mkString))
result.body |>>> consumeForeach
result
}
}
}