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