System.Net.FtpControlStream.QueueOrCreateDataConection C# (CSharp) Method

QueueOrCreateDataConection() private method

private QueueOrCreateDataConection ( PipelineEntry entry, ResponseDescription response, bool timeout, Stream &stream, bool &isSocketReady ) : PipelineInstruction
entry PipelineEntry
response ResponseDescription
timeout bool
stream Stream
isSocketReady bool
return PipelineInstruction
        private PipelineInstruction QueueOrCreateDataConection(PipelineEntry entry, ResponseDescription response, bool timeout, ref Stream stream, out bool isSocketReady)
        {
            isSocketReady = false;
            if (_dataHandshakeStarted)
            {
                isSocketReady = true;
                return PipelineInstruction.Pause; //if we already started then this is re-entering into the callback where we proceed with the stream
            }

            _dataHandshakeStarted = true;

            // Handle passive responses by parsing the port and later doing a Connect(...)
            bool isPassive = false;
            int port = -1;
            if (entry.Command == "PASV\r\n" || entry.Command == "EPSV\r\n")
            {
                if (!response.PositiveCompletion)
                {
                    _abortReason = SR.Format(SR.net_ftp_server_failed_passive, response.Status);
                    return PipelineInstruction.Abort;
                }
                if (entry.Command == "PASV\r\n")
                {
                    port = GetPortV4(response.StatusDescription);
                }
                else
                {
                    port = GetPortV6(response.StatusDescription);
                }

                isPassive = true;
            }

            if (isPassive)
            {
                if (port == -1)
                {
                    NetEventSource.Fail(this, "'port' not set.");
                }

                try
                {
                    _dataSocket = CreateFtpDataSocket((FtpWebRequest)_request, Socket);
                }
                catch (ObjectDisposedException)
                {
                    throw ExceptionHelper.RequestAbortedException;
                }

                IPEndPoint localEndPoint = new IPEndPoint(((IPEndPoint)Socket.LocalEndPoint).Address, 0);
                _dataSocket.Bind(localEndPoint);

                _passiveEndPoint = new IPEndPoint(ServerAddress, port);
            }

            PipelineInstruction result;

            if (_passiveEndPoint != null)
            {
                IPEndPoint passiveEndPoint = _passiveEndPoint;
                _passiveEndPoint = null;
                if (NetEventSource.IsEnabled) NetEventSource.Info(this, "starting Connect()");
                if (_isAsync)
                {
                    _dataSocket.BeginConnect(passiveEndPoint, s_connectCallbackDelegate, this);
                    result = PipelineInstruction.Pause;
                }
                else
                {
                    _dataSocket.Connect(passiveEndPoint);
                    result = PipelineInstruction.Advance; // for passive mode we end up going to the next command
                }
            }
            else
            {
                if (NetEventSource.IsEnabled) NetEventSource.Info(this, "starting Accept()");

                if (_isAsync)
                {
                    _dataSocket.BeginAccept(s_acceptCallbackDelegate, this);
                    result = PipelineInstruction.Pause;
                }
                else
                {
                    Socket listenSocket = _dataSocket;
                    try
                    {
                        _dataSocket = _dataSocket.Accept();
                        if (!ServerAddress.Equals(((IPEndPoint)_dataSocket.RemoteEndPoint).Address))
                        {
                            _dataSocket.Close();
                            throw new WebException(SR.net_ftp_active_address_different, WebExceptionStatus.ProtocolError);
                        }
                        isSocketReady = true;   // for active mode we end up creating a stream before advancing the pipeline
                        result = PipelineInstruction.Pause;
                    }
                    finally
                    {
                        listenSocket.Close();
                    }
                }
            }
            return result;
        }