Since people started to experiment with the new Socket class in AS3 I've often read that it wouldn't be possible to connect to any port below 1024 with it. While that's true if you want to connect to any server on the web, it is possible to connect to servers that run a special socket server returning cross domain policy information to the Flash Player. It's similar to putting a cross-domain-policy file on your web server - it just requires a little more effort.
Connecting to ports below 1024 opens some interesting possibilities, like tunneling multiuser apps through port 80 to avoid being blocked by strict firewalls, writing your own mail-client, ftp-client - any network client for that matter (that doesn't need the ability to listen for incoming connections, so forget about p2p in Flash). Joa Ebert for example has written an IRC client in Flash. You could also write a Proxy on your own server to forward access to any port on any server...
This is how you can allow the AS3 Socket and XMLSocket to connect to a low port number, for example to a web server's port 80.
AS3 commands
Whenever you call the connect method of a Socket class in AS3:
Actionscript:
socket = new Socket();
socket.connect("localhost", 80);
... the Flash Player implicitly opens a socket - in the example above to port 80 - and sends the following character sequence:
If the server responds with a string formatted as a common policy xml file, Flash Player will open the real socket and will fire the Event.CONNECT event. If no policy string is returned the connection will fail.
XML:
<?xml version="1.0"?><cross-domain-policy><allow-access-from domain="*" to-ports="80" /></cross-domain-policy>
Now you probably don't want to modify the source code of your preferred open source webserver to make it answer to Flash Player's policy requests. Luckily there is an AS3 command to make Flash connect to another port when looking for the policy:
Actionscript:
Security.loadPolicyFile("xmlsocket://localhost:1008");
This will cause the Flash Player to open a socket to port 1008, send the policy-request and read the policy file. If access is allowed it'll open the desired Socket connection to port 80 without further delay.
It is important to know that only policy-files read from a port below 1024 can grant access to ports below 1024. If your policy file is served from a port, say 8008, access below 1024 is blocked even though the policy file might say differently.
Curious - Adobe's DTD defining the structure of a policy file doesn't mention the to-ports attribute, but the Flash Player definitely reads it.
Java socket server
I wrote a little Java-class that, when started, runs as a policy server. By default it listens on port 1008, allowing connections to any port. Which is good for testing but should be changed when running it publicly!
You can download the source code here, or a runnable jar-file here.
Just install the Java-Runtime-Environment (you probably already have it) and on the command line type
java -jar policyserver.jar.
Flex example client
I've also written a little example AS3/Flex application that connects to the localhost web-server, sends an HTTP GET command and reads the response including HTTP headers from the webserver. You could call it a browser ;) - unfortunately it only let's you connect to servers that have the policy server running.
You can download the source code here (just import it into a Flex project and mark WebReader.as as the Default Application).
Or view an example here - enter a path starting with "/" and click on connect and see what it reads from our blog webserver...