All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xin.alum.aim.server.PortUnificationHandshake Maven / Gradle / Ivy

There is a newer version: 1.9.6
Show newest version
package xin.alum.aim.server;

import xin.alum.aim.AIM;
import xin.alum.aim.config.DataAgreement;
import xin.alum.aim.socks.SocksServerHandler;
import xin.alum.aim.socks.SocksServerInitializer;
import xin.alum.aim.websocks.WebSocketServerInitializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

import java.util.List;

/**
 * 统一端口服务处理器[协议握手]
 * 

* 使用同一个端口去处理TCP/HTTP协议的请求,因为HTTP的底层协议也是TCP,因此可以在此处理器内部可以通过解析部分数据 * 来判断请求是TCP请求还是HTTP请求,然使用动态的pipeline切换 * * @author Succy * create on 2020/11/19 */ public class PortUnificationHandshake extends ByteToMessageDecoder { private static final InternalLogger logger = InternalLoggerFactory.getInstance(PortUnificationHandshake.class); @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { // Will use the first five bytes to detect a protocol. if (in.readableBytes() < 4) { return; } final int magic1 = in.getUnsignedByte(in.readerIndex()); final int magic2 = in.getUnsignedByte(in.readerIndex() + 1); ChannelPipeline p = ctx.pipeline(); // 判断是不是HTTP请求 if (isHttp(magic1, magic2)) { WebSocketServerInitializer.InitWebSocket(p); } else if (AIM.request.onHandShake(ctx.channel(), in)) {//TCP协议握手成功 //1、走TCP解码,协议握手 in.markReaderIndex(); in.readerIndex(in.readableBytes() >= 5 ? 1 : 0); int agreement = in.readInt(); DataAgreement dataAgreement = DataAgreement.valueOf(agreement); SocksServerInitializer.InitSocket(p, dataAgreement); //2、走YML配置约定协议,生产环境启用 // dataAgreement = AIM.properties.getAgreement();//使用配置商定协议 // SocksServerInitializer.InitSocket(p, dataAgreement); // ctx.fireChannelRead(in.retain());//使用配置商定协议 } // 将自身移除掉 p.remove(this); } /** * 判断请求是否是HTTP请求 * * @param magic1 报文第一个字节 * @param magic2 报文第二个字节 * @return */ private boolean isHttp(int magic1, int magic2) { return magic1 == 'G' && magic2 == 'E' || // GET magic1 == 'P' && magic2 == 'O' || // POST magic1 == 'P' && magic2 == 'U' || // PUT magic1 == 'H' && magic2 == 'E' || // HEAD magic1 == 'O' && magic2 == 'P' || // OPTIONS magic1 == 'P' && magic2 == 'A' || // PATCH magic1 == 'D' && magic2 == 'E' || // DELETE magic1 == 'T' && magic2 == 'R' || // TRACE magic1 == 'C' && magic2 == 'O'; // CONNECT } }