package org.rx.socks.proxy;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.rx.common.Logger; import java.util.function.BiConsumer; import static org.rx.common.Contract.require; public class DirectClientHandler extends SimpleChannelInboundHandler<byte[]> {
private BiConsumer<ChannelHandlerContext, byte[]> onReceive;
private ChannelHandlerContext ctx; public Channel getChannel() {
require(ctx);
return ctx.channel();
} public DirectClientHandler(BiConsumer<ChannelHandlerContext, byte[]> onReceive) {
require(onReceive); this.onReceive = onReceive;
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
this.ctx = ctx;
Logger.info("DirectClientHandler %s connect %s", ctx.channel().localAddress(), ctx.channel().remoteAddress());
} @Override
protected void channelRead0(ChannelHandlerContext ctx, byte[] bytes) {
onReceive.accept(ctx, bytes);
Logger.info("DirectClientHandler %s recv %s bytes from %s", ctx.channel().remoteAddress(), bytes.length,
ctx.channel().localAddress());
} public ChannelFuture send(byte[] bytes) {
try {
return ctx.channel().writeAndFlush(bytes);
} finally {
Logger.info("DirectClientHandler %s send %s bytes to %s", ctx.channel().localAddress(), bytes.length,
ctx.channel().remoteAddress());
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
Logger.error(cause, "DirectClientHandler");
ctx.close();
}
}
package org.rx.socks.proxy;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.rx.common.Logger; import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer; import static org.rx.common.Contract.require; public class DirectServerHandler extends SimpleChannelInboundHandler<byte[]> {
private static class ClientState {
private ProxyClient directClient;
// private int length;
// private MemoryStream stream; public ProxyClient getDirectClient() {
return directClient;
} public ClientState(boolean enableSsl, SocketAddress directAddress,
BiConsumer<ChannelHandlerContext, byte[]> onReceive) {
require(directAddress, onReceive); directClient = new ProxyClient();
directClient.setEnableSsl(enableSsl);
directClient.connect((InetSocketAddress) directAddress, onReceive);
// stream = new MemoryStream(32, true);
} // private int readRemoteAddress(byte[] bytes) {
// int offset = 0;
// if (length == -1) {
// stream.setLength(length = Bytes.toInt(bytes, 0));
// stream.setPosition(0);
// offset = Integer.BYTES;
// }
// int count = length - stream.getPosition();
// stream.write(bytes, offset, Math.min(count, bytes.length));
// if (stream.getPosition() < length) {
// return -1;
// }
//
// directAddress = Sockets.parseAddress(Bytes.toString(stream.getBuffer(), 0, length));
// length = -1;
// return bytes.length - count;
// }
} private final Map<ChannelHandlerContext, ClientState> clients;
private boolean enableSsl;
private SocketAddress directAddress; public DirectServerHandler(boolean enableSsl, SocketAddress directAddress) {
require(directAddress); clients = new ConcurrentHashMap<>();
this.enableSsl = enableSsl;
this.directAddress = directAddress;
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
clients.put(ctx, new ClientState(enableSsl, directAddress, (directChannel, bytes) -> {
ctx.writeAndFlush(bytes);
Logger.info("DirectServerHandler %s recv %s bytes from %s", ctx.channel().remoteAddress(), bytes.length,
directAddress);
}));
Logger.info("DirectServerHandler %s connect %s", ctx.channel().remoteAddress(), directAddress);
} @Override
protected void channelRead0(ChannelHandlerContext ctx, byte[] bytes) {
ClientState state = clients.get(ctx);
require(state); ProxyClient directClient = state.getDirectClient();
directClient.send(bytes);
Logger.info("DirectServerHandler %s send %s bytes to %s",
directClient.getHandler().getChannel().remoteAddress(), bytes.length, ctx.channel().remoteAddress());
} @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
clients.remove(ctx);
Logger.info("DirectServerHandler %s disconnect %s", ctx.channel().remoteAddress(), directAddress);
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
Logger.error(cause, "DirectServerHandler");
ctx.close();
}
}
package org.rx.socks.proxy;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.compression.ZlibWrapper;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import lombok.SneakyThrows;
import org.rx.common.App;
import org.rx.common.Disposable; import java.net.InetSocketAddress;
import java.util.function.BiConsumer; import static org.rx.common.Contract.require;
import static org.rx.socks.proxy.ProxyServer.Compression_Key; public class ProxyClient extends Disposable {
private EventLoopGroup group;
private boolean enableSsl;
private DirectClientHandler handler; public boolean isEnableSsl() {
return enableSsl;
} public void setEnableSsl(boolean enableSsl) {
this.enableSsl = enableSsl;
} public boolean isEnableCompression() {
return App.convert(App.readSetting(Compression_Key), boolean.class);
} public DirectClientHandler getHandler() {
checkNotClosed();
return handler;
} @Override
protected void freeObjects() {
if (group != null) {
group.shutdownGracefully();
}
} public void connect(InetSocketAddress remoteAddress) {
connect(remoteAddress, null);
} @SneakyThrows
public void connect(InetSocketAddress remoteAddress, BiConsumer<ChannelHandlerContext, byte[]> onReceive) {
checkNotClosed();
require(group == null);
require(remoteAddress); // Configure SSL.
SslContext sslCtx = null;
if (enableSsl) {
sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} Bootstrap b = new Bootstrap();
SslContext ssl = sslCtx;
b.group(group = new NioEventLoopGroup()).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
if (ssl != null) {
pipeline.addLast(
ssl.newHandler(ch.alloc(), remoteAddress.getHostName(), remoteAddress.getPort()));
}
if (isEnableCompression()) {
pipeline.addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
pipeline.addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
} pipeline.addLast(new ByteArrayDecoder());
pipeline.addLast(new ByteArrayEncoder()); pipeline.addLast(new DirectClientHandler(onReceive));
}
});
ChannelFuture f = b.connect(remoteAddress).sync();
handler = (DirectClientHandler) f.channel().pipeline().last();
} public ChannelFuture send(byte[] bytes) {
checkNotClosed();
require(group != null);
require(bytes); return getHandler().send(bytes);
}
}
package org.rx.socks.proxy;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.compression.ZlibWrapper;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import lombok.SneakyThrows;
import org.rx.common.App;
import org.rx.common.Disposable;
import org.rx.socks.Sockets; import java.net.InetSocketAddress;
import java.net.SocketAddress; import static org.rx.common.Contract.require; public final class ProxyServer extends Disposable {
public static final String Compression_Key = "app.netProxy.compression";
public static final String ListenBlock_Key = "app.netProxy.listenBlock";
private EventLoopGroup group;
private boolean enableSsl; public boolean isEnableSsl() {
return enableSsl;
} public void setEnableSsl(boolean enableSsl) {
this.enableSsl = enableSsl;
} public boolean isEnableCompression() {
return App.convert(App.readSetting(Compression_Key), boolean.class);
} public boolean isListening() {
return group != null;
} private boolean isListenBlock() {
return App.convert(App.readSetting(ListenBlock_Key), boolean.class);
} @Override
protected void freeObjects() {
if (group != null) {
group.shutdownGracefully();
}
} public void start(int localPort, SocketAddress directAddress) {
start(new InetSocketAddress(Sockets.AnyAddress, localPort), directAddress);
} @SneakyThrows
public void start(SocketAddress localAddress, SocketAddress directAddress) {
checkNotClosed();
require(group == null);
require(localAddress); // Configure SSL.
SslContext sslCtx = null;
if (enableSsl) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
} ServerBootstrap b = new ServerBootstrap();
SslContext ssl = sslCtx;
b.group(group = new NioEventLoopGroup()).channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
if (ssl != null) {
pipeline.addLast(ssl.newHandler(ch.alloc()));
}
if (isEnableCompression()) {
// Enable stream compression (you can remove these two if unnecessary)
pipeline.addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
pipeline.addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
} // Add the number codec first,
pipeline.addLast(new ByteArrayDecoder());
pipeline.addLast(new ByteArrayEncoder()); // and then business logic.
// Please note we create a handler for every new channel because it has stateful properties.
pipeline.addLast(new DirectServerHandler(enableSsl, directAddress));
}
});
ChannelFuture f = b.bind(localAddress).sync();
if (isListenBlock()) {
f.channel().closeFuture().sync();
}
} public void closeClients() {
checkNotClosed();
if (group == null) {
return;
} group.shutdownGracefully();
group = null;
}
}

