Skip to content

Instantly share code, notes, and snippets.

@eamelink
Created November 15, 2013 12:31
Show Gist options
  • Save eamelink/7483621 to your computer and use it in GitHub Desktop.
Save eamelink/7483621 to your computer and use it in GitHub Desktop.
Proxying a web service with Play
package controllers
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.iteratee.{ Concurrent, Iteratee }
import play.api.libs.ws.{ ResponseHeaders, WS }
import play.api.mvc.{ Action, Controller, SimpleResult }
import scala.concurrent.Promise
object Application extends Controller {
def proxy(url: String) = Action.async { request =>
val resultP = Promise[SimpleResult]()
WS.url(url).get { headers =>
val iterateeP = Promise[Iteratee[Array[Byte], Unit]]
// I wonder if we can propagate error or disconnect of the client
// to the WS library.
val enumerator = Concurrent.unicast[Array[Byte]](
onStart = channel => {
val iteratee = Iteratee.foreach[Array[Byte]](channel.push).map(_ => channel.eofAndEnd())
iterateeP.success(iteratee)
})
resultP.success(Status(headers.status).chunked(enumerator).withHeaders(seqHeaders(headers): _*))
Iteratee.flatten(iterateeP.future)
}.map(_.run)
resultP.future
}
/**
* Transform headers from Map[String, Seq[String]] to Seq[(String, String)]
*/
def seqHeaders(responseHeaders: ResponseHeaders): Seq[(String, String)] =
for {
(name, values) <- responseHeaders.headers.toSeq
value <- values
} yield name -> value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment