private IEnumerator <object> SendResponseTask(Stream source, int?count)
            {
                var length = Math.Min(
                    (int)source.Length,
                    count.GetValueOrDefault(int.MaxValue)
                    );

                ContentLength = length;

                if (!HeadersSent)
                {
                    HeadersSent = true;
                    yield return(SendHeadersTask());
                }

                ResponseSent = true;

                const int blockSize = 1024 * 128;
                var       bytesLeft = length;

                using (var sda = new StreamDataAdapter(source, false))
                    using (var buffer = BufferPool <byte> .Allocate(blockSize))
                        while (bytesLeft > 0)
                        {
                            var readSize = Math.Min(blockSize, bytesLeft);
                            var fBlock   = sda.Read(buffer.Data, 0, blockSize);
                            yield return(fBlock);

                            bytesLeft -= fBlock.Result;

                            yield return(Adapter.Write(buffer.Data, 0, fBlock.Result));
                        }
            }
Beispiel #2
0
        public static AsyncTextWriter GetResponseWriter(this HttpListenerContext context, Encoding encoding)
        {
            var adapter = new StreamDataAdapter(context.Response.OutputStream, true);
            var result  = new AsyncTextWriter(adapter, encoding);

            result.AutoFlush = true;
            return(result);
        }
Beispiel #3
0
        public static AsyncTextReader GetRequestReader(this HttpListenerContext context)
        {
            var encoding = context.Request.ContentEncoding ?? Encoding.UTF8;
            var adapter  = new StreamDataAdapter(context.Request.InputStream, true);
            var result   = new AsyncTextReader(adapter, encoding);

            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Connect this instance.
        /// </summary>
        /// <param name="logger">Logger object</param>
        /// <returns>The connected data adapter</returns>
        public IDataAdapter Connect(Logger logger)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if ((Port <= 0) || (Port > 65535))
            {
                throw new NetServiceException(Properties.Resources.FixedProxyDocument_MustProvideValidPort);
            }

            try
            {
                ProxyClient client = Client != null?Client.Create(logger)
                                         : new IpProxyClient();

                IpProxyToken token = new IpProxyToken(null, Host, Port,
                                                      UdpEnable ? IpProxyToken.IpClientType.Udp : IpProxyToken.IpClientType.Tcp, IPv6);
                IDataAdapter adapter = client.Connect(token, logger, new MetaDictionary(), new MetaDictionary(), new PropertyBag());
                if (_layers.Count > 0)
                {
                    MemoryStream      initial_stm    = new MemoryStream(InitialData ?? new byte[0]);
                    StreamDataAdapter initial        = new StreamDataAdapter(initial_stm);
                    IDataAdapter      client_adapter = initial;
                    foreach (INetworkLayer layer in _layers.Select(f => f.CreateLayer(logger)))
                    {
                        layer.Negotiate(ref client_adapter, ref adapter, token, logger, new MetaDictionary(),
                                        new MetaDictionary(), new PropertyBag(), NetworkLayerBinding.Client);
                    }
                }
                return(adapter);
            }
            catch (SocketException ex)
            {
                throw new NetServiceException(Properties.Resources.FixedProxyDocument_ErrorCreatingService, ex);
            }
            catch (IOException ex)
            {
                throw new NetServiceException(Properties.Resources.FixedProxyDocument_ErrorCreatingService, ex);
            }
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="token"></param>
        /// <param name="meta"></param>
        /// <param name="globalMeta"></param>
        /// <param name="service"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public override IDataAdapter Complete(ProxyToken token, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service, IDataAdapter client)
        {
            IDataAdapter ret = null;

            // An empty initial request indicates we are a full connection
            if (token.State.ContainsKey("header"))
            {
                HttpRequestHeader   initialRequest = (HttpRequestHeader)token.State["header"];
                DataAdapterToStream stm            = (DataAdapterToStream)token.State["stm"];

                if (token.Status == NetStatusCodes.Success)
                {
                    if (initialRequest.IsConnect)
                    {
                        ReturnResponse(null, 200, "Connection established", initialRequest.Method, initialRequest.Version, stm);

                        // Connect is transparent
                        ret = new StreamDataAdapter(stm);
                    }
                    else
                    {
                        // Use a proxy adapter
                        ret = new HttpProxyServerAdapter(stm, initialRequest, _logger);
                    }
                }
                else
                {
                    ReturnResponse(initialRequest, 404, "Not Found", initialRequest.Method, HttpVersion.Version11, stm);
                }
            }
            else
            {
                ret = (IDataAdapter)token.State["adapter"];
            }

            token.State.Clear();

            return(ret);
        }
Beispiel #6
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);
        }