我想实现一个http4s服务器,它从另一个服务接收内容,处理它并返回响应。
原始服务使用重定向,所以我添加了Follow 重定向中间件。我还添加了 Logger 中间件来检查生成的日志。
服务的骨架是:
implicit val clientResource = BlazeClientBuilder[F](global).resource
val wikidataEntityUrl = "http://www.wikidata.org/entity/Q"
def routes(implicit timer: Timer[F]): HttpRoutes[F] = HttpRoutes.of[F] {
case GET -> Root / "e" / entity => {
val uri = uri"http://www.wikidata.org/entity/" / ("Q" + entity)
val req: Request[F] = Request(uri = uri)
clientResource.use { c => {
val req: Request[F] = Request(Method.GET, uri)
def cb(resp: Response[F]): F[Response[F]] = Ok(resp.bodyAsText)
val redirectClient = Logger(true,true,_ => false)(FollowRedirect[F](10, _ => true)(c))
redirectClient.fetch[Response[F]](req)(cb)
}}}}
当我尝试使用 curl 访问服务时:
curl -v http://localhost:8080/e/33
响应包含原始内容的第一部分,并以:
transfer closed with outstanding read data remaining
* Closing connection 0
查看日志,它们包含以下行:
ERROR o.h.s.blaze.Http1ServerStage$$anon$1 - Error writing body
org.http4s.InvalidBodyException: Received premature EOF.
这表明接收过早的 EOF 时出错。
我在这个问题上找到了一个可能的答案:但答案建议使用不推荐使用的方法,如 tohttpService。
我想我需要使用流重写代码,但我不确定更惯用的方法是什么。一些建议?