0
|
1 import java.io.IOException;
|
|
2 import java.nio.ByteBuffer;
|
|
3 import java.nio.ByteOrder;
|
|
4 import java.nio.channels.SelectionKey;
|
|
5 import java.nio.channels.SocketChannel;
|
|
6 import java.security.MessageDigest;
|
|
7 import java.security.NoSuchAlgorithmException;
|
|
8 import java.util.HashMap;
|
|
9 import java.util.regex.Matcher;
|
|
10 import java.util.regex.Pattern;
|
|
11
|
|
12
|
|
13 public class IOHandler implements Handler {
|
|
14 public static int BUFFERSIZE = 8192;
|
|
15 public HashMap<String, String> map = new HashMap<String, String>();
|
|
16
|
|
17 @Override
|
|
18 public void handle(SelectionKey key) {
|
|
19 if (!key.isReadable())
|
|
20 return;
|
|
21 SocketChannel sChannel = (SocketChannel)key.channel();
|
|
22 ByteBuffer buffer = ByteBuffer.allocate(BUFFERSIZE);
|
|
23 try {
|
|
24 int num;
|
|
25 if ((num = sChannel.read(buffer)) > 0) {
|
1
|
26 String str = new String(buffer.array(), 0, num - 8);
|
|
27 Pattern pat = Pattern.compile("((([^\n\r:]+): ([^\n\r]+))|(^GET ([^ \n\r]+) HTTP/1.1))");
|
0
|
28 Matcher mat = pat.matcher(str);
|
|
29 while (mat.find()) {
|
|
30 if (mat.group(6) != null) {
|
|
31 map.put("path", mat.group(6));
|
|
32 }
|
|
33 if (mat.group(3) != null && mat.group(4) != null) {
|
|
34 map.put(mat.group(3), mat.group(4));
|
|
35 }
|
|
36 }
|
|
37 buffer.position(num - 8);
|
|
38 byte[] key3 = new byte[8];
|
|
39 buffer.get(key3);
|
|
40 byte[] resCode = generateResponseCode(key3);
|
|
41 ByteBuffer response = generateResponse(resCode);
|
|
42 sChannel.write(response);
|
|
43 System.out.println("sent response");
|
|
44 }
|
|
45 } catch (IOException e) {
|
|
46 e.printStackTrace();
|
|
47 }
|
|
48 }
|
|
49
|
|
50 private ByteBuffer generateResponse(byte[] resCode) {
|
|
51 ByteBuffer response = ByteBuffer.allocate(BUFFERSIZE);
|
|
52 response.put("HTTP/1.1 101 WebSocket Protocol Handshake\r\n".getBytes());
|
|
53 response.put("Upgrade: WebSocket\r\n".getBytes());
|
|
54 response.put("Connection: ".getBytes());
|
|
55 response.put(map.get("Connection").getBytes());
|
|
56 response.put("\r\n".getBytes());
|
|
57 response.put("Sec-WebSocket-Origin: ".getBytes());
|
|
58 response.put(map.get("Origin").getBytes());
|
|
59 response.put("\r\n".getBytes());
|
|
60 response.put("Sec-WebSocket-Location: ".getBytes());
|
|
61 response.put(generateWebSocketAddress(map.get("Origin"), map.get("path")).getBytes());
|
|
62 response.put("\r\n".getBytes());
|
|
63 String s;
|
|
64 if ((s = map.get("Sec-WebSocket-Protocol")) != null) {
|
|
65 response.put("Sec-WebSocket-Protocol: ".getBytes());
|
|
66 response.put(s.getBytes());
|
|
67 response.put("\r\n".getBytes());
|
|
68 }
|
|
69 response.put("\r\n".getBytes());
|
|
70 response.put(resCode);
|
|
71 //response.put("\r\n".getBytes());
|
|
72 response.limit(response.position());
|
|
73 response.rewind();
|
|
74 return response;
|
|
75 }
|
|
76
|
|
77 private String generateWebSocketAddress(String origin, String path) {
|
|
78 return origin.replaceAll("https*", "ws") + ":" + WebSocketServer.port + path;
|
|
79 }
|
|
80
|
|
81 private byte[] generateResponseCode(byte[] key3) {
|
|
82 int val1 = generateResponseCodeValue(map.get("Sec-WebSocket-Key1"));
|
|
83 int val2 = generateResponseCodeValue(map.get("Sec-WebSocket-Key2"));
|
|
84 ByteBuffer buf = ByteBuffer.allocate(16);
|
|
85 buf.order(ByteOrder.BIG_ENDIAN);
|
|
86 buf.putInt(val1);
|
|
87 buf.putInt(val2);
|
|
88 buf.put(key3);
|
|
89 byte[] code = null;
|
|
90 try {
|
|
91 MessageDigest digest = MessageDigest.getInstance("MD5");
|
|
92 code = digest.digest(buf.array());
|
|
93 } catch (NoSuchAlgorithmException e) {
|
|
94 e.printStackTrace();
|
|
95 }
|
|
96 return code;
|
|
97 }
|
|
98
|
|
99 private int generateResponseCodeValue(String str) {
|
|
100 char[] ch = str.toCharArray();
|
1
|
101 long val = 0;
|
0
|
102 int spNum = 0;
|
|
103 for (char c : ch) {
|
|
104 if (c == ' ') {
|
|
105 spNum++;
|
|
106 } else if ('0' <= c && c <= '9') {
|
|
107 val *= 10;
|
|
108 val += c - '0';
|
|
109 }
|
|
110 }
|
1
|
111 return (int) (val / spNum);
|
0
|
112 }
|
|
113 }
|