Example #1
0
        private static void ConnectWithHttpProxyToken(Stream stm, HttpProxyToken token, Logger logger)
        {
            token.IsHTTPProxyClient = true;

            if (token.Connect)
            {
                // Send original CONNECT headers
                StringBuilder builder = new StringBuilder();
                foreach (var s in token.Headers)
                {
                    builder.Append(s);
                }

                byte[] data = GeneralUtils.MakeByteArray(builder.ToString());

                stm.Write(data, 0, data.Length);

                builder.Clear();

                // Read out response headers
                while (true)
                {
                    string nextLine = GeneralUtils.ReadLine(stm);

                    builder.Append(nextLine);

                    if (nextLine.Trim().Length == 0)
                    {
                        break;
                    }
                }

                // Smuggle data back to server
                token.Response = GeneralUtils.MakeByteArray(builder.ToString());
            }

            token.Status = NetStatusCodes.Success;
        }
Example #2
0
        private HttpProxyToken HandleConnect(string host, string[] headers, DataAdapterToStream stm)
        {
            string hostName = null;
            int    port     = 80;

            string[]       connectHeader = host.Split(':');
            HttpProxyToken ret           = null;

            if (connectHeader.Length > 0)
            {
                hostName = connectHeader[0];
                if (connectHeader.Length > 1)
                {
                    if (!int.TryParse(connectHeader[1], out port))
                    {
                        _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidConnect, connectHeader[1]);
                        port = 0;
                    }
                }

                if (port > 0)
                {
                    UriBuilder builder = new UriBuilder(GetProbableProtocol(port), hostName);
                    builder.Port = port;

                    ret = new HttpProxyToken(hostName, port, true, headers, builder.Uri, stm);
                }
                else
                {
                    // TODO: Put in some decent error codes
                    ReturnResponse(500, "Server Error", stm);
                }
            }

            return(ret);
        }
Example #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="token"></param>
        /// <param name="client"></param>
        /// <param name="globalMeta"></param>
        /// <param name="meta"></param>
        /// <param name="service"></param>
        /// <returns></returns>
        public override IDataAdapter Complete(ProxyToken token, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service, IDataAdapter client)
        {
            IDataAdapter        ret       = null;
            HttpProxyToken      httpToken = (HttpProxyToken)token;
            DataAdapterToStream stm       = httpToken.Adapter;

            if (httpToken.Status == NetStatusCodes.Success)
            {
                if (httpToken.IsHTTPProxyClient)
                {
                    // We don't have to do anything as such, other than send back any smuggled data if it was a connect call
                    if (httpToken.Response != null)
                    {
                        stm.Write(httpToken.Response, 0, httpToken.Response.Length);
                    }

                    httpToken.Adapter = null;

                    if (httpToken.Connect)
                    {
                        // With CONNECT the data stream is transparent
                        ret = new StreamDataAdapter(stm);
                    }
                    else
                    {
                        // For anything else, rebuild the original headers so it can flow through the graph
                        StringBuilder builder = new StringBuilder();

                        foreach (string s in httpToken.Headers)
                        {
                            builder.Append(s);
                        }

                        ret = new PrefixedDataAdapter(new StreamDataAdapter(stm), GeneralUtils.MakeByteArray(builder.ToString()));
                    }
                }
                else
                {
                    if (httpToken.Connect)
                    {
                        ReturnResponse(200, "Connection established", stm);

                        httpToken.Adapter = null;
                        ret = new StreamDataAdapter(stm);
                    }
                    else
                    {
                        StringBuilder builder = new StringBuilder();

                        string[] reqValues = httpToken.Headers[0].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                        // Downgrade to version 1.0
                        httpToken.Headers[0] = reqValues[0] + " " + httpToken.Url.PathAndQuery + " HTTP/1.0\r\n";
                        foreach (string s in httpToken.Headers)
                        {
                            // Remove proxy headers
                            if (!s.StartsWith("proxy", StringComparison.OrdinalIgnoreCase))
                            {
                                builder.Append(s);
                            }
                        }

                        httpToken.Adapter = null;

                        ret = new PrefixedDataAdapter(new StreamDataAdapter(stm), GeneralUtils.MakeByteArray(builder.ToString()));
                    }
                }
            }
            else
            {
                ReturnResponse(404, "Not Found", stm);
            }

            return(ret);
        }
Example #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="adapter"></param>
        /// <param name="globalMeta"></param>
        /// <param name="meta"></param>
        /// <param name="service"></param>
        /// <returns></returns>
        public override ProxyToken Accept(IDataAdapter adapter, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service)
        {
            HttpProxyToken token = null;

            if (_ssl != null)
            {
                IDataAdapter client = null;

                _ssl.Negotiate(ref adapter, ref client, null, _logger, null, null,
                               new PropertyBag("Root"), NetworkLayerBinding.Server);
            }

            DataAdapterToStream stm = new DataAdapterToStream(adapter);

            List <string> headers = new List <string>();

            // Read out HTTP headers
            try
            {
                while (true)
                {
                    string nextLine = GeneralUtils.ReadLine(stm);

                    headers.Add(nextLine);

                    if (nextLine.Trim('\r', '\n').Length == 0)
                    {
                        break;
                    }
                }
            }
            catch (EndOfStreamException)
            {
                // Pass on the exception if we got killed half way through
                if (headers.Count > 0)
                {
                    throw;
                }
            }

            if (headers.Count > 0)
            {
                string[] reqValues = headers[0].Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                // Check it at least has a VERB and a PATH
                if (reqValues.Length > 1)
                {
                    if (reqValues[0].Equals("CONNECT", StringComparison.OrdinalIgnoreCase))
                    {
                        token = HandleConnect(reqValues[1], headers.ToArray(), stm);
                    }
                    else
                    {
                        token = HandleOtherRequest(reqValues[1], headers.ToArray(), stm);
                    }
                }
                else
                {
                    _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidRequest, headers[0]);

                    // TODO: Put in some decent error codes
                    ReturnResponse(500, "Server Error", stm);
                }
            }

            return(token);
        }