1 package com.foxinmy.weixin4j.socket;
2
3 import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
4 import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
5 import static io.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED;
6
7 import com.foxinmy.weixin4j.dispatcher.WeixinMessageDispatcher;
8 import com.foxinmy.weixin4j.request.WeixinRequest;
9 import com.foxinmy.weixin4j.response.SingleResponse;
10 import com.foxinmy.weixin4j.type.EncryptType;
11 import com.foxinmy.weixin4j.util.AesToken;
12 import com.foxinmy.weixin4j.util.HttpUtil;
13 import com.foxinmy.weixin4j.util.MessageUtil;
14 import com.foxinmy.weixin4j.util.ServerToolkits;
15
16 import io.netty.channel.ChannelFutureListener;
17 import io.netty.channel.ChannelHandlerContext;
18 import io.netty.channel.SimpleChannelInboundHandler;
19 import io.netty.handler.codec.http.DefaultFullHttpResponse;
20 import io.netty.handler.codec.http.FullHttpResponse;
21 import io.netty.handler.codec.http.HttpMethod;
22 import io.netty.handler.codec.http.HttpResponseStatus;
23 import io.netty.util.internal.logging.InternalLogger;
24 import io.netty.util.internal.logging.InternalLoggerFactory;
25
26
27
28
29
30
31
32
33
34
35 public class WeixinRequestHandler extends SimpleChannelInboundHandler<WeixinRequest> {
36 private final InternalLogger logger = InternalLoggerFactory.getInstance(getClass());
37
38 private final WeixinMessageDispatcher messageDispatcher;
39
40 public WeixinRequestHandler(WeixinMessageDispatcher messageDispatcher) {
41 this.messageDispatcher = messageDispatcher;
42 }
43
44 public void channelReadComplete(ChannelHandlerContext ctx) {
45 ctx.flush();
46 }
47
48 @Override
49 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
50 ctx.close();
51 logger.error(cause);
52 }
53
54 @Override
55 protected void channelRead0(ChannelHandlerContext ctx, WeixinRequest request) {
56 AesToken aesToken = request.getAesToken();
57
58 if (aesToken == null || (ServerToolkits.isBlank(request.getSignature())
59 && ServerToolkits.isBlank(request.getMsgSignature()))) {
60 ctx.writeAndFlush(resolveResponse(BAD_REQUEST, request)).addListener(ChannelFutureListener.CLOSE);
61 return;
62 }
63
64
65
66
67
68 if (request.getMethod() == HttpMethod.GET) {
69
70 if (!ServerToolkits.isBlank(request.getSignature())
71 && MessageUtil.signature(aesToken.getToken(), request.getTimeStamp(), request.getNonce())
72 .equals(request.getSignature())) {
73 ctx.writeAndFlush(new SingleResponse(request.getEchoStr()));
74 return;
75 }
76
77 if (!ServerToolkits.isBlank(request.getMsgSignature()) && MessageUtil
78 .signature(aesToken.getToken(), request.getTimeStamp(), request.getNonce(), request.getEchoStr())
79 .equals(request.getMsgSignature())) {
80 ctx.writeAndFlush(
81 new SingleResponse(MessageUtil.aesDecrypt(null, aesToken.getAesKey(), request.getEchoStr())));
82 return;
83 }
84 ctx.writeAndFlush(resolveResponse(FORBIDDEN, request)).addListener(ChannelFutureListener.CLOSE);
85 return;
86 } else if (request.getMethod() == HttpMethod.POST) {
87
88 if (!ServerToolkits.isBlank(request.getSignature())
89 && !MessageUtil.signature(aesToken.getToken(), request.getTimeStamp(), request.getNonce())
90 .equals(request.getSignature())) {
91 ctx.writeAndFlush(resolveResponse(FORBIDDEN, request)).addListener(ChannelFutureListener.CLOSE);
92 return;
93 }
94
95 if (request.getEncryptType() == EncryptType.AES
96 && !MessageUtil.signature(aesToken.getToken(), request.getTimeStamp(), request.getNonce(),
97 request.getEncryptContent()).equals(request.getMsgSignature())) {
98 ctx.writeAndFlush(resolveResponse(FORBIDDEN, request)).addListener(ChannelFutureListener.CLOSE);
99 return;
100 }
101 } else {
102
103 ctx.writeAndFlush(resolveResponse(METHOD_NOT_ALLOWED, request)).addListener(ChannelFutureListener.CLOSE);
104 return;
105 }
106 messageDispatcher.doDispatch(ctx, request);
107 }
108
109 private FullHttpResponse resolveResponse(HttpResponseStatus responseStatus, WeixinRequest request) {
110 FullHttpResponse response = new DefaultFullHttpResponse(request.getProtocolVersion(), responseStatus);
111 HttpUtil.resolveHeaders(response);
112 return response;
113 }
114 }