<PackageReference Include="SSH.NET" Version="2025.0.0" />

HttpConnector

sealed class HttpConnector : ProxyConnector
Establishes a tunnel via an HTTP proxy server.
using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using System.Text.RegularExpressions.Generated; namespace Renci.SshNet.Connection { internal sealed class HttpConnector : ProxyConnector { private const string HttpResponsePattern = "HTTP/(?<version>\\d[.]\\d) (?<statusCode>\\d{3}) (?<reasonPhrase>.+)$"; private const string HttpHeaderPattern = "(?<fieldName>[^\\[\\]()<>@,;:\\\"/?={} \\t]+):(?<fieldValue>.+)?"; private static readonly Regex HttpResponseRegex = GetHttpResponseRegex(); private static readonly Regex HttpHeaderRegex = GetHttpHeaderRegex(); [GeneratedRegex("HTTP/(?<version>\\d[.]\\d) (?<statusCode>\\d{3}) (?<reasonPhrase>.+)$")] [GeneratedCode("System.Text.RegularExpressions.Generator", "8.0.12.16413")] private static Regex GetHttpResponseRegex() { return <RegexGenerator_g>FF02E8C37B99F41659B0026E2B1005AC8CE9F303D9F9E176C498C4EA009567923__GetHttpResponseRegex_0.Instance; } [GeneratedRegex("(?<fieldName>[^\\[\\]()<>@,;:\\\"/?={} \\t]+):(?<fieldValue>.+)?")] [GeneratedCode("System.Text.RegularExpressions.Generator", "8.0.12.16413")] private static Regex GetHttpHeaderRegex() { return <RegexGenerator_g>FF02E8C37B99F41659B0026E2B1005AC8CE9F303D9F9E176C498C4EA009567923__GetHttpHeaderRegex_1.Instance; } public HttpConnector(ISocketFactory socketFactory) : base(socketFactory) { } protected override void HandleProxyConnect(IConnectionInfo connectionInfo, Socket socket) { SocketAbstraction.Send(socket, SshData.Ascii.GetBytes(string.Format(CultureInfo.InvariantCulture, "CONNECT {0}:{1} HTTP/1.0\r\n", connectionInfo.Host, connectionInfo.Port))); if (!string.IsNullOrEmpty(connectionInfo.ProxyUsername)) { string s = string.Format(CultureInfo.InvariantCulture, "Proxy-Authorization: Basic {0}\r\n", Convert.ToBase64String(SshData.Ascii.GetBytes(connectionInfo.ProxyUsername + ":" + connectionInfo.ProxyPassword))); SocketAbstraction.Send(socket, SshData.Ascii.GetBytes(s)); } SocketAbstraction.Send(socket, SshData.Ascii.GetBytes("\r\n")); HttpStatusCode? nullable = null; int num = 0; while (true) { string text = SocketReadLine(socket, connectionInfo.Timeout); if (text == null) break; if (!nullable.HasValue) { Match match = HttpResponseRegex.Match(text); if (match.Success) { string text2 = match.Result("${statusCode}"); nullable = (HttpStatusCode)int.Parse(text2, CultureInfo.InvariantCulture); if (nullable.GetValueOrDefault() != HttpStatusCode.OK) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(22, 2); defaultInterpolatedStringHandler.AppendLiteral("HTTP: Status code "); defaultInterpolatedStringHandler.AppendFormatted(text2); defaultInterpolatedStringHandler.AppendLiteral(", \""); defaultInterpolatedStringHandler.AppendFormatted(match.Result("${reasonPhrase}")); defaultInterpolatedStringHandler.AppendLiteral("\""); throw new ProxyException(defaultInterpolatedStringHandler.ToStringAndClear()); } } } else { Match match2 = HttpHeaderRegex.Match(text); if (match2.Success) { if (match2.Result("${fieldName}").Equals("Content-Length", StringComparison.OrdinalIgnoreCase)) num = int.Parse(match2.Result("${fieldValue}"), CultureInfo.InvariantCulture); } else if (text.Length == 0) { if (num > 0) { byte[] buffer = new byte[num]; ConnectorBase.SocketRead(socket, buffer, 0, num, connectionInfo.Timeout); } break; } } } if (!nullable.HasValue) throw new ProxyException("HTTP response does not contain status line."); } private static string SocketReadLine(Socket socket, TimeSpan readTimeout) { Encoding ascii = SshData.Ascii; List<byte> list = new List<byte>(); byte[] array = new byte[1]; while (SocketAbstraction.Read(socket, array, 0, array.Length, readTimeout) != 0) { byte b = array[0]; list.Add(b); if (b == 10 && list.Count > 1 && list[list.Count - 2] == 13) return ascii.GetString(list.ToArray(), 0, list.Count - 2); } if (list.Count == 0) return null; return ascii.GetString(list.ToArray(), 0, list.Count); } } }