Scala Play框架中的代理请求

Scala Play框架中的代理请求,scala,playframework,proxy,Scala,Playframework,Proxy,如何使用Play框架实现完全代理 我希望保持请求和响应的标题和正文完好无损。基本上,客户端和服务器都有一个透明的代理层 注意:我有些东西在工作。如果允许的话,我会把它贴出来。这就是我的结局 通过我的(不全面的)测试,这适用于各种身体类型的所有方法 请注意我使用的\uu.head。我还没有深入了解为什么标题的类型为Map[String,Seq[String]]。我可能正在删除重复的标题内容(例如,标题中的Content Type超过个)。可能将Seq[String]与连接起来是更好的方法 impo

如何使用Play框架实现完全代理

我希望保持请求和响应的标题和正文完好无损。基本上,客户端和服务器都有一个透明的代理层


注意:我有些东西在工作。如果允许的话,我会把它贴出来。

这就是我的结局

通过我的(不全面的)测试,这适用于各种身体类型的所有方法

请注意我使用的
\uu.head
。我还没有深入了解为什么标题的类型为
Map[String,Seq[String]]
。我可能正在删除重复的标题内容(例如,标题中的
Content Type
超过个)。可能将
Seq[String]
连接起来是更好的方法

import play.api.libs.ws._
import play.api.libs.iteratee.Enumerator
import play.api.mvc._

def proxy(proxyUrl: String) = Action.async(BodyParsers.parse.raw) { request =>
  // filter out the Host and potentially any other header we don't want
  val headers: Seq[(String, String)] = request.headers.toSimpleMap.toSeq.filter {
    case (headerStr, _) if headerStr != "Host" => true
    case _ => false
  }
  val wsRequestBase: WSRequestHolder = WS.url(s"http://localhost:9000/$proxyUrl") // set the proxy path
    .withMethod(request.method) // set our HTTP method
    .withHeaders(headers : _*) // Set our headers, function takes var args so we need to "explode" the Seq to var args
    .withQueryString(request.queryString.mapValues(_.head).toSeq: _*) // similarly for query strings
  // depending on whether we have a body, append it in our request
  val wsRequest: WSRequestHolder = request.body.asBytes() match {
    case Some(bytes) => wsRequestBase.withBody(bytes)
    case None => wsRequestBase
  }
  wsRequest
    .stream() // send the request. We want to process the response body as a stream
    .map { case (responseHeader: WSResponseHeaders, bodyStream: Enumerator[Array[Byte]]) => // we want to read the raw bytes for the body
      // Content stream is an enumerator. It's a 'stream' that generates Array[Byte]
      new Result(
        new ResponseHeader(responseHeader.status),
        bodyStream
      )
      .withHeaders(responseHeader.headers.mapValues(_.head).toSeq: _*)
    }
}
路由
文件条目如下所示:

GET     /proxy/*proxyUrl                   @controllers.Application.proxy(proxyUrl: String)
您需要修改其他行以支持其他方法(例如POST)

请随意提出编辑建议