001    package org.granite.gravity.websocket;
002    
003    import java.io.IOException;
004    import java.nio.ByteBuffer;
005    import java.nio.channels.ClosedByInterruptException;
006    import java.nio.channels.ServerSocketChannel;
007    import java.nio.channels.SocketChannel;
008    
009    import org.granite.logging.Logger;
010    
011    
012    public 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    }