/// <inheritdoc /> /// <summary> /// Создаёт соединение с сервером через прокси-сервер. /// </summary> /// <param name="destinationHost">Хост сервера, с которым нужно связаться через прокси-сервер.</param> /// <param name="destinationPort">Порт сервера, с которым нужно связаться через прокси-сервер.</param> /// <param name="tcpClient">Соединение, через которое нужно работать, или значение <see langword="null" />.</param> /// <returns>Соединение с сервером через прокси-сервер.</returns> /// <exception cref="T:System.InvalidOperationException"> /// Значение свойства <see cref="!:Host" /> равно <see langword="null" /> или имеет нулевую длину. /// -или- /// Значение свойства <see cref="!:Port" /> меньше 1 или больше 65535. /// -или- /// Значение свойства <see cref="!:Username" /> имеет длину более 255 символов. /// -или- /// Значение свойства <see cref="!:Password" /> имеет длину более 255 символов. /// </exception> /// <exception cref="T:System.ArgumentNullException">Значение параметра <paramref name="destinationHost" /> равно <see langword="null" />.</exception> /// <exception cref="T:System.ArgumentException">Значение параметра <paramref name="destinationHost" /> является пустой строкой.</exception> /// <exception cref="T:System.ArgumentOutOfRangeException">Значение параметра <paramref name="destinationPort" /> меньше 1 или больше 65535.</exception> /// <exception cref="!:Leaf.xNet.Net.ProxyException">Ошибка при работе с прокси-сервером.</exception> public override TcpClient CreateConnection(string destinationHost, int destinationPort, TcpClient tcpClient = null) { CheckState(); #region Проверка параметров if (destinationHost == null) { throw new ArgumentNullException(nameof(destinationHost)); } if (destinationHost.Length == 0) { throw ExceptionHelper.EmptyString(nameof(destinationHost)); } if (!ExceptionHelper.ValidateTcpPort(destinationPort)) { throw ExceptionHelper.WrongTcpPort(nameof(destinationHost)); } #endregion var curTcpClient = tcpClient ?? CreateConnectionToProxy(); try { var nStream = curTcpClient.GetStream(); InitialNegotiation(nStream); SendCommand(nStream, CommandConnect, destinationHost, destinationPort); } catch (Exception ex) { curTcpClient.Close(); if (ex is IOException || ex is SocketException) { throw NewProxyException(Resources.ProxyException_Error, ex); } throw; } return(curTcpClient); }
/// <inheritdoc /> /// <summary> /// Создаёт соединение с сервером через прокси-сервер. /// </summary> /// <param name="destinationHost">Хост сервера, с которым нужно связаться через прокси-сервер.</param> /// <param name="destinationPort">Порт сервера, с которым нужно связаться через прокси-сервер.</param> /// <param name="tcpClient">Соединение, через которое нужно работать, или значение <see langword="null" />.</param> /// <returns>Соединение с сервером через прокси-сервер.</returns> /// <exception cref="T:System.InvalidOperationException"> /// Значение свойства <see cref="!:Host" /> равно <see langword="null" /> или имеет нулевую длину. /// -или- /// Значение свойства <see cref="!:Port" /> меньше 1 или больше 65535. /// -или- /// Значение свойства <see cref="!:Username" /> имеет длину более 255 символов. /// -или- /// Значение свойства <see cref="!:Password" /> имеет длину более 255 символов. /// </exception> /// <exception cref="T:System.ArgumentNullException">Значение параметра <paramref name="destinationHost" /> равно <see langword="null" />.</exception> /// <exception cref="T:System.ArgumentException">Значение параметра <paramref name="destinationHost" /> является пустой строкой.</exception> /// <exception cref="T:System.ArgumentOutOfRangeException">Значение параметра <paramref name="destinationPort" /> меньше 1 или больше 65535.</exception> /// <exception cref="!:Leaf.xNet.Net.ProxyException">Ошибка при работе с прокси-сервером.</exception> /// <remarks>Если порт сервера неравен 80, то для подключения используется метод 'CONNECT'.</remarks> public override TcpClient CreateConnection(string destinationHost, int destinationPort, TcpClient tcpClient = null) { CheckState(); #region Проверка параметров if (destinationHost == null) { throw new ArgumentNullException(nameof(destinationHost)); } if (destinationHost.Length == 0) { throw ExceptionHelper.EmptyString(nameof(destinationHost)); } if (!ExceptionHelper.ValidateTcpPort(destinationPort)) { throw ExceptionHelper.WrongTcpPort(nameof(destinationHost)); } #endregion var curTcpClient = tcpClient ?? CreateConnectionToProxy(); if (destinationPort == 80) { return(curTcpClient); } HttpStatusCode statusCode; try { var nStream = curTcpClient.GetStream(); SendConnectionCommand(nStream, destinationHost, destinationPort); statusCode = ReceiveResponse(nStream); } catch (Exception ex) { curTcpClient.Close(); if (ex is IOException || ex is SocketException) { throw NewProxyException(Resources.ProxyException_Error, ex); } throw; } if (statusCode == HttpStatusCode.OK) { return(curTcpClient); } curTcpClient.Close(); throw new ProxyException(string.Format( Resources.ProxyException_ReceivedWrongStatusCode, statusCode, ToString()), this); }