StringHandler.java
4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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);
}
}
}