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. three.js初探,立体几何入手(一)

    前言:首先先推荐一篇博客,关于webgl原理,讲的非常之通俗易懂了 图解WebGL&Three.js工作原理  webGL可以理解为openGL ES2.0 (webGL2.0 - openG ...

  2. 用JSON.stringify处理循环引用对象

    通常,我们会用JSON.stringify把Javascript对象序列化成JSON格式,这在大多数情况下是够用的.但是,当你要转换的对象里存在循环引用时,问题就来了. js对象循环引用导致内存泄漏 ...

  3. Lombok之使用详解

    前言 在Java中,封装是一个非常好的机制,最常见的封装莫过于get,set方法了,无论是Intellij idea 还是Eclipse,都提供了快速生成get,set方法的快捷键,使用起来很是方便, ...

  4. ape 文件 转化为mp3 文件

    试了很多软件,最后才发觉 any-audio-converter最好用. 可以吧ape 按 cue切割好,然后转化成 MP3 官网可以免费下载: https://www.any-audio-conve ...

  5. python - xml转excel

    xml转excel,可以用xml.etree.ElementTree去解析xml文件,然后用xlwt写入excel 示例:ConvConfig.xml <Conveyor_Channel_1&g ...

  6. python爬取某站磁力链

    不同磁力链网站网页内容都不同,需要定制 1,并发爬取 并发爬取后,好像一会就被封了 import requests from lxml import etree import re from conc ...

  7. 同一个世界(erlang解题答案)

    最近玩同一个世界,才几关就把3次提示用完了,十分气愤, 于是写了程序来解~~~ o(^▽^)o 以2-1为例子,题目如下 以0代表白色,1代表黑色,抽象的就是这样的 ----------------- ...

  8. RecyclerView嵌套ScrollView导致RecyclerView内容显示不全

    我们在使用RecyclerView嵌套至ScrollView内的时候 RecyclerView不在屏幕内的数据会不显示出来,这里是一个坑,我们需要重写RecyclerView /** * Create ...

  9. C# WPF开发之MVVM模式开发

    MVVM模式由Model,View,ViewModel三部分组成. Model需继承INotifyPropertyChange(属性修改通知) ViewModel负责业务逻辑,连接View和Model ...

  10. python 做接口自动化测试框架设计

    1,明确什么叫自动化测试,什么叫接口自动化测试,如何设计接口测试用例,已登录为例 自动化测试:解放人力来自动完成规定的测试. 自动化测试分层模型:UI层,不论WEB端还是移动端,都是基于页面元素的识别 ...