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}