java proxy 转包的更多相关文章

  1. 深入理解Java Proxy

    深入理解Java Proxy: http://blog.csdn.net/rokii/article/details/4046098 整理之后的代码: package com.stono.reftes ...

  2. Java Proxy和CGLIB动态代理原理

    动态代理在Java中有着广泛的应用,比如Spring AOP,Hibernate数据查询.测试框架的后端mock.RPC,Java注解对象获取等.静态代理的代理关系在编译时就确定了,而动态代理的代理关 ...

  3. 动态代理:JDK原生动态代理(Java Proxy)和CGLIB动态代理原理+附静态态代理

    本文只是对原文的梳理总结,以及自行理解.自己总结的比较简单,而且不深入,不如直接看原文.不过自己梳理一遍更有助于理解. 详细可参考原文:http://www.cnblogs.com/Carpenter ...

  4. java Proxy InvocationHandler 动态代理实现详解

    spring 两大思想,其一是IOC,其二就是AOP..而AOP的原理就是java 的动态代理机制.这里主要记录java 动态代理的实现及相关类的说明. java  动态代理机制依赖于Invocati ...

  5. java Proxy(代理机制)

    我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习 ...

  6. Set Java Proxy for Http/Https

     Command Line JVM Settings The proxy settings are given to the JVM via command line arguments: java ...

  7. 深入理解Java Proxy机制(转)

    动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组 ...

  8. Java Proxy

    Client---->Interface A --        -- 代理类     Class AImpl 代理类是动态生成的,借助Proxy类和InvocationHandler接口进行实 ...

  9. 几个java proxy servlet 工具

    HTTP-Proxy-Servlet 这个工具使用比较简单,可以通过配置,或者代码的方式 https://github.com/mitre/HTTP-Proxy-Servlet servlet 配置方 ...

