Created
October 6, 2016 01:17
-
-
Save ryandavidhartman/e625e31f80bda4ea08851cbdb0a404f3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.angieslist.common.play.controller | |
import com.angieslist.common.http.DispatchHttpClientComponent | |
import com.angieslist.common.{Logger, LoggerComponent} | |
import com.ning.http.client.FluentCaseInsensitiveStringsMap | |
import com.typesafe.config.{Config, ConfigFactory} | |
import dispatch.{url, _} | |
import play.api.mvc._ | |
import scala.collection.JavaConversions._ | |
import scala.concurrent.ExecutionContext | |
import scala.concurrent.ExecutionContext.Implicits.global | |
trait ProxyConfig { | |
val config: Config = ConfigFactory.load() | |
val routes = config.getConfigList("proxiedRoutes").map(config => config.getString("path") -> config.getString("proxy")) | |
def proxiedRoutes: Map[String,String] = routes.toMap | |
} | |
trait ProxyController extends Controller{ | |
def proxyWildCard(wildcard: String)(implicit executionContext: ExecutionContext): Action[AnyContent] | |
def proxyTo(request: RequestHeader)(implicit executionContext: ExecutionContext): Future[Result] | |
def proxyTo(request: RequestHeader, wildcard: String)(implicit executionContext: ExecutionContext): Future[Result] | |
} | |
class DispatchProxyController(dispatchClient: Http, proxiedRoutes: Map[String,String], logger: Logger) extends ProxyController { | |
//val http = Http.configure(_ setFollowRedirects true setCompressionEnabled true) | |
val stripResponseHeaders = Seq("transfer-encoding", "Connection", "Content-Length") | |
def proxy = proxyWildCard("") | |
def proxyWildCard(wildcard: String)(implicit executionContext: ExecutionContext): Action[AnyContent] = Action.async { request => | |
proxyTo(request, wildcard) | |
} | |
def proxyTo(request: RequestHeader)(implicit executionContext: ExecutionContext): Future[Result] = proxyTo(request, "") | |
def proxyTo(request: RequestHeader, wildcard: String)(implicit executionContext: ExecutionContext): Future[Result] = { | |
val target = proxiedRoutes.get(request.path) | |
target map { t => | |
logger.debug(s"Proxying to target [${target}] for path [${request.path}] and wildcard.") | |
proxyRequest(request, t + wildcard) | |
} getOrElse { | |
val notFound = proxiedRoutes.get("/notfound") | |
notFound map { nf => | |
proxyRequest(request, nf + request.path) | |
} getOrElse {Future.successful(NotFound("Not Found"))} | |
} | |
} | |
private def proxyRequest(request: RequestHeader, urlToProxy: String) = { | |
val site = url(urlToProxy).setHeaders(request.headers.toMap) | |
dispatchClient(site).map { r => | |
val body = r.getResponseBody | |
Ok(body).withHeaders( | |
fixHeaders(r.getHeaders, body.length).toSeq: _* | |
) | |
} | |
} | |
private def fixHeaders(headers: FluentCaseInsensitiveStringsMap, bodyLength: Int) = { | |
headers | |
.filterKeys(k => { | |
!stripResponseHeaders.contains(k) | |
}) | |
.mapValues(_.head) | |
} | |
} | |
trait ProxyControllerComponent { | |
def proxyController: ProxyController | |
} | |
trait DispatchProxyControllerComponent extends ProxyController { | |
this: LoggerComponent | |
with ProxyConfig | |
with DispatchHttpClientComponent=> | |
lazy val proxyController: ProxyController = new DispatchProxyController(dispatchClient, proxiedRoutes, logger) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment