在 Netty 中解码 PUT 请求
decoding a PUT request in Netty
我使用以下处理程序在 Netty 中创建了一个 HTTPServer:
public class HttpRouterServerHandler extends SimpleChannelInboundHandler<HttpRequest> {
public void channelRead0(ChannelHandlerContext ctx, HttpRequest req) {
if (HttpUtil.is100ContinueExpected(req)) {
ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE));
return;
}
System.out.println(req.toString());
HttpResponse res = /* create the response here */
flushResponse(ctx, req, res);
}
我在 Python 中使用 http.client:
发送 PUT 请求
json_data = /* constructJSON content */
connection = http.client.HTTPConnection("localhost", 8080)
connection.request("PUT", "/proto/api/send", json_data)
response = self.connection.getresponse()
connection.close()
出于某种原因,我无法获取请求的 BODY(json 内容)。原因好像是我的HttpRequest
不是FullHttpRequest
,所以我拿不到它的content()
如果我打印我的请求内容,我有类似的东西:
DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
PUT /proto/api/send HTTP/1.1
Host: localhost:8080
Accept-Encoding: identity
content-length: 47
我还尝试用我的处理程序的 FullHttpRequest 替换 HttpRequest,但在这种情况下,Netty 服务器不再响应,这导致异常 Python:
public class HttpRouterServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
if (HttpUtil.is100ContinueExpected(req)) {
ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE));
return;
}
System.out.println(req.toString());
HttpResponse res = /* create the response here */
flushResponse(ctx, req, res);
}
我的错误在哪里?
如果您不使用 FullHttpRequest
,您将收到以下消息:
- 一条
HttpRequest
条消息
- 零个或多个
HttpContent
条消息
- 一条
LastHttpContent
条消息
第一个代码片段的问题是它只接受HttpRequest
,如果你想得到以上所有消息,你应该接受HttpObject
。
我不确定第二个片段有什么问题,很可能您没有收到完整的内容,因此 FullHttpRequest
没有创建和发出。我会建议在管道中添加一个 LoggingHandler
并查看您在线上收到的内容。
我的错误是在初始化程序中。我做了:
public class HttpRouterServerInitializer extends ChannelInitializer<SocketChannel> {
private final HttpRouterServerHandler handler;
public HttpRouterServerInitializer(HttpPythonModule module) {
handler = new HttpRouterServerHandler(moduler);
}
public void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new HttpServerCodec())
.addLast(handler)
}
}
我应该做的地方:
public class HttpRouterServerInitializer extends ChannelInitializer<SocketChannel> {
private final HttpRouterServerHandler handler;
public HttpRouterServerInitializer(HttpPythonModule module) {
handler = new HttpRouterServerHandler(moduler);
}
public void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(Integer.MAX_VALUE))
.addLast(handler)
}
}
Netty 文档说 HttpObjectAggregator
class:
A ChannelHandler that aggregates an HttpMessage and its following HttpContents into a single FullHttpRequest or FullHttpResponse (depending on if it used to handle requests or responses) with no following HttpContents.
我使用以下处理程序在 Netty 中创建了一个 HTTPServer:
public class HttpRouterServerHandler extends SimpleChannelInboundHandler<HttpRequest> {
public void channelRead0(ChannelHandlerContext ctx, HttpRequest req) {
if (HttpUtil.is100ContinueExpected(req)) {
ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE));
return;
}
System.out.println(req.toString());
HttpResponse res = /* create the response here */
flushResponse(ctx, req, res);
}
我在 Python 中使用 http.client:
发送 PUT 请求 json_data = /* constructJSON content */
connection = http.client.HTTPConnection("localhost", 8080)
connection.request("PUT", "/proto/api/send", json_data)
response = self.connection.getresponse()
connection.close()
出于某种原因,我无法获取请求的 BODY(json 内容)。原因好像是我的HttpRequest
不是FullHttpRequest
,所以我拿不到它的content()
如果我打印我的请求内容,我有类似的东西:
DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
PUT /proto/api/send HTTP/1.1
Host: localhost:8080
Accept-Encoding: identity
content-length: 47
我还尝试用我的处理程序的 FullHttpRequest 替换 HttpRequest,但在这种情况下,Netty 服务器不再响应,这导致异常 Python:
public class HttpRouterServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
if (HttpUtil.is100ContinueExpected(req)) {
ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE));
return;
}
System.out.println(req.toString());
HttpResponse res = /* create the response here */
flushResponse(ctx, req, res);
}
我的错误在哪里?
如果您不使用 FullHttpRequest
,您将收到以下消息:
- 一条
HttpRequest
条消息 - 零个或多个
HttpContent
条消息 - 一条
LastHttpContent
条消息
第一个代码片段的问题是它只接受HttpRequest
,如果你想得到以上所有消息,你应该接受HttpObject
。
我不确定第二个片段有什么问题,很可能您没有收到完整的内容,因此 FullHttpRequest
没有创建和发出。我会建议在管道中添加一个 LoggingHandler
并查看您在线上收到的内容。
我的错误是在初始化程序中。我做了:
public class HttpRouterServerInitializer extends ChannelInitializer<SocketChannel> {
private final HttpRouterServerHandler handler;
public HttpRouterServerInitializer(HttpPythonModule module) {
handler = new HttpRouterServerHandler(moduler);
}
public void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new HttpServerCodec())
.addLast(handler)
}
}
我应该做的地方:
public class HttpRouterServerInitializer extends ChannelInitializer<SocketChannel> {
private final HttpRouterServerHandler handler;
public HttpRouterServerInitializer(HttpPythonModule module) {
handler = new HttpRouterServerHandler(moduler);
}
public void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(Integer.MAX_VALUE))
.addLast(handler)
}
}
Netty 文档说 HttpObjectAggregator
class:
A ChannelHandler that aggregates an HttpMessage and its following HttpContents into a single FullHttpRequest or FullHttpResponse (depending on if it used to handle requests or responses) with no following HttpContents.