随机推荐

  1. HTTP 方法:Get与Post分析

    GET - 从指定的资源请求数据 POST - 向指定的资源提交要被处理的数据 GET 方法 GET 请求可被缓存 GET 请求保留在浏览器历史记录中 GET 请求可被收藏为书签 GET 请求不应在处 ...

  2. hadoop搭建笔记(一)

    环境:mac/linux hadoop版本:3.1.1 安装特性:非HA 准备: 1. jdk8以上 2. ssh 3. 下载hadoop安装包 配置文件,这里都只有简易配置: 1. core-sit ...

  3. 如何只安装Postgresql client(以9.4 为例)

    Install the repository RPM: yum install https://download.postgresql.org/pub/repos/yum/9.4/redhat/rhe ...

  4. .Net Core文件上传

    https://www.cnblogs.com/viter/p/10074766.html 1.内置了很多种绑定模型  缺少了一个FromFileAttribute 绑定模型 需要自己实现一个 pub ...

  5. CSS3 3D图片立方体旋转

    html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...

  6. android------个人项目(歆语气象通新版)

    歆语气象通: 歆语气象伴随你的身边,便捷生活. 包含了以下功能: 1. 天气预报数据覆盖中国城市和地区:2. 提供一周天气预报及最低最高温度,时刻关注天气,轻松计划出行:3. 各种指数详细信息,如太阳 ...

  7. activiti-用户与用户组

    https://my.oschina.net/acitiviti/blog/283892 activiti学习笔记3-用户与用户组 收藏 安世博 发表于 3年前 阅读 5507 收藏 10 点赞 0 ...

  8. FPM五:拆解前面的四——OVP做查询和结果

    说明:前面的例子是将list和search放到一个Feeder Class里的,这里来做拆解分步说明. 1.创建SEARCH的结构 2.创建RESULT的结构 表类型(不用表类型的话,需要自己在cla ...

  9. 移动端最强适配(rem适配之px2rem)&& 移动端结合Vuex实现简单loading加载效果

    一.rem之px2rem适配 前言:相信许多小伙伴上手移动端时面对各式各样的适配方案,挑选出一个自己觉得简便.实用.高效的适配方案是件很纠结的事情. 深有体会... 经过多个移动端项目从最初的 vie ...

  10. idea函数被调用

    打开一个复杂的程序或者项目进行分析的时候,我们就需要知道一个方法在哪里被调用,用于迅速厘清代码逻辑.操作如下:选中函数,右键,点击Find Usages. 如图: 操作简单,但右键还是没有快捷键方便. ...