Mercurial > hg > Members > kazz > WebSocket
view src/IOHandler.java @ 2:d5d2ca53a832
dealed dispose of connection close
author | kazz |
---|---|
date | Sat, 22 Jan 2011 05:30:20 +0900 |
parents | 4c2ddaa9b998 |
children | fe4469e7915a |
line wrap: on
line source
import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; public class IOHandler implements Handler { public static int BUFFERSIZE = 8192; public HashMap<String, String> map = new HashMap<String, String>(); @Override public void handle(SelectionKey key) { if (!key.isReadable()) { key.selector().keys().remove(key); return; } SocketChannel sChannel = (SocketChannel)key.channel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFERSIZE); try { int num; if ((num = sChannel.read(buffer)) > 0) { String str = new String(buffer.array(), 0, num - 8); Pattern pat = Pattern.compile("((([^\n\r:]+): ([^\n\r]+))|(^GET ([^ \n\r]+) HTTP/1.1))"); Matcher mat = pat.matcher(str); while (mat.find()) { if (mat.group(6) != null) { map.put("path", mat.group(6)); } if (mat.group(3) != null && mat.group(4) != null) { map.put(mat.group(3), mat.group(4)); } } buffer.position(num - 8); byte[] key3 = new byte[8]; buffer.get(key3); byte[] resCode = generateResponseCode(key3); ByteBuffer response = generateResponse(resCode); sChannel.write(response); System.out.println("sent response"); } } catch (IOException e) { e.printStackTrace(); } } private ByteBuffer generateResponse(byte[] resCode) { ByteBuffer response = ByteBuffer.allocate(BUFFERSIZE); response.put("HTTP/1.1 101 WebSocket Protocol Handshake\r\n".getBytes()); response.put("Upgrade: WebSocket\r\n".getBytes()); response.put("Connection: ".getBytes()); response.put(map.get("Connection").getBytes()); response.put("\r\n".getBytes()); response.put("Sec-WebSocket-Origin: ".getBytes()); response.put(map.get("Origin").getBytes()); response.put("\r\n".getBytes()); response.put("Sec-WebSocket-Location: ".getBytes()); response.put(generateWebSocketAddress(map.get("Origin"), map.get("path")).getBytes()); response.put("\r\n".getBytes()); String s; if ((s = map.get("Sec-WebSocket-Protocol")) != null) { response.put("Sec-WebSocket-Protocol: ".getBytes()); response.put(s.getBytes()); response.put("\r\n".getBytes()); } response.put("\r\n".getBytes()); response.put(resCode); //response.put("\r\n".getBytes()); response.limit(response.position()); response.rewind(); return response; } private String generateWebSocketAddress(String origin, String path) { return origin.replaceAll("https*", "ws") + ":" + WebSocketServer.port + path; } private byte[] generateResponseCode(byte[] key3) { int val1 = generateResponseCodeValue(map.get("Sec-WebSocket-Key1")); int val2 = generateResponseCodeValue(map.get("Sec-WebSocket-Key2")); ByteBuffer buf = ByteBuffer.allocate(16); buf.order(ByteOrder.BIG_ENDIAN); buf.putInt(val1); buf.putInt(val2); buf.put(key3); byte[] code = null; try { MessageDigest digest = MessageDigest.getInstance("MD5"); code = digest.digest(buf.array()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return code; } private int generateResponseCodeValue(String str) { char[] ch = str.toCharArray(); long val = 0; int spNum = 0; for (char c : ch) { if (c == ' ') { spNum++; } else if ('0' <= c && c <= '9') { val *= 10; val += c - '0'; } } return (int) (val / spNum); } }