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)); } }
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); }
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); }
/// <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); } }
/// <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); }
/// <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); }