001package org.granite.gravity.websocket; 002 003import java.io.IOException; 004import java.nio.ByteBuffer; 005import java.nio.channels.ClosedByInterruptException; 006import java.nio.channels.ServerSocketChannel; 007import java.nio.channels.SocketChannel; 008 009import org.granite.logging.Logger; 010 011 012public class PolicyFileServer implements Runnable { 013 014 private static final Logger log = Logger.getLogger(PolicyFileServer.class); 015 016 017 private int serverPort = 843; 018 private String[] allowDomains = {}; 019 private String[] allowPorts = {}; 020 private Thread policyServer = null; 021 022 public void setServerPort(int serverPort) { 023 this.serverPort = serverPort; 024 } 025 026 public void setAllowDomains(String[] domains) { 027 this.allowDomains = domains; 028 } 029 030 public void setAllowPorts(String[] ports) { 031 this.allowPorts = ports; 032 } 033 034 public void start() { 035 policyServer = new Thread(this, "FlashPolicyFileServer:" + serverPort); 036 policyServer.start(); 037 } 038 039 public void stop() { 040 if (policyServer != null) 041 policyServer.interrupt(); 042 } 043 044 public void run() { 045 ServerSocketChannel server = null; 046 try { 047 server = ServerSocketChannel.open(); 048 server.socket().bind(new java.net.InetSocketAddress(serverPort)); 049 log.info("Flash socket policy server started on port " + serverPort); 050 } 051 catch (IOException e) { 052 log.error(e, "Could not init flash socket policy server on port " + serverPort); 053 return; 054 } 055 while (true) { 056 SocketChannel socket = null; 057 try { 058 socket = server.accept(); 059 060 ByteBuffer buf = ByteBuffer.allocate(100); 061 int size = socket.read(buf); 062 if (size == 23) { 063 byte[] req = new byte[size]; 064 buf.get(req, 0, size); 065 String request = new String(req, "UTF-8"); 066 067 log.info("Received policy file request %s", request); 068 069 String policyFile = "<?xml version=\"1.0\"?>\n" 070 + "<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">" 071 + "<cross-domain-policy>"; 072 for (int i = 0; i < allowDomains.length; i++) 073 policyFile += " <allow-access-from domain=\"" + allowDomains[i] + "\" to-ports=\"" + allowPorts[i] + "\"/>"; 074 policyFile += "</cross-domain-policy>"; 075 byte[] bytes = policyFile.getBytes("UTF-8"); 076 077 socket.write(ByteBuffer.wrap(bytes)); 078 } 079 } 080 catch (ClosedByInterruptException e) { 081 log.info("Flash socket policy server stopped"); 082 break; 083 } 084 catch (IOException e) { 085 log.error(e, "Could not send policy file"); 086 } 087 finally { 088 if (socket != null) { 089 try { 090 socket.close(); 091 } 092 catch (IOException e) { 093 log.error(e, "Could not close socket"); 094 } 095 } 096 } 097 } 098 } 099 100}