<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Coders Like Us &#187; proxy</title>
	<atom:link href="http://coderslike.us/tag/proxy/feed/" rel="self" type="application/rss+xml" />
	<link>http://coderslike.us</link>
	<description>Things I've learned and stuff I'm thinking about.</description>
	<lastBuildDate>Sat, 04 Feb 2012 20:12:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='coderslike.us' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Coders Like Us &#187; proxy</title>
		<link>http://coderslike.us</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://coderslike.us/osd.xml" title="Coders Like Us" />
	<atom:link rel='hub' href='http://coderslike.us/?pushpress=hub'/>
		<item>
		<title>Flash Socket Code and crossdomain Policy Serving</title>
		<link>http://coderslike.us/2009/01/23/flash-socket-code-and-crossdomain-policy-serving/</link>
		<comments>http://coderslike.us/2009/01/23/flash-socket-code-and-crossdomain-policy-serving/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 19:12:10 +0000</pubDate>
		<dc:creator>dkavanagh</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[crossdomain]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[policy]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[socket]]></category>

		<guid isPermaLink="false">http://coderslikeus.wordpress.com/?p=5</guid>
		<description><![CDATA[I&#8217;ve just spent the past day trying to get my flash app talking to another device on my network via socket 23. I found some sample telnet code (which operates on port 23) and allowed me to &#8220;talk&#8221; to the RFID reader. It worked fine as a new project in Flex Builder and being served [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=coderslike.us&amp;blog=6290704&amp;post=5&amp;subd=coderslikeus&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just spent the past day trying to get my flash app talking to another device on my network via socket 23. I found some sample telnet code (which operates on port 23) and allowed me to &#8220;talk&#8221; to the RFID reader. It worked fine as a new project in Flex Builder and being served from a local file. The moment I served the application from a web server (tomcat) on my laptop, I get crossdomain issues. Flash won&#8217;t open a socket that is different from the one that served your application unless that socket authorizes it. I will spare you the details that took many hours of my day. If you&#8217;re trying to talk to another web server on a different port, no problem.. just put the crossdomain.xml file on that server that authorizes the connection. In this case, I was trying to connect to another host and another port (which runs telnet, not http). The RFID reader can&#8217;t be modified to serve up a crossdomain.xml file, so I had to get creative.</p>
<p>My solution was to run a TCP proxy on my web server machine that proxied requests to the RFID reader. I made it listen on port 8023 and forward requests to 23 on the RFID reader. This was the start because I still got errors about that localhost:8023  not being authorized. It turns out that when you try the connection, flash connects to the socket and sends 23 bytes which contain &#8220;&lt;policy-file-request/&gt;&#8221;. Flash expects whatever is running at that port to respond with the policy string (that would have been in the crossdomain.xml file). So, I modified this little proxy class I got off the internet to recognize the proxy request and respond with a proxy string (null terminated.. that is very important!). Once I had this set up right, I was able to communicate from my flash app to my RFID reader. Not the most elegant solution, but this is something temporary for a demo.</p>
<p> </p>
<p>To run the code below, compile with javac and invoke &#8220;java -classpath &lt;class.file.location&gt; ProxyThread 8023 192.168.1.39 23&#8243;. Those options are what I used to talk to my RFID reader, but you&#8217;ll likely use different values.</p>
<pre>import java.net.*;
import java.io.*;
 
/*
  Java Transparent Proxy
  Copyright (C) 1999 by Didier Frick (http://www.dfr.ch/)
  This software is provided under the GNU general public license (http://www.gnu.org/copyleft/gpl.html).
*/

public class ProxyThread extends Thread {
     protected class StreamCopyThread extends Thread {
<span>	</span>private Socket inSock;
<span>	</span>private Socket outSock;
<span>	</span>private boolean done=false;
<span>	</span>private StreamCopyThread peer;
<span>	</span>private boolean inFromLocal;<span>	</span>// in from local port
<span>	</span>private OutputStream out;
 
<span>	</span>private String policy = "&lt;cross-domain-policy&gt;\n&lt;allow-access-from domain=\"*\" to-ports=\"8023\"/&gt;\n&lt;/cross-domain-policy&gt;";
 
<span>	</span>public StreamCopyThread(Socket inSock, Socket outSock, boolean in) {
<span>	</span>    this.inSock=inSock;
<span>	</span>    this.outSock=outSock;
<span>	</span>    this.inFromLocal = in;
<span>	</span>}
 
<span>	</span>public void sendPolicy() {
<span>		</span>try {
<span>			</span>out.write(policy.getBytes());
<span>			</span>System.err.println("Sent policy");
<span>		</span>} catch (IOException ex) {
<span>			</span>System.err.println("Error sending policy file");
<span>		</span>}
<span>	</span>}
 
<span>	</span>public void run() {
<span>	</span>    byte[] buf=new byte[bufSize];
<span>	</span>    int count=-1;
<span>	</span>    try {
<span>		</span>InputStream in=inSock.getInputStream();
<span>		</span>out=outSock.getOutputStream();
<span>		</span>try {
<span>		</span>    while(((count=in.read(buf))&gt;0)&amp;&amp;!isInterrupted()) {
<span>		</span>    <span>	</span>if (inFromLocal &amp;&amp; count==23 &amp;&amp; new String(buf).startsWith("&lt;policy-file-request/&gt;")) {
<span>				</span>// send policy file back.. don't forward this to other port
<span>				</span>System.err.println("Got policy request");
<span>				</span>peer.sendPolicy();
<span>			</span>}
<span>			</span>else {
<span>				</span>out.write(buf,0,count);
<span>				</span>//System.err.println(count+" bytes "+(inFromLocal?"sent":"received"));
<span>			</span>}
<span>		</span>    }
<span>		</span>} catch(Exception xc) {
<span>		</span>    if(debug) {
<span>			</span>// FIXME
<span>			</span>// It's very difficult to sort out between "normal"
<span>			</span>// exceptions (occuring when one end closes the connection
<span>			</span>// normally), and "exceptional" exceptions (when something
<span>			</span>// really goes wrong)
<span>			</span>// Therefore we only log exceptions occuring here if the debug flag
<span>			</span>// is true, in order to avoid cluttering up the log.
<span>			</span>err.println(header+":"+xc);
<span>			</span>xc.printStackTrace();
<span>		</span>    }
<span>		</span>} finally {
<span>		</span>    // The input and output streams will be closed when the sockets themselves
<span>		</span>    // are closed.
<span>		</span>    out.flush();
<span>		</span>}
<span>	</span>    } catch(Exception xc) {
<span>		</span>err.println(header+":"+xc);
<span>		</span>xc.printStackTrace();
<span>	</span>    }
<span>	</span>    synchronized(lock) {
<span>		</span>done=true;
<span>		</span>try {
<span>		</span>    if((peer==null)||peer.isDone()) {
<span>			</span>// Cleanup if there is only one peer OR
<span>			</span>// if _both_ peers are done
<span>			</span>inSock.close();
<span>			</span>outSock.close();
<span>		</span>    }
<span>		</span>    else 
<span>			</span>// Signal the peer (if any) that we're done on this side of the connection
<span>			</span>peer.interrupt();
<span>		</span>} catch(Exception xc) {
<span>		</span>    err.println(header+":"+xc);
<span>		</span>    xc.printStackTrace();
<span>		</span>} finally {
<span>		</span>    connections.removeElement(this);
<span>		</span>}
<span>	</span>    }
<span>	</span>}
 
<span>	</span>public boolean isDone() {
<span>	</span>    return done;
<span>	</span>}
    
<span>	</span>public void setPeer(StreamCopyThread peer) {
<span>	</span>    this.peer=peer;
<span>	</span>}
     }

    // Holds all the currently active StreamCopyThreads
    private java.util.Vector connections=new java.util.Vector();
    // Used to synchronize the connection-handling threads with this thread
    private Object lock=new Object();
    // The address to forward connections to
    private InetAddress dstAddr;
    // The port to forward connections to
    private int dstPort;
    // Backlog parameter used when creating the ServerSocket
    protected static final int backLog=100;
    // Timeout waiting for a StreamCopyThread to finish
    public static final int threadTimeout=2000; //ms
    // Linger time
    public static final int lingerTime=180; //seconds (?)
    // Size of receive buffer
    public static final int bufSize=2048;
    // Header to prepend to log messages
    private String header;
    // This proxy's server socket
    private ServerSocket srvSock;
    // Debug flag
    private boolean debug=false;
 
    // Log streams for output and error messages
    private PrintStream out;
    private PrintStream err;
 
    private static final String 
<span>	</span>argsMessage="Arguments: ( [source_address] source_port dest_address dest_port ) | config_file";
    private static final String 
<span>	</span>propertyPrefix="proxy";

 
    public ProxyThread(InetAddress srcAddr,int srcPort,
<span>		</span>       InetAddress dstAddr,int dstPort, PrintStream out, PrintStream err) 
<span>	</span>throws IOException {
<span>	</span>this.out=out;
<span>	</span>this.err=err;
<span>	</span>this.srvSock=(srcAddr==null) ? new ServerSocket(srcPort,backLog) :  
<span>	</span>    new ServerSocket(srcPort,backLog,srcAddr);
<span>	</span>this.dstAddr=dstAddr;
<span>	</span>this.dstPort=dstPort;
<span>	</span>this.header=(srcAddr==null ? "" : srcAddr.toString())+":"+srcPort+" &lt;-&gt; "+dstAddr+":"+dstPort;
<span>	</span>start();
    }
 
    public void run() {
<span>	</span>out.println(header+" : starting");
<span>	</span>try {
<span>	</span>    while(!isInterrupted()) {
<span>		</span>Socket serverSocket=srvSock.accept();
<span>		</span>try {
<span>		</span>    serverSocket.setSoLinger(true,lingerTime);
<span>		</span>    Socket clientSocket=new Socket(dstAddr,dstPort);
<span>		</span>    clientSocket.setSoLinger(true,lingerTime);
<span>		</span>    StreamCopyThread sToC=new StreamCopyThread(serverSocket,clientSocket, true);
<span>		</span>    StreamCopyThread cToS=new StreamCopyThread(clientSocket,serverSocket, false);
<span>		</span>    sToC.setPeer(cToS);
<span>		</span>    cToS.setPeer(sToC);
<span>		</span>    synchronized(lock) {
<span>			</span>connections.addElement(cToS);
<span>			</span>connections.addElement(sToC);
<span>			</span>sToC.start();
<span>			</span>cToS.start();
<span>		</span>    }
<span>		</span>} catch(Exception xc) {
<span>		</span>    err.println(header+":"+xc);
<span>		</span>    if(debug)
<span>			</span>xc.printStackTrace();
<span>		</span>}
<span>	</span>    }
<span>	</span>    srvSock.close();
<span>	</span>} catch(IOException xc) {
<span>	</span>    err.println(header+":"+xc);
<span>	</span>    if(debug)
<span>		</span>xc.printStackTrace();
<span>	</span>} finally {
<span>	</span>    cleanup();
<span>	</span>    out.println(header+" : stopped");
<span>	</span>}
    }
 
     private void cleanup() {
<span>	</span>synchronized(lock) {
<span>	</span>    try {
<span>		</span>while(connections.size()&gt;0) {
<span>		</span>    StreamCopyThread sct=(StreamCopyThread)connections.elementAt(0);
<span>		</span>    sct.interrupt();
<span>		</span>    sct.join(threadTimeout);
<span>		</span>}
<span>	</span>    } catch(InterruptedException xc) {
<span>	</span>    }
<span>	</span>}
    }
 
    private static ProxyThread addProxy(String src,String srcPort, String dst, String dstPort,
<span>					</span>PrintStream out, PrintStream err) throws
<span>					</span>UnknownHostException, IOException
    {
<span>	</span>InetAddress srcAddr=(src==null) ? null : InetAddress.getByName(src);
<span>	</span>return new ProxyThread(srcAddr,Integer.parseInt(srcPort),
<span>			</span>       InetAddress.getByName(dst),Integer.parseInt(dstPort),out,err);
    }
 
    private static java.util.Vector parseConfigFile(String fileName,PrintStream out,PrintStream err) throws 
        FileNotFoundException, IOException, UnknownHostException
    {
<span>	</span>java.util.Vector result=new java.util.Vector();
<span>	</span>FileInputStream in=new FileInputStream(fileName);
<span>	</span>java.util.Properties props= new java.util.Properties();
<span>	</span>props.load(in);
<span>	</span>in.close();
<span>	</span>for(int i=0;;i++) {
<span>	</span>    String srcAddr=props.getProperty(propertyPrefix+"."+i+".sourceAddr");
<span>	</span>    String srcPort=props.getProperty(propertyPrefix+"."+i+".sourcePort");
<span>	</span>    if(srcPort==null)
<span>		</span>break;
<span>	</span>    String dstAddr=props.getProperty(propertyPrefix+"."+i+".destAddr");
<span>	</span>    String dstPort=props.getProperty(propertyPrefix+"."+i+".destPort");
<span>	</span>    if(dstAddr==null) {
<span>		</span>throw new IllegalArgumentException("Missing destination address for proxy "+i);
<span>	</span>    }
<span>	</span>    if(dstPort==null) {
<span>		</span>throw new IllegalArgumentException("Missing destination port for proxy "+i);
<span>	</span>    }
<span>	</span>    result.addElement(addProxy(srcAddr,srcPort,dstAddr,dstPort,out,err));
<span>	</span>}
<span>	</span>return result;
    }
 
    static java.util.Vector parseArguments(String[] argv,PrintStream out,PrintStream err) throws
        FileNotFoundException, IOException, UnknownHostException
    {
<span>	</span>java.util.Vector result=null;
<span>	</span>int argBase=0;
<span>	</span>String src=null;
<span>	</span>if(argv.length&gt;1) {
<span>	</span>    if(argv.length&gt;3) {
<span>		</span>argBase=1;
<span>		</span>src=argv[0];
<span>	</span>    }
<span>	</span>    result=new java.util.Vector();
<span>	</span>    result.addElement(addProxy(src,argv[argBase++],argv[argBase++],argv[argBase++],out,err));
<span>	</span>} else if(argv.length==1) {
<span>	</span>    result=parseConfigFile(argv[0],out,err);
<span>	</span>} else {
<span>	</span>    throw new IllegalArgumentException(argsMessage);
<span>	</span>}
<span>	</span>return result;
    }
 
    public static void main(String[] argv) throws Exception {
<span>	</span>System.out.println("Java Transparent Proxy");
<span>	</span>System.out.println("Copyright (C) 1999 by Didier Frick (http://www.dfr.ch/)");
<span>	</span>System.out.println("This software is provided under the GNU general public license"+
<span>			</span>   " (http://www.gnu.org/copyleft/gpl.html)");
<span>	</span>try {
<span>	</span>    parseArguments(argv,System.out,System.err);
<span>	</span>} catch(IllegalArgumentException xc) {
<span>	</span>    System.err.println(xc.getMessage());
<span>	</span>    System.exit(1);
<span>	</span>}
    }
}
The initial ProxyThread code came from here: <span style="font-family:Georgia;line-height:19px;white-space:normal;"><a title="ProxyThread site" href="http://www.dfr.ch/en/proxy.html">http://www.dfr.ch/en/proxy.html</a></span>
<span style="font-family:Georgia;line-height:19px;white-space:normal;">
</span></pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/coderslikeus.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/coderslikeus.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/coderslikeus.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/coderslikeus.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/coderslikeus.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/coderslikeus.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/coderslikeus.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/coderslikeus.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/coderslikeus.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/coderslikeus.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/coderslikeus.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/coderslikeus.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/coderslikeus.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/coderslikeus.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=coderslike.us&amp;blog=6290704&amp;post=5&amp;subd=coderslikeus&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://coderslike.us/2009/01/23/flash-socket-code-and-crossdomain-policy-serving/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bd0b0382966354c72daa660969bca2cd?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dkavanagh</media:title>
		</media:content>
	</item>
	</channel>
</rss>
