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 }