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