StringHandler.java 4.5 KB
package org.shadowsocks.handler.server;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import org.shadowsocks.crypto.SSCrypto;
import org.shadowsocks.dto.RequestInfo;
import org.shadowsocks.dto.RequestMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;

import static org.shadowsocks.dto.RequestMethod.CONNECT;

public class StringHandler extends ChannelInboundHandlerAdapter {
    private static Logger logger = LoggerFactory.getLogger(StringHandler.class);
    private final ByteBuf dataQueue = Unpooled.buffer();
    private final SSCrypto ssCrypto;
    public StringHandler(SSCrypto ssCrypto) {
        this.ssCrypto = ssCrypto;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        logger.info("connected with {}", ctx.channel());
    }


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

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("disconnected with {}", ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buff = (ByteBuf) msg;
        if (buff.readableBytes() <= 0) {
            return;
        }
        byte [] array = ByteBufUtil.getBytes(buff);
        logger.info("请求内容\n{}\n{}",msg.getClass(),new String(array));

        dataQueue.writeBytes(array);
        if (dataQueue.readableBytes() < 2) {
            return;
        }
        byte[] ats = ByteBufUtil.getBytes(dataQueue.slice(dataQueue.readerIndex(),dataQueue.bytesBefore((byte) ' ')));
        String addressType = new String(ats);
        RequestInfo requestInfo =  getRequestInfo(RequestMethod.valueOf(addressType));
        if(null != requestInfo)
        {
            ctx.channel().pipeline().addLast(new ClientDataHandler(requestInfo.getHost(), requestInfo.getPost(), ctx, buff,ssCrypto));
            ctx.channel().pipeline().remove(this);
        }else{
            rterre(ctx,"没有解析到头部信息");
        }

    }

    private void rterre(ChannelHandlerContext ctx,String message)
    {
        //构造内容
        ByteBuf context = Unpooled.copiedBuffer(message, CharsetUtil.UTF_8);

        //设置 response
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                context);

        //构建 响应头
        HttpHeaders headers = response.headers();
        headers.set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=utf-8");
        headers.set(HttpHeaderNames.CONTENT_LENGTH, context.readableBytes());

        //将消息返回
        ctx.channel().writeAndFlush(response);
    }

    private RequestInfo getRequestInfo(RequestMethod requestMethod) throws UnknownHostException {
        switch (requestMethod)
        {
            case CONNECT:
                if (dataQueue.readableBytes() < 7) {
                    return null;
                }
                // addrType(7) + ipv4(4) + port(2)
                dataQueue.readerIndex(7);
                dataQueue.readUnsignedByte();
                int index = dataQueue.bytesBefore((byte) ' ');
                byte[] ats = new byte[index];
                dataQueue.readBytes(ats);
                String[] addresAndPost = new String(ats).split(":");
                dataQueue.readUnsignedByte();
                return new RequestInfo(addresAndPost[0],Integer.parseInt(addresAndPost[1]));
//            case ADDR_TYPE_HOST:
//                int hostLength = dataQueue.getUnsignedByte(1);
//                if (dataQueue.readableBytes() < hostLength + 4) {
//                    return null;
//                }
//                dataQueue.readUnsignedByte();
//                dataQueue.readUnsignedByte();
//                byte[] hostBytes = new byte[hostLength];
//                dataQueue.readBytes(hostBytes);
//                return new RequestInfo(new String(hostBytes),dataQueue.readShort());
            default:
                throw new IllegalStateException("unknown address type: " + requestMethod);
        }
    }
}