Project Description
SOHP is a connection proxy/tunnel based on the HTTP protocol designed to allow socket connections from behind strict firewalls. It can also be used to circumvent the security restrictions placed on the Silverlight socket class.

Milestones
12/28/2011 Basic connection tunneling completed. Completed 12/28/2011
01/06/2012 Test via HTTPS/SSL. Completed 12/29/2011
01/13/2012 Change CrossAccessPolicy serving to be configurable. Completed 12/29/2011
01/13/2012 Add support to restrict target hosts for security purposes.
01/20/2012 Fully document SOHP protocol.



If you are using SOHP in your project, please let us know! We'd like to know what it's being used for, how it's being used, and what we can do to improve it.

Sample Server Implementation
    partial class SohpProxyServer : ServiceBase
    {
        private SohpServer.ProxyServer sohpServer;

        public SohpProxyServer()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            if (this.sohpServer == null)
            {
                 this.sohpServer = new SohpServer.ProxyServer("https://sohpuri/");
                 this.sohpServer.AddCustomContentHandler("crossaccesspolicy.xml", SohpProxyServer.ServeCrossAccessPolicy);
            }
            this.sohpServer.StartServer(500);
        }

        private static void ServeCrossAccessPolicy(HttpListenerContext reqContext)
        {
            string policyXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><access-policy><cross-domain-access><policy><allow-from http-methods=\"*\" http-request-headers=\"*\"><domain uri=\"*\" /><domain uri=\"http://*\" /><domain uri=\"https://*\" /></allow-from><grant-to><resource path=\"/\" include-subpaths=\"true\"/></grant-to></policy><policy><allow-from http-request-headers=\"*\"><domain uri=\"*\" /><domain uri=\"http://*\" /><domain uri=\"https://*\" /></allow-from><grant-to><resource path=\"/\" include-subpaths=\"true\"/></grant-to></policy></cross-domain-access></access-policy>";
            byte[] policyData = Encoding.Default.GetBytes(policyXml);
            reqContext.Response.ContentType = "text/xml";
            reqContext.Response.ContentLength64 = policyData.Length;
            reqContext.Response.OutputStream.Write(policyData, 0, policyData.Length);
            reqContext.Response.Close();

            return;
        }
    }

Last edited Jan 4, 2012 at 11:00 PM by wgraham, version 11