import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.socks.; import io.netty.handler.codec.http.*;

public class Socks5Server { private static ServerBootstrap serverBootstrap = new ServerBootstrap(); private static SocksInsideChannelInitializer channelInitializer = new SocksInsideChannelInitializer();

public static void main(String[] args) throws Exception {

    NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
    NioEventLoopGroup workerGroup = new NioEventLoopGroup();
    serverBootstrap.channel(NioServerSocketChannel.class);
    serverBootstrap.group(bossGroup, workerGroup);
    serverBootstrap.childHandler(channelInitializer);
    serverBootstrap.bind(52007).addListener(new GenericFutureListener<Future<? super Void>>() {
        @Override
        public void operationComplete(Future<? super Void> future) throws Exception {
            System.out.println('socks-inside-server started, listening port: ' + 52007);
        }
    });
}

private static class SocksInsideChannelInitializer extends ChannelInitializer<Channel> {
    private Socks5ProcessServerHandler socksProxyProcessHandler = new Socks5ProcessServerHandler();
    @Override
    protected void initChannel(Channel ch) throws Exception {
        ch.pipeline().addLast(new SocksInitRequestDecoder());
        ch.pipeline().addLast(new SocksMessageEncoder());
        ch.pipeline().addLast(socksProxyProcessHandler);
    }
}

}

@ChannelHandler.Sharable class Socks5ProcessServerHandler extends SimpleChannelInboundHandler{

@Override
protected void channelRead0(ChannelHandlerContext ctx, SocksRequest msg) throws Exception {
    System.out.println(msg.requestType());

    switch (msg.requestType()) {
        case INIT:
            ctx.pipeline().addFirst(new SocksCmdRequestDecoder());
            ctx.writeAndFlush(new SocksInitResponse(SocksAuthScheme.NO_AUTH));
            break;
        case AUTH:
            ctx.pipeline().addFirst(new SocksCmdRequestDecoder());
            ctx.writeAndFlush(new SocksAuthResponse(SocksAuthStatus.SUCCESS));
            break;
        case CMD:
            SocksCmdRequest req = (SocksCmdRequest) msg;
            System.out.println(req.cmdType());
            if (req.cmdType() == SocksCmdType.CONNECT) {
                ctx.pipeline().addLast(new SocksServerHandler());
                ctx.pipeline().remove(this);
                ctx.fireChannelRead(msg);
            } else {
                ctx.close();
            }
            break;
        case UNKNOWN:
            ctx.close();
            break;
        default:
            ctx.close();
            break;
    }
}

}

@ChannelHandler.Sharable class SocksServerHandler extends SimpleChannelInboundHandler {

@Override
protected void channelRead0(final ChannelHandlerContext browserCtx, final SocksCmdRequest msg) throws Exception {

	if (msg.host() == null || msg.host().isEmpty()) {
		browserCtx.close();
		return;
	}
	browserCtx.pipeline().remove(this);
	browserCtx.pipeline().addLast(new SocksHandler(browserCtx, msg));
	browserCtx.channel().writeAndFlush(new SocksCmdResponse(SocksCmdStatus.SUCCESS, SocksAddressType.IPv4));

}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    if (ctx.channel().isActive()) {
    	ctx.channel().close();
    }
}

private class SocksHandler extends ChannelInboundHandlerAdapter {
	
	private ChannelHandlerContext browserCtx;
	private SocksCmdRequest req;
	
	public SocksHandler(ChannelHandlerContext browserCtx, SocksCmdRequest req) {
		this.browserCtx = browserCtx;
		this.req = req;
	}

	@Override
    public void channelRead(ChannelHandlerContext outsideProxyCtx, Object msg) throws Exception {
		System.out.println(req.host());
		System.out.println(req.port());
		System.out.println(msg);
		// 处理HTTP请求
		if (msg instanceof FullHttpRequest) {
			FullHttpRequest request = (FullHttpRequest) msg;
			if (request.decoderResult().isSuccess()) {
				// 获取请求的信息
				String method = request.method().name();
				String uri = request.uri();
				String version = request.protocolVersion().text();
				System.out.println('HTTP Request: ' + method + ' ' + uri + ' ' + version);
				// 返回响应
				String response = 'Hello World!';
				FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
							HttpResponseStatus.OK, Unpooled.wrappedBuffer(response.getBytes()));
				httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, 'text/plain');
				httpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, httpResponse.content().readableBytes());
				outsideProxyCtx.writeAndFlush(httpResponse);
			} else {
				browserCtx.close();
			}
		}
	}

}

}

Java Netty 实现 SOCKS5 代理服务器:获取浏览器请求信息并返回响应

原文地址: https://www.cveoy.top/t/topic/oadF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录