Instantly share code, notes, and snippets.

Embed
What would you like to do?
Reverse-proxy in Play!
def reverseProxy = Action.async(parse.raw) {
request: Request[RawBuffer] =>
// Create the request to the upstream server:
val proxyRequest =
WS.url("http://localhost:8887" + request.path)
.withFollowRedirects(false)
.withMethod(request.method)
.withVirtualHost("localhost:9000")
.withHeaders(flattenMultiMap(request.headers.toMap): _*)
.withQueryString(request.queryString.mapValues(_.head).toSeq: _*)
.withBody(request.body.asBytes().get)
// Stream the response to the client:
proxyRequest.stream.map {
case (headers: WSResponseHeaders, enum) => Result(
ResponseHeader(headers.status, headers.headers.mapValues(_.head)),
enum)
}
}
@aloon

This comment has been minimized.

aloon commented Mar 10, 2015

The code runs well unless the backend content-encoding is chuncked. Do you know how do it?

@dominikbucher

This comment has been minimized.

dominikbucher commented Oct 5, 2015

Something like that? Also see the Play Framework Documentation.

      proxyRequest.stream().map {
        case (response, body) =>
          // Check that the response was successful.
          if (response.status == 200) {
            // Get the content type.
            val contentType = response.headers.get("Content-Type").flatMap(_.headOption)
              .getOrElse("application/octet-stream")
            val headers = response.headers.filterKeys(_ != "Transfer-Encoding")

            // If there's a content length, send that, otherwise return the body chunked.
            response.headers.get("Content-Length") match {
              case Some(Seq(length)) =>
                Ok.feed(body)
                  .withHeaders(headers.mapValues(_.mkString(",")).toSeq: _*)
                  .withHeaders("Content-Length" -> length)
                  .as(contentType)
              case _ =>
                Ok.chunked(body)
                  .withHeaders(headers.mapValues(_.mkString(",")).toSeq: _*)
                  .as(contentType)
            }
          } else {
            BadGateway
          }
      }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment