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