protected Tunnel(ProxyRequest preq, Stream stream) { this.Reqeust = preq; this.ProxyStream = stream; this.CancelSource = CancellationTokenSource.CreateLinkedTokenSource(GlobalCancelSource.Token); this.CancelSource.Token.Register(stream.Close); }
public static bool TryParse(Stream proxyStream, bool isSsl, out ProxyRequest req) { req = new ProxyRequest(proxyStream); while (true) { var firstLine = req.m_proxyStream.ReadLine(); if (firstLine == null) { req.Dispose(); req = null; return(false); } try { var sp = firstLine.Split(' '); req.Method = sp[0]; req.RequestUriRaw = sp[1]; req.Version = sp[2]; if (req.Version.StartsWith("HTTP")) { break; } } catch { throw; } } string line; while ((line = req.m_proxyStream.ReadLine()) != null) { if (string.IsNullOrEmpty(line)) { break; } var i = line.IndexOf(':'); req.Headers.Add(line.Substring(0, i), line.Substring(i + 1).Trim()); } req.RemoteHost = req.Method == "CONNECT" ? req.RequestUriRaw : req.Headers.Get("Host"); var hostSep = req.RemoteHost.IndexOf(':'); if (hostSep != -1) { req.RemotePort = int.Parse(req.RemoteHost.Substring(hostSep + 1)); req.RemoteHost = req.RemoteHost.Substring(0, hostSep); } else { req.RemotePort = isSsl ? 443 : 80; } if (req.Method != "CONNECT") { var baseUri = new UriBuilder { Scheme = isSsl ? "https" : "http", Host = req.RemoteHost, Port = req.RemotePort, }.Uri; req.RequestUri = new Uri(baseUri, req.RequestUriRaw); } if (req.Method == "POST" || req.Method == "PUT" || req.Method == "PATCH") { req.RequestBodyReader = new ProxyRequestBody(req); } req.ProxyAuthorization = req.Headers[HttpRequestHeader.ProxyAuthorization]; req.Headers.Remove(HttpRequestHeader.ProxyAuthorization); req.KeepAlive = (req.Headers["Proxy-Connection"] ?? req.Headers[HttpRequestHeader.Connection])?.Equals("Keep-Alive", StringComparison.OrdinalIgnoreCase) ?? false; req.Headers.Remove("Proxy-Connection"); return(true); }
public ProxyRequestBody(ProxyRequest req) { this.m_request = req; }
public TunnelPlain(ProxyRequest preq, Stream stream) : base(preq, stream) { }
public override void Handle() { using (var proxyStreamSsl = new SslStream(this.ProxyStream)) { this.ProxyStream.Write(ConnectionEstablished, 0, ConnectionEstablished.Length); proxyStreamSsl.AuthenticateAsServer(this.m_certificate, false, SslProtocol, false); using (var reqSSL = ProxyRequest.Parse(proxyStreamSsl, true)) { using (var resp = new ProxyResponse(proxyStreamSsl)) { try { if (this.m_handler(new ProxyContext(reqSSL, resp))) { return; } } catch { if (!resp.HeaderSent) { using (var respErr = new ProxyResponse(proxyStreamSsl)) respErr.StatusCode = HttpStatusCode.InternalServerError; } throw; } if (resp.HeaderSent) { return; } resp.SetNoResponse(); } using (var remoteClient = new TcpClient()) { this.CancelSource.Token.Register(remoteClient.Close); try { remoteClient.Connect(this.GetEndPoint()); } catch { using (var respErr = new ProxyResponse(proxyStreamSsl)) respErr.StatusCode = HttpStatusCode.InternalServerError; throw; } using (var remoteStream = remoteClient.GetStream()) using (var remoteStreamSsl = new SslStream(remoteStream)) { remoteStreamSsl.AuthenticateAsClient(reqSSL.RemoteHost); var taskToProxy = this.CopyToAsync(proxyStreamSsl, remoteStreamSsl); reqSSL.WriteRawRequest(remoteStreamSsl); var taskToRemote = this.CopyToAsync(remoteStreamSsl, proxyStreamSsl); try { Task.WaitAll(taskToProxy, taskToRemote); } catch { } } } } } }
public TunnelSslMitm(ProxyRequest preq, Stream stream, X509Certificate2 certificate, MitmHandler handler) : base(preq, stream) { this.m_certificate = certificate; this.m_handler = handler; }
public static ProxyRequest Parse(Stream proxyStream, bool isSsl) { var req = new ProxyRequest(proxyStream); while (true) { var firstLine = req.m_streamReader.ReadLine(); try { var sp = firstLine.Split(' '); req.Method = sp[0]; req.RequestUriRaw = sp[1]; req.Version = sp[2]; if (req.Version.StartsWith("HTTP")) { break; } } catch { } } string line; while ((line = req.m_streamReader.ReadLine()) != null) { if (string.IsNullOrEmpty(line)) { break; } if (line.IndexOf("\r\n") > -1) { var lines = line.Split(new[] { Environment.NewLine }, StringSplitOptions.None); for (int i = 0; i < lines.Length; i++) { var index = lines[i].IndexOf(':'); string key = lines[i].Substring(0, index); string value = lines[i].Substring(index + 1).Trim(); req.Headers.Add(key, value); } } else { var i = line.IndexOf(':'); req.Headers.Add(line.Substring(0, i), line.Substring(i + 1).Trim()); } } req.RemoteHost = req.Method == "CONNECT" ? req.RequestUriRaw : req.Headers.Get("Host"); var hostSep = req.RemoteHost.IndexOf(':'); if (hostSep != -1) { req.RemotePort = int.Parse(req.RemoteHost.Substring(hostSep + 1)); req.RemoteHost = req.RemoteHost.Substring(0, hostSep); } else { req.RemotePort = isSsl ? 443 : 80; } if (req.Method != "CONNECT") { var baseUri = new UriBuilder { Scheme = isSsl ? "https" : "http", Host = req.RemoteHost, Port = req.RemotePort, }.Uri; req.RequestUri = new Uri(baseUri, req.RequestUriRaw); } if (req.Method == "POST" || req.Method == "PUT" || req.Method == "PATCH") { req.RequestBodyReader = new ProxyRequestBody(req); } return(req); }
public TunnelSslForward(ProxyRequest preq, Stream stream) : base(preq, stream) { }
public ProxyContext(ProxyRequest req, ProxyResponse resp) { this.Request = req; this.Response = resp; }