예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }