如何解决在 Netty 客户端从 HttpResponse 获取正文字节
我正在尝试使用 netty 创建 HTTP 客户端并且一切正常,但是我很难解析正文。我的管道如下所示:
pipeline.addLast(new HttpClientCodec())
pipeline.addLast(new HttpContentDecompressor())
pipeline.addLast(new HttpObjectAggregator(1024*10))
pipeline.addLast(new HttpClientHandler[A](key,metrics))
和客户端处理程序(用Scala编写)
class HttpClientHandler[A: BodyParser](key: AttributeKey[Callback[A]],metrics: Metrics)
extends SimpleChannelInboundHandler[FullHttpResponse]
with LazyLogging {
override def channelRead0(ctx: ChannelHandlerContext,msg: FullHttpResponse): Unit = {
val callback = ctx.channel().attr(key).get()
if (callback != null) {
val response = buildResponse(msg)
callback(response)
} else {
throw new Exception("Callback not present in channel context ... this is a bug")
}
}
private def buildResponse(msg: FullHttpResponse): Either[Throwable,Response[A]] = {
val result = {
try {
val parsedBody = BodyParser[A].parse(msg.content().asReadOnly())
if (msg.status() == HttpResponseStatus.OK) {
Right(Response.Ok(parsedBody))
} else {
Right(Response.Other(msg.status().code(),parsedBody))
}
} catch {
case e: Throwable =>
Left(e)
}
}
result.fold(metrics.bodyParseFailure,metrics.successfulResponse)
result
}
override def exceptionCaught(ctx: ChannelHandlerContext,cause: Throwable): Unit = {
logger.warn(s"error observed for channel ${ctx.channel()},closing",cause)
ctx.channel().attr(key).get().apply(Left(cause))
}
}
主要问题是 msg.content()
还包含 Http 数据(方法、版本、标题...)但我只对正文感兴趣。我究竟做错了什么?谢谢!
解决方法
这太奇怪了... msg.content()
是一个 ByteBuf
,它只应该包含请求/响应的有效负载。
事实证明这是由于对重复整个 http 请求的回显服务器进行测试引起的,如以下证明:
$ curl -X POST localhost:3000/a/b/c -v
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3000 (#0)
> POST /a/b/c HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sat,19 Dec 2020 09:50:56 GMT
< X-Http-Echo-Server-Id: 9fcf5d57-2ac7-4a92-8aed-775879bf3ac2
< Content-Type: text/plain;charset=utf-8
< Transfer-Encoding: chunked
< Server: Jetty(9.4.24.v20191120)
<
POST /a/b/c HTTP/1.1
Accept: */*
User-Agent: curl/7.64.1
Host: localhost:3000
* Connection #0 to host localhost left intact
* Closing connection 0
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。