- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这与 this question 相关,但我正在尝试将问题分解为更小的步骤。
我正在尝试使用netty编写一个简单的http服务器(服务器A),它接收http请求,向另一台服务器(服务器B)发出http请求,然后将响应中的内容复制到对初始请求。我知道有一些如何做到这一点的示例,例如 LittleProxy,但代码相当复杂,而且由于我对 netty 很陌生,所以我试图使我的第一个代码尽可能简单,而无需陷入困境杂草。
目前,我忽略了所有关于并发性的问题,只建立了一个从服务器 A 到服务器 B 的 channel (我知道这会因并发请求而严重中断,但它使我的初始任务更简单)。
我的方法如下:
设置客户端 Bootstrap 并连接到在本地主机端口 18080 上运行的服务器 B。获取相应的 channel 。
启动服务器 A 监听端口 2080,并使用管道解码 http 请求,然后写入到服务器 B 的 channel 。
向生成的 channel future 添加一个监听器,该监听器会将服务器 B 的响应内容复制到对服务器 A 的原始客户端请求的响应。
这是我的代码(非常短),我试图在其中完全按照上面描述的方式进行操作。我的问题是我不知道如何将服务器 B 的响应复制到服务器的响应。当我在服务器 A 发送的响应中写入原始客户端时,我发现执行此操作的一种方法会导致 IllegalArgumentException(我检查了 ChannelBuffer 的内容,并且代理服务器返回了正确的文本)。我在下面粘贴了异常的部分堆栈跟踪。欢迎其他评论,因为除了明显缺乏对服务器 B channel 的锁定之外,我可能还会犯其他错误:
public class NettyExample {
private static Channel channel;
private static Map<Channel, Channel> proxyToClient = new ConcurrentHashMap<Channel, Channel>();
public static void main(String[] args) throws Exception {
ChannelFactory clientFactory =
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
final ClientBootstrap cb = new ClientBootstrap(clientFactory);
cb.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
return Channels.pipeline(
new HttpRequestEncoder(),
new HttpResponseDecoder(),
new ResponseHandler());
}
});
ChannelFuture cf = cb.connect(new InetSocketAddress("localhost", 18080));
channel = cf.awaitUninterruptibly().getChannel();
ChannelFactory factory =
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
ServerBootstrap sb = new ServerBootstrap(factory);
sb.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
return Channels.pipeline(
new HttpRequestDecoder(),
new RequestHandler());
}
});
sb.setOption("child.tcpNoDelay", true);
sb.setOption("child.keepAlive", true);
sb.bind(new InetSocketAddress(2080));
}
private static class ResponseHandler extends SimpleChannelHandler {
@Override
public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) {
final HttpResponse proxyResponse = (HttpResponse) e.getMessage();
Channel clientChannel = proxyToClient.get(e.getChannel());
HttpResponse clientResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
clientResponse.setContent(proxyResponse.getContent());
clientChannel.write(clientResponse).addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
Channel ch = future.getChannel();
ch.close();
}
});
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
e.getCause().printStackTrace();
Channel ch = e.getChannel();
ch.close();
}
}
private static class RequestHandler extends SimpleChannelHandler {
@Override
public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) {
final HttpRequest request = (HttpRequest) e.getMessage();
System.out.println("calling client channel");
proxyToClient.put(channel, e.getChannel());
channel.write(request);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
e.getCause().printStackTrace();
Channel ch = e.getChannel();
ch.close();
}
}
}
这个中继调用似乎有效,直到调用 clientChannel.write(clientResponse) 为止。在那里,生成以下异常:
java.lang.IllegalArgumentException: unsupported message type: class org.jboss.netty.handler.codec.http.DefaultHttpResponse
at org.jboss.netty.channel.socket.nio.SocketSendBufferPool.acquire(SocketSendBufferPool.java:53)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.write0(AbstractNioWorker.java:468)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromTaskLoop(AbstractNioWorker.java:432)
最佳答案
您需要设置一个客户端管道来等待响应,然后将其写入您的响应。
查看窥探客户端 example ;具体来说,HttpSnoopClientHandler .
关于java - 如何解码 http 请求的响应并在 netty 中使用内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15772620/
我有以下 json: {"results": [{"columns":["room_id","player_name","player_ip"], "types":["integer","text
我在 go 中获取格式不一致的 JSON 文件。例如,我可以有以下内容: {"email": "\"blah.blah@blah.com\""} {"email": "robert@gmail.com
JavaScript中有JSON编码/解码base64编码/解码函数吗? 最佳答案 是的,btoa() 和 atob() 在某些浏览器中可以工作: var enc = btoa("this is so
我在其中一个项目中使用了 Encog,但在解码 One-Of Class 时卡住了。该字段的规范化操作之一是 NormalizationAction.OneOf,它具有三个输出。当我评估时,我想解码预
在我的 previous question关于使用 serialize() 创建对象的 CSV 我从 jmoy 那里得到了一个很好的答案,他推荐了我的序列化文本的 base64 编码。这正是我要找的。
有些事情让我感到困惑 - 为什么 this image在每个浏览器中显示不同? IE9(和 Windows 照片查看器)中的图像: Firefox(和 Photoshop)中的图像: Chrome(和
是否可以在不知道它的类型( JAXBContext.newInstance(clazz) )的情况下解码一个类,或者什么是测试即将到来的正确方法? 我确实收到了从纯文本中解码的消息 - 字符串 传入的
我正在尝试使用 openSSL 库进行 Base64 解码,然后使用 CMS 来验证签名。 下面的代码总是将缓冲区打印为 NULL。 char signed_data[] = "MIIO"; int
我有一个带有 SEL 类型实例变量的类,它是对选择器的引用。在encodeWithCoder/initWithCoder中,如何编码/解码这种类型的变量? 最佳答案 您可以使用 NSStringFro
var url = 'http://www.googleapis.com/customsearch/v1?q=foo&searchType=image'; window.fetch(url) .t
我想知道Android 2.2、2.3和3,4支持的音频/视频格式列表。我也想知道哪些Android版本支持视频编码和解码。我经历了this link,但是关于编码和解码我并不清楚。 任何人的回答都是
我在其中一个项目中使用 Encog,但在解码 One-Of 类时遇到了困难。该字段的规范化操作之一是 NormalizationAction.OneOf,它具有三个输出。当我评估时,我想解码预测值。如
我正在尝试解码现有的 xml 文件,以便我可以正确处理数据,但 XML 结构看起来很奇怪。下面是 xml 示例以及我创建的对象。 11 266 AA1001 1
对 unicode 字符进行 URL 编码的常用方法是将其拆分为 2 %HH 代码。 (\u4161 => %41%61) 但是,unicode在解码时是如何区分的呢?您如何知道 %41%61 是 \
我正在尝试将 json 字符串解码为 Map。 我知道有很多这样的问题,但我需要非常具体的格式。例如,我有 json 字符串: { "map": { "a": "b",
我有一个查询,我认为需要像这样(解码会更大) SELECT firstName, lastName, decode(mathMrk, 80, 'A', mathMrk) as decodeMat
我知道PHP函数encode()和decode(),它们对我来说工作得很好,但我想在url中传递编码字符串,但encode确实返回特殊字符,如“=”、“”' “等等...... 这显然会破坏我的脚本,
我必须解码 Basic bW9uTG9naW46bW9uTW90RGVQYXNz 形式的 http 请求的授权 header 当我解码它时online ,我得到了正确的结果 monLogin:monM
这个问题已经有答案了: Decode Base64 data in Java (21 个回答) 已关闭 8 年前。 我想知道使用哪个库进行 Base64 编码/解码?我需要此功能足够稳定以供生产使用。
我正在尝试从 Arduino BT 解码 []byte,我的连接完美,问题是当我尝试解码数组时。我得到的只是这个字符�(发送的字节数相同)我认为问题出在解码上。我尝试使用 ASCII 字符集,但仍然存
我是一名优秀的程序员,十分优秀!