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. Antd-Pro2.0版本如何修改代理,让Mock变为真实服务器接口

    Antd-pro2.0之前更改代理方式 更改.roadhogrc.mock.js export default { 'GET /api/*': 'http://localhost:8001/', 'P ...

  2. java导出excel 浏览器直接下载或者或以文件形式导出

    /** * excel表格直接下载 */ public static void exportExcelByDownload(HSSFWorkbook wb,HttpServletResponse ht ...

  3. vue实现实时监听文本框内容的变化(最后一种为原生js)

    一.用watch方法监听这个变量. <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  4. xls文件导入数据库

     protected void btn_ok_Click(object sender, EventArgs e)     {         int num = 0;                  ...

  5. 雷林鹏分享:jQuery EasyUI 数据网格 - 动态改变列

    jQuery EasyUI 数据网格 - 动态改变列 数据网格(DataGrid)列可以使用 'columns' 属性简单地定义.如果您想动态地改变列,那根本没有问题.为了改变列,您可以重新调用dat ...

  6. python多线程采集

    import requests import json import threading Default_Header = { #具体请求头自己去弄 } _session=requests.sessi ...

  7. PHP获取POST的几种方法

    一.PHP获取POST数据的几种方法 方法1.最常见的方法是:$_POST['fieldname'];说明:只能接收Content-Type: application/x-www-form-urlen ...

  8. redis单线程为什么速度那么快?

    1.redis是存储在内存上的,读写的话不会受到硬盘 I/O 速度的限制 如图: (1).硬盘数据库的工作模式: (2).内存数据库的工作模式 2.数据结构简单,对数据操作也简单 3.多路IO复用模型 ...

  9. springcloud-spring cloud config统一配置中心

    统一配置中心 为什么需要统一配置中心? 统一配置中心顾名思义,就是将配置统一管理,配置统一管理的好处是在日后大规模集群部署服务应用时相同的服务配置一致,日后再修改配置只需要统一修改全部同步,不需要一个 ...

  10. 学习PYTHON之路, DAY 9 - Socket网络编程

    __import__ 两种方法,官方推荐下面的方法 Socket 参数介绍 sk.bind(address) 必会 s.bind(address) 将套接字绑定到地址.address地址的格式取决于地 ...