annotate src/IOHandler.java @ 3:fe4469e7915a default tip

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