Использовать лифт в качестве прокси

Я хочу запретить полный доступ к ядру Solr извне и разрешить использовать его только для запросов. Таким образом, я запускаю вторичный экземпляр сервера с соединителем в контейнере сервлетов Jetty (кроме основного веб-приложения) на порту, который недоступен из WWW.

Когда есть входящий HTTP-запрос к liftweb приложение, я ловлю с RestHelper:

object Dispatcher extends RestHelper {
  serve {
    case List("api", a @ _*) JsonGet _ => JString("API is not implemented yet. rest: " + a)
  }
}

Ориентация моего браузера на http://localhost/api/solr/select?q=region Я получаю ответ "API is not implemented yet. rest: List(solr, select)"так что похоже на работу. Теперь я хочу установить соединение с внутренним портом (где находится Solr), чтобы передать запрос с помощьюapi часть URL (т.е. http://localhost:8080/solr/select?q=region). Я ловлю завершающую REST-часть URL (с помощью a @ _*), но как я могу получить доступ к параметрам URL? Было бы идеально передать необработанную строку (после api элемент пути) к экземпляру Solr, просто чтобы предотвратить избыточные шаги разбора / сборки. Так же относится и к ответу Солра: я бы хотел избежать разбора сборки JsonResponse.

Кажется, это хороший пример выполнения HTTP-перенаправления, но тогда мне придется открыть скрытый порт Solr, насколько я понимаю.

Какой самый эффективный способ справиться с этой задачей?

РЕДАКТИРОВАТЬ:

Ну, я пропустил это после JsonGet выходит Req значение, в котором есть вся необходимая информация. Но есть ли еще способ избежать нежелательного разбора / создания URL для скрытого порта и JSON-ответа?

РЕШЕНИЕ:

Вот то, что я получил предложение Дейва:

import net.liftweb.common.Full
import net.liftweb.http.{JsonResponse, InMemoryResponse}
import net.liftweb.http.provider.HTTPRequest
import net.liftweb.http.rest.RestHelper
import dispatch.{Http, url}

object ApiDispatcher extends RestHelper {
  private val SOLR_PORT = 8080

  serve { "api" :: Nil prefix {
    case JsonGet(path @ List("solr", "select"), r) =>
      val u = localApiUrl(SOLR_PORT, path, r.request)
      Http(url(u) >> { is =>
        val bytes = Stream.continually(is.read).takeWhile(-1 !=).map(_.toByte).toArray
        val headers = ("Content-Length", bytes.length.toString) ::
          ("Content-Type", "application/json; charset=utf-8") :: JsonResponse.headers
        Full(InMemoryResponse(bytes, headers, JsonResponse.cookies, 200))
      })
  }}

  private def localApiUrl(port: Int, path: List[String], r: HTTPRequest) =
    "%s://localhost:%d/%s%s".format(r.scheme, port, path mkString "/", r.queryString.map("?" + _).openOr(""))
}

1 ответ

Решение

Я не уверен, что понимаю ваш вопрос, но если вы хотите вернуть JSON, полученный от solr, без его анализа, вы можете использовать net.liftweb.http.InMemoryResponse, который содержит представление JSON byte[].

Другие вопросы по тегам