Inheritance: CommandStream
        private static void AcceptCallback(IAsyncResult asyncResult)
        {
            FtpControlStream asyncState  = (FtpControlStream)asyncResult.AsyncState;
            LazyAsyncResult  result      = asyncResult as LazyAsyncResult;
            Socket           asyncObject = (Socket)result.AsyncObject;

            try
            {
                asyncState.m_DataSocket = asyncObject.EndAccept(asyncResult);
                if (!asyncState.ServerAddress.Equals(((IPEndPoint)asyncState.m_DataSocket.RemoteEndPoint).Address))
                {
                    asyncState.m_DataSocket.Close();
                    throw new WebException(SR.GetString("net_ftp_active_address_different"), WebExceptionStatus.ProtocolError);
                }
                asyncState.ContinueCommandPipeline();
            }
            catch (Exception exception)
            {
                asyncState.CloseSocket();
                asyncState.InvokeRequestCallback(exception);
            }
            finally
            {
                asyncObject.Close();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Provides a wrapper for the async accept operations.
        /// </summary>
        private static void AcceptCallback(IAsyncResult asyncResult)
        {
            FtpControlStream connection   = (FtpControlStream)asyncResult.AsyncState;
            Socket           listenSocket = connection._dataSocket;

            try
            {
                connection._dataSocket = listenSocket.EndAccept(asyncResult);
                if (!connection.ServerAddress.Equals(((IPEndPoint)connection._dataSocket.RemoteEndPoint).Address))
                {
                    connection._dataSocket.Close();
                    throw new WebException(SR.net_ftp_active_address_different, WebExceptionStatus.ProtocolError);
                }
                connection.ContinueCommandPipeline();
            }
            catch (Exception e)
            {
                connection.CloseSocket();
                connection.InvokeRequestCallback(e);
            }
            finally
            {
                listenSocket.Close();
            }
        }
        private static void SSLHandshakeCallback(IAsyncResult asyncResult)
        {
            FtpControlStream asyncState = (FtpControlStream)asyncResult.AsyncState;

            try
            {
                asyncState.ContinueCommandPipeline();
            }
            catch (Exception exception)
            {
                asyncState.CloseSocket();
                asyncState.InvokeRequestCallback(exception);
            }
        }
Esempio n. 4
0
        private static void SSLHandshakeCallback(IAsyncResult asyncResult)
        {
            FtpControlStream connection = (FtpControlStream)asyncResult.AsyncState;

            try
            {
                connection._tlsStream.EndAuthenticateAsClient(asyncResult);
                connection.ContinueCommandPipeline();
            }
            catch (Exception e)
            {
                connection.CloseSocket();
                connection.InvokeRequestCallback(e);
            }
        }
Esempio n. 5
0
        /// <summary>
        ///    <para>Provides a wrapper for the async accept operations</para>
        /// </summary>
        private static void ConnectCallback(IAsyncResult asyncResult)
        {
            FtpControlStream connection = (FtpControlStream)asyncResult.AsyncState;

            try
            {
                connection._dataSocket.EndConnect(asyncResult);
                connection.ContinueCommandPipeline();
            }
            catch (Exception e)
            {
                connection.CloseSocket();
                connection.InvokeRequestCallback(e);
            }
        }
        private static void ConnectCallback(IAsyncResult asyncResult)
        {
            FtpControlStream asyncState = (FtpControlStream)asyncResult.AsyncState;

            try
            {
                LazyAsyncResult result = asyncResult as LazyAsyncResult;
                ((Socket)result.AsyncObject).EndConnect(asyncResult);
                asyncState.ContinueCommandPipeline();
            }
            catch (Exception exception)
            {
                asyncState.CloseSocket();
                asyncState.InvokeRequestCallback(exception);
            }
        }
        //
        // Only executed for Async requests
        //
        private void AsyncRequestCallback(object obj)
        {
            GlobalLog.Enter("FtpWebRequest#" + ValidationHelper.HashString(this) + "::AsyncRequestCallback", "#"+ValidationHelper.HashString(obj));
            RequestStage stageMode = RequestStage.CheckForError;

            try {

                FtpControlStream connection;
                connection = obj as FtpControlStream;
                FtpDataStream stream = obj as FtpDataStream;
                Exception exception = obj as Exception;

                bool completedRequest = (obj == null);

                GlobalLog.Print("AsyncRequestCallback()  stream:"+ValidationHelper.HashString(stream)+" conn:"+ValidationHelper.HashString(connection)+" exp:"+ValidationHelper.HashString(exception)+" completedRequest:"+ValidationHelper.HashString(completedRequest));

                while (true)
                {
                    if (exception != null)
                    {
                        if (AttemptedRecovery(exception))
                        {
                            connection = QueueOrCreateConnection();
                            if (connection == null)
                                return;
                            exception = null;
                        }
                        if (exception != null)
                        {
                            SetException(exception);
                            break;
                        }
                    }

                    if (connection != null)
                    {
                        lock(m_SyncObject)
                        {
                            if (m_Aborted)
                            {
                                if (Logging.On) Logging.PrintInfo(Logging.Web, this, "", SR.GetString(SR.net_log_releasing_connection, ValidationHelper.HashString(connection)));
                                m_ConnectionPool.PutConnection(connection, this, Timeout);
                                break;
                            }
                            m_Connection = connection;
                            if (Logging.On) Logging.Associate(Logging.Web, this, m_Connection);
                        }

                        try {
                            stream = (FtpDataStream)TimedSubmitRequestHelper(true);
                        } catch (Exception e) {
                            exception = e;
                            continue;
                        }
                        return;
                    }
                    else if (stream != null)
                    {
                        lock (m_SyncObject)
                        {
                            if (m_Aborted)
                            {
                                ((ICloseEx)stream).CloseEx(CloseExState.Abort|CloseExState.Silent);
                                break;
                            }
                            m_Stream = stream;
                        }

                        stream.SetSocketTimeoutOption(SocketShutdown.Both, Timeout, true);
                        EnsureFtpWebResponse(null);
                        // This one may update the Stream member on m_FtpWebResponse based on the CacheProtocol feedback.
                        CheckCacheRetrieveOnResponse();
                        CheckCacheUpdateOnResponse();

                        stageMode = stream.CanRead? RequestStage.ReadReady: RequestStage.WriteReady;
                    }
                    else if (completedRequest)
                    {
                        connection = m_Connection;

                        bool isRevalidatedOrRetried = false;
                        if (connection != null)
                        {
                            EnsureFtpWebResponse(null);

                            // This to update response status and exit message if any
                            // Note that due to a design of FtpControlStream the status 221 "Service closing control connection" is always suppresses.
                            m_FtpWebResponse.UpdateStatus(connection.StatusCode, connection.StatusLine, connection.ExitMessage);

                            isRevalidatedOrRetried =!m_CacheDone &&
                                                    (CacheProtocol.ProtocolStatus == CacheValidationStatus.Continue || CacheProtocol.ProtocolStatus == CacheValidationStatus.RetryResponseFromServer);

                            lock (m_SyncObject)
                            {
                                if(!CheckCacheRetrieveOnResponse())
                                    continue;

                                if (m_FtpWebResponse.IsFromCache)
                                    isRevalidatedOrRetried = false;

                                CheckCacheUpdateOnResponse();
                            }
                        }

                        if (!isRevalidatedOrRetried)
                            stageMode = RequestStage.ReleaseConnection;
                    }
                    else
                    {
                        throw new InternalException();
                    }
                    break;
                }
            }
            catch (Exception exception)
            {
                SetException(exception);
            }            
            finally {
                FinishRequestStage(stageMode);
                GlobalLog.Leave("FtpWebRequest#" + ValidationHelper.HashString(this) + "::AsyncRequestCallback");
            }
        }
Esempio n. 8
0
        //
        // NOTE1: The caller must synchronize access to SubmitRequest(), only one call is allowed for a particular request.
        // NOTE2: This method eats all exceptions so the caller must rethrow them.
        //
        private void SubmitRequest(bool isAsync)
        {
            try
            {
                _async = isAsync;

                //
                // FYI: Will do 2 attempts max as per AttemptedRecovery
                //
                Stream stream;

                while (true)
                {
                    FtpControlStream connection = _connection;

                    if (connection == null)
                    {
                        if (isAsync)
                        {
                            CreateConnectionAsync();
                            return;
                        }

                        connection = CreateConnection();
                        _connection = connection;
                    }

                    if (!isAsync)
                    {
                        if (Timeout != System.Threading.Timeout.Infinite)
                        {
                            _remainingTimeout = Timeout - (int)((DateTime.UtcNow - _startTime).TotalMilliseconds);

                            if (_remainingTimeout <= 0)
                            {
                                throw ExceptionHelper.TimeoutException;
                            }
                        }
                    }

                    if (NetEventSource.IsEnabled) NetEventSource.Info(this, "Request being submitted");

                    connection.SetSocketTimeoutOption(RemainingTimeout);

                    try
                    {
                        stream = TimedSubmitRequestHelper(isAsync);
                    }
                    catch (Exception e)
                    {
                        if (AttemptedRecovery(e))
                        {
                            if (!isAsync)
                            {
                                if (Timeout != System.Threading.Timeout.Infinite)
                                {
                                    _remainingTimeout = Timeout - (int)((DateTime.UtcNow - _startTime).TotalMilliseconds);
                                    if (_remainingTimeout <= 0)
                                    {
                                        throw;
                                    }
                                }
                            }
                            continue;
                        }
                        throw;
                    }
                    // no retry needed
                    break;
                }
            }
            catch (WebException webException)
            {
                // If this was a timeout, throw a timeout exception
                IOException ioEx = webException.InnerException as IOException;
                if (ioEx != null)
                {
                    SocketException sEx = ioEx.InnerException as SocketException;
                    if (sEx != null)
                    {
                        if (sEx.SocketErrorCode == SocketError.TimedOut)
                        {
                            SetException(new WebException(SR.net_timeout, WebExceptionStatus.Timeout));
                        }
                    }
                }

                SetException(webException);
            }
            catch (Exception exception)
            {
                SetException(exception);
            }
        }
Esempio n. 9
0
        //
        // Returns a previous stage
        //
        private RequestStage FinishRequestStage(RequestStage stage)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"state:{stage}");

            if (_exception != null)
                stage = RequestStage.ReleaseConnection;

            RequestStage prev;
            LazyAsyncResult writeResult;
            LazyAsyncResult readResult;
            FtpControlStream connection;

            lock (_syncObject)
            {
                prev = _requestStage;

                if (stage == RequestStage.CheckForError)
                    return prev;

                if (prev == RequestStage.ReleaseConnection &&
                    stage == RequestStage.ReleaseConnection)
                {
                    return RequestStage.ReleaseConnection;
                }

                if (stage > prev)
                    _requestStage = stage;

                if (stage <= RequestStage.RequestStarted)
                    return prev;

                writeResult = _writeAsyncResult;
                readResult = _readAsyncResult;
                connection = _connection;

                if (stage == RequestStage.ReleaseConnection)
                {
                    if (_exception == null &&
                        !_aborted &&
                        prev != RequestStage.ReadReady &&
                        _methodInfo.IsDownload &&
                        !_ftpWebResponse.IsFromCache)
                    {
                        return prev;
                    }

                    _connection = null;
                }
            }

            try
            {
                // First check to see on releasing the connection
                if ((stage == RequestStage.ReleaseConnection ||
                     prev == RequestStage.ReleaseConnection)
                    && connection != null)
                {
                    try
                    {
                        if (_exception != null)
                        {
                            connection.Abort(_exception);
                        }
                    }
                    finally
                    {
                        if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Releasing connection: {connection}");
                        connection.CloseSocket();
                        if (_async)
                            if (_requestCompleteAsyncResult != null)
                                _requestCompleteAsyncResult.InvokeCallback();
                    }
                }
                return prev;
            }
            finally
            {
                try
                {
                    // In any case we want to signal the writer if came here
                    if (stage >= RequestStage.WriteReady)
                    {
                        // If writeResult == null and this is an upload request, it means
                        // that the user has called GetResponse() without calling 
                        // GetRequestStream() first. So they are not interested in a 
                        // stream. Therefore we close the stream so that the 
                        // request/pipeline can continue
                        if (_methodInfo.IsUpload && !_getRequestStreamStarted)
                        {
                            if (_stream != null)
                                _stream.Close();
                        }
                        else if (writeResult != null && !writeResult.InternalPeekCompleted)
                            writeResult.InvokeCallback();
                    }
                }
                finally
                {
                    // The response is ready either with or without a stream
                    if (stage >= RequestStage.ReadReady && readResult != null && !readResult.InternalPeekCompleted)
                        readResult.InvokeCallback();
                }
            }
        }
Esempio n. 10
0
        //
        // Only executed for Async requests
        //
        private void AsyncRequestCallback(object obj)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Enter(this, obj);
            RequestStage stageMode = RequestStage.CheckForError;

            try
            {
                FtpControlStream connection;
                connection = obj as FtpControlStream;
                FtpDataStream stream = obj as FtpDataStream;
                Exception exception = obj as Exception;

                bool completedRequest = (obj == null);

                if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"stream:{stream} conn:{connection} exp:{exception} completedRequest:{completedRequest}");
                while (true)
                {
                    if (exception != null)
                    {
                        if (AttemptedRecovery(exception))
                        {
                            connection = CreateConnection();
                            if (connection == null)
                                return;

                            exception = null;
                        }
                        if (exception != null)
                        {
                            SetException(exception);
                            break;
                        }
                    }

                    if (connection != null)
                    {
                        lock (_syncObject)
                        {
                            if (_aborted)
                            {
                                if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Releasing connect:{connection}");
                                connection.CloseSocket();
                                break;
                            }
                            _connection = connection;
                            if (NetEventSource.IsEnabled) NetEventSource.Associate(this, _connection);
                        }

                        try
                        {
                            stream = (FtpDataStream)TimedSubmitRequestHelper(true);
                        }
                        catch (Exception e)
                        {
                            exception = e;
                            continue;
                        }
                        return;
                    }
                    else if (stream != null)
                    {
                        lock (_syncObject)
                        {
                            if (_aborted)
                            {
                                ((ICloseEx)stream).CloseEx(CloseExState.Abort | CloseExState.Silent);
                                break;
                            }
                            _stream = stream;
                        }

                        stream.SetSocketTimeoutOption(Timeout);
                        EnsureFtpWebResponse(null);

                        stageMode = stream.CanRead ? RequestStage.ReadReady : RequestStage.WriteReady;
                    }
                    else if (completedRequest)
                    {
                        connection = _connection;

                        if (connection != null)
                        {
                            EnsureFtpWebResponse(null);

                            // This to update response status and exit message if any.
                            // Note that the status 221 "Service closing control connection" is always suppressed.
                            _ftpWebResponse.UpdateStatus(connection.StatusCode, connection.StatusLine, connection.ExitMessage);
                        }

                        stageMode = RequestStage.ReleaseConnection;
                    }
                    else
                    {
                        throw new InternalException();
                    }
                    break;
                }
            }
            catch (Exception exception)
            {
                SetException(exception);
            }
            finally
            {
                FinishRequestStage(stageMode);
                if (NetEventSource.IsEnabled) NetEventSource.Exit(this);
            }
        }
Esempio n. 11
0
        /// <summary>
        ///    <para>Returns true if we should restart the request after an error</para>
        /// </summary>
        private bool AttemptedRecovery(Exception e)
        {
            if (e is OutOfMemoryException
                || _onceFailed
                || _aborted
                || _timedOut
                || _connection == null
                || !_connection.RecoverableFailure)
            {
                return false;
            }
            _onceFailed = true;

            lock (_syncObject)
            {
                if (_connection != null)
                {
                    _connection.CloseSocket();
                    if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Releasing connection: {_connection}");
                    _connection = null;
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
Esempio n. 12
0
        private async void CreateConnectionAsync()
        {
            string hostname = _uri.Host;
            int port = _uri.Port;

            TcpClient client = new TcpClient();

            object result;
            try
            {
                await client.ConnectAsync(hostname, port).ConfigureAwait(false);
                result = new FtpControlStream(client);
            }
            catch (Exception e)
            {
                result = TranslateConnectException(e);
            }

            AsyncRequestCallback(result);
        }
Esempio n. 13
0
        //
        // Only executed for Async requests
        //
        private void AsyncRequestCallback(object obj)
        {
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Enter("FtpWebRequest#" + LoggingHash.HashString(this) + "::AsyncRequestCallback", "#" + LoggingHash.HashString(obj));
            }
            RequestStage stageMode = RequestStage.CheckForError;

            try
            {
                FtpControlStream connection;
                connection = obj as FtpControlStream;
                FtpDataStream stream = obj as FtpDataStream;
                Exception exception = obj as Exception;

                bool completedRequest = (obj == null);

                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print("AsyncRequestCallback()  stream:" + LoggingHash.HashString(stream) + " conn:" + LoggingHash.HashString(connection) + " exp:" + LoggingHash.HashString(exception) + " completedRequest:" + LoggingHash.HashString(completedRequest));
                }
                while (true)
                {
                    if (exception != null)
                    {
                        if (AttemptedRecovery(exception))
                        {
                            connection = CreateConnection();
                            if (connection == null)
                                return;

                            exception = null;
                        }
                        if (exception != null)
                        {
                            SetException(exception);
                            break;
                        }
                    }

                    if (connection != null)
                    {
                        lock (_syncObject)
                        {
                            if (_aborted)
                            {
                                if (NetEventSource.Log.IsEnabled())
                                    NetEventSource.PrintInfo(NetEventSource.ComponentType.Web, this, "", string.Format("Releasing connection: {0}", LoggingHash.HashString(connection)));
                                connection.CloseSocket();
                                break;
                            }
                            _connection = connection;
                            if (NetEventSource.Log.IsEnabled())
                                NetEventSource.Associate(NetEventSource.ComponentType.Web, this, _connection);
                        }

                        try
                        {
                            stream = (FtpDataStream)TimedSubmitRequestHelper(true);
                        }
                        catch (Exception e)
                        {
                            exception = e;
                            continue;
                        }
                        return;
                    }
                    else if (stream != null)
                    {
                        lock (_syncObject)
                        {
                            if (_aborted)
                            {
                                ((ICloseEx)stream).CloseEx(CloseExState.Abort | CloseExState.Silent);
                                break;
                            }
                            _stream = stream;
                        }

                        stream.SetSocketTimeoutOption(Timeout);
                        EnsureFtpWebResponse(null);

                        stageMode = stream.CanRead ? RequestStage.ReadReady : RequestStage.WriteReady;
                    }
                    else if (completedRequest)
                    {
                        connection = _connection;

                        if (connection != null)
                        {
                            EnsureFtpWebResponse(null);

                            // This to update response status and exit message if any.
                            // Note that the status 221 "Service closing control connection" is always suppressed.
                            _ftpWebResponse.UpdateStatus(connection.StatusCode, connection.StatusLine, connection.ExitMessage);
                        }

                        stageMode = RequestStage.ReleaseConnection;
                    }
                    else
                    {
                        throw new InternalException();
                    }
                    break;
                }
            }
            catch (Exception exception)
            {
                SetException(exception);
            }
            finally
            {
                FinishRequestStage(stageMode);
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Leave("FtpWebRequest#" + LoggingHash.HashString(this) + "::AsyncRequestCallback");
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        ///    <para>Returns true if we should restart the request after an error</para>
        /// </summary>
        private bool AttemptedRecovery(Exception e)
        {
            if (e is OutOfMemoryException
                || _onceFailed
                || _aborted
                || _timedOut
                || _connection == null
                || !_connection.RecoverableFailure)
            {
                return false;
            }
            _onceFailed = true;

            lock (_syncObject)
            {
                if (_connection != null)
                {
                    _connection.CloseSocket();
                    if (NetEventSource.Log.IsEnabled())
                        NetEventSource.PrintInfo(NetEventSource.ComponentType.Web, this, "", string.Format("Releasing connection: {0}", LoggingHash.HashString(_connection)));
                    _connection = null;
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
 private void AsyncRequestCallback(object obj)
 {
     RequestStage checkForError = RequestStage.CheckForError;
     try
     {
         FtpControlStream objectValue = obj as FtpControlStream;
         FtpDataStream stream2 = obj as FtpDataStream;
         Exception e = obj as Exception;
         bool flag = obj == null;
     Label_001D:
         if (e != null)
         {
             if (this.AttemptedRecovery(e))
             {
                 objectValue = this.QueueOrCreateConnection();
                 if (objectValue == null)
                 {
                     return;
                 }
                 e = null;
             }
             if (e != null)
             {
                 this.SetException(e);
                 return;
             }
         }
         if (objectValue != null)
         {
             lock (this.m_SyncObject)
             {
                 if (this.m_Aborted)
                 {
                     if (Logging.On)
                     {
                         Logging.PrintInfo(Logging.Web, this, "", SR.GetString("net_log_releasing_connection", new object[] { ValidationHelper.HashString(objectValue) }));
                     }
                     this.m_ConnectionPool.PutConnection(objectValue, this, this.Timeout);
                     return;
                 }
                 this.m_Connection = objectValue;
                 if (Logging.On)
                 {
                     Logging.Associate(Logging.Web, this, this.m_Connection);
                 }
             }
             try
             {
                 stream2 = (FtpDataStream) this.TimedSubmitRequestHelper(true);
             }
             catch (Exception exception2)
             {
                 e = exception2;
                 goto Label_001D;
             }
         }
         else if (stream2 != null)
         {
             lock (this.m_SyncObject)
             {
                 if (this.m_Aborted)
                 {
                     ((ICloseEx) stream2).CloseEx(CloseExState.Silent | CloseExState.Abort);
                     return;
                 }
                 this.m_Stream = stream2;
             }
             stream2.SetSocketTimeoutOption(SocketShutdown.Both, this.Timeout, true);
             this.EnsureFtpWebResponse(null);
             this.CheckCacheRetrieveOnResponse();
             this.CheckCacheUpdateOnResponse();
             checkForError = stream2.CanRead ? RequestStage.ReadReady : RequestStage.WriteReady;
         }
         else
         {
             if (!flag)
             {
                 throw new InternalException();
             }
             objectValue = this.m_Connection;
             bool flag4 = false;
             if (objectValue != null)
             {
                 this.EnsureFtpWebResponse(null);
                 this.m_FtpWebResponse.UpdateStatus(objectValue.StatusCode, objectValue.StatusLine, objectValue.ExitMessage);
                 flag4 = !this.m_CacheDone && ((base.CacheProtocol.ProtocolStatus == CacheValidationStatus.Continue) || (base.CacheProtocol.ProtocolStatus == CacheValidationStatus.RetryResponseFromServer));
                 lock (this.m_SyncObject)
                 {
                     if (!this.CheckCacheRetrieveOnResponse())
                     {
                         goto Label_001D;
                     }
                     if (this.m_FtpWebResponse.IsFromCache)
                     {
                         flag4 = false;
                     }
                     this.CheckCacheUpdateOnResponse();
                 }
             }
             if (!flag4)
             {
                 checkForError = RequestStage.ReleaseConnection;
             }
         }
     }
     catch (Exception exception3)
     {
         this.SetException(exception3);
     }
     finally
     {
         this.FinishRequestStage(checkForError);
     }
 }
        /// <summary>
        ///    <para>Returns true if we should restart the request after an error</para>
        /// </summary>
        private bool AttemptedRecovery(Exception e) {
            // The first 'if' is just checking whether the exception is thrown due to the
            // relogin failure which is a recoverable error
            if (!(e is WebException && ((WebException)e).InternalStatus == WebExceptionInternalStatus.Isolated))
            {
                if (e is ThreadAbortException
                    || e is StackOverflowException
                    || e is OutOfMemoryException
                    || m_OnceFailed
                    || m_Aborted
                    || m_TimedOut
                    || m_Connection==null
                    || !m_Connection.RecoverableFailure)
                {
                    return false;
                }
                m_OnceFailed = true;
            }

            lock (m_SyncObject) {
                if (m_ConnectionPool != null && m_Connection != null) {
                    m_Connection.CloseSocket();
                    if (Logging.On) Logging.PrintInfo(Logging.Web, this, "", SR.GetString(SR.net_log_releasing_connection, ValidationHelper.HashString(m_Connection)));
                    m_ConnectionPool.PutConnection(m_Connection, this, RemainingTimeout);
                    m_Connection = null;
                } else {
                    return false;
                }
            }
            return true;
        }
        //
        //
        //
        private FtpControlStream QueueOrCreateConnection()
        {
            FtpControlStream connection = (FtpControlStream) m_ConnectionPool.GetConnection((object)this, (m_Async ? m_AsyncCallback : null), (m_Async ? -1: RemainingTimeout));

            if (connection == null)
            {
                GlobalLog.Assert(m_Async, "QueueOrCreateConnection|m_ConnectionPool.GetConnection() returned null on a Sync Request.");
                return null;
            }

            lock (m_SyncObject)
            {
                if (m_Aborted)
                {
                    if (Logging.On) Logging.PrintInfo(Logging.Web, this, "", SR.GetString(SR.net_log_releasing_connection, ValidationHelper.HashString(connection)));
                    m_ConnectionPool.PutConnection(connection, this, RemainingTimeout);
                    CheckError(); //must throw
                    throw new InternalException();
                }
                m_Connection = connection;
                if (Logging.On) Logging.Associate(Logging.Web, this, m_Connection);
            }
            return connection;
        }
 private bool AttemptedRecovery(Exception e)
 {
     if (!(e is WebException) || (((WebException) e).InternalStatus != WebExceptionInternalStatus.Isolated))
     {
         if ((((e is ThreadAbortException) || (e is StackOverflowException)) || ((e is OutOfMemoryException) || this.m_OnceFailed)) || ((this.m_Aborted || this.m_TimedOut) || ((this.m_Connection == null) || !this.m_Connection.RecoverableFailure)))
         {
             return false;
         }
         this.m_OnceFailed = true;
     }
     lock (this.m_SyncObject)
     {
         if ((this.m_ConnectionPool != null) && (this.m_Connection != null))
         {
             this.m_Connection.CloseSocket();
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.Web, this, "", SR.GetString("net_log_releasing_connection", new object[] { ValidationHelper.HashString(this.m_Connection) }));
             }
             this.m_ConnectionPool.PutConnection(this.m_Connection, this, this.RemainingTimeout);
             this.m_Connection = null;
         }
         else
         {
             return false;
         }
     }
     return true;
 }
 private RequestStage FinishRequestStage(RequestStage stage)
 {
     RequestStage requestStage;
     LazyAsyncResult writeAsyncResult;
     LazyAsyncResult readAsyncResult;
     FtpControlStream connection;
     RequestStage stage3;
     if (this.m_Exception != null)
     {
         stage = RequestStage.ReleaseConnection;
     }
     lock (this.m_SyncObject)
     {
         requestStage = this.m_RequestStage;
         if (stage == RequestStage.CheckForError)
         {
             return requestStage;
         }
         if ((requestStage == RequestStage.ReleaseConnection) && (stage == RequestStage.ReleaseConnection))
         {
             return RequestStage.ReleaseConnection;
         }
         if (stage > requestStage)
         {
             this.m_RequestStage = stage;
         }
         if (stage <= RequestStage.RequestStarted)
         {
             return requestStage;
         }
         writeAsyncResult = this.m_WriteAsyncResult;
         readAsyncResult = this.m_ReadAsyncResult;
         connection = this.m_Connection;
         if (stage == RequestStage.ReleaseConnection)
         {
             if ((((this.m_Exception == null) && !this.m_Aborted) && ((requestStage != RequestStage.ReadReady) && this.m_MethodInfo.IsDownload)) && !this.m_FtpWebResponse.IsFromCache)
             {
                 return requestStage;
             }
             if (((this.m_Exception != null) || !this.m_FtpWebResponse.IsFromCache) || this.KeepAlive)
             {
                 this.m_Connection = null;
             }
         }
     }
     try
     {
         if (((stage == RequestStage.ReleaseConnection) || (requestStage == RequestStage.ReleaseConnection)) && (connection != null))
         {
             try
             {
                 if (this.m_Exception != null)
                 {
                     connection.Abort(this.m_Exception);
                 }
                 else if (this.m_FtpWebResponse.IsFromCache && !this.KeepAlive)
                 {
                     connection.Quit();
                 }
             }
             finally
             {
                 if (Logging.On)
                 {
                     Logging.PrintInfo(Logging.Web, this, "", SR.GetString("net_log_releasing_connection", new object[] { ValidationHelper.HashString(connection) }));
                 }
                 this.m_ConnectionPool.PutConnection(connection, this, this.RemainingTimeout);
                 if (this.m_Async && (this.m_RequestCompleteAsyncResult != null))
                 {
                     this.m_RequestCompleteAsyncResult.InvokeCallback();
                 }
             }
         }
         stage3 = requestStage;
     }
     finally
     {
         try
         {
             if (stage >= RequestStage.WriteReady)
             {
                 if (this.m_MethodInfo.IsUpload && !this.m_GetRequestStreamStarted)
                 {
                     if (this.m_Stream != null)
                     {
                         this.m_Stream.Close();
                     }
                 }
                 else if ((writeAsyncResult != null) && !writeAsyncResult.InternalPeekCompleted)
                 {
                     writeAsyncResult.InvokeCallback();
                 }
             }
         }
         finally
         {
             if (((stage >= RequestStage.ReadReady) && (readAsyncResult != null)) && !readAsyncResult.InternalPeekCompleted)
             {
                 readAsyncResult.InvokeCallback();
             }
         }
     }
     return stage3;
 }
        //
        // Returns a previous stage
        //
        private RequestStage FinishRequestStage(RequestStage stage)
        {
            GlobalLog.Print("FtpWebRequest#" + ValidationHelper.HashString(this) + "::FinishRequestStage : stage="+stage);
            if (m_Exception != null)
                stage = RequestStage.ReleaseConnection;

            RequestStage     prev;
            LazyAsyncResult  writeResult;
            LazyAsyncResult  readResult;
            FtpControlStream connection;

            lock (m_SyncObject)
            {
                prev = m_RequestStage;

                if (stage == RequestStage.CheckForError)
                    return prev;

                if (prev == RequestStage.ReleaseConnection && 
                    stage == RequestStage.ReleaseConnection)
                {
                    return RequestStage.ReleaseConnection;
                }

                if (stage > prev)
                    m_RequestStage = stage;

                if (stage <= RequestStage.RequestStarted)
                    return prev;

                writeResult  = m_WriteAsyncResult;
                readResult   = m_ReadAsyncResult;
                connection   = m_Connection;

                if (stage == RequestStage.ReleaseConnection)
                {
                    if (m_Exception == null &&
                        !m_Aborted &&
                        prev != RequestStage.ReadReady &&
                        this.m_MethodInfo.IsDownload && 
                        !m_FtpWebResponse.IsFromCache)
                    {
                        return prev;
                    }
                    if (m_Exception != null || !(m_FtpWebResponse.IsFromCache && !KeepAlive))
                        m_Connection = null;
                }
            }

            try {
                // First check to see on releasing the connection
                if ((stage == RequestStage.ReleaseConnection ||
                     prev  == RequestStage.ReleaseConnection)
                    && connection != null)
                {
                    try {
                        if (m_Exception != null)
                        {
                            connection.Abort(m_Exception);
                        }
                        else if (m_FtpWebResponse.IsFromCache && !KeepAlive)
                        {
                            // This means the response has been revalidated and found as good means the commands pipleline is completed.
                            // Now if this request was NOT KeepAlive we want to be fair and close the control connection.
                            // That becomes unnecessary complicated in the async case to support "QUIT" command semantic, so simply close the socket
                            // and let pool collect the object.
                            connection.Quit();
                        }
                    } finally {
                        if (Logging.On) Logging.PrintInfo(Logging.Web, this, "", SR.GetString(SR.net_log_releasing_connection, ValidationHelper.HashString(connection)));
                        m_ConnectionPool.PutConnection(connection, this, RemainingTimeout);
                        if (m_Async)
                            if (m_RequestCompleteAsyncResult != null)
                                m_RequestCompleteAsyncResult.InvokeCallback();
                    }
                }
                return prev;
            }
            finally {
                try {
                    // In any case we want to signal the writer if came here
                    if (stage >= RequestStage.WriteReady) {
                        // If writeResult == null and this is an upload request, it means
                        // that the user has called GetResponse() without calling 
                        // GetRequestStream() first. So they are not interested in a 
                        // stream. Therefore we close the stream so that the 
                        // request/pipeline can continue
                        if (m_MethodInfo.IsUpload && !m_GetRequestStreamStarted)
                        {
                            if (m_Stream != null)
                                m_Stream.Close();
                        }
                        else if (writeResult != null && !writeResult.InternalPeekCompleted)
                            writeResult.InvokeCallback();
                    }
                }
                finally {
                    // The response is ready either with or without a stream
                    if (stage >= RequestStage.ReadReady && readResult != null && !readResult.InternalPeekCompleted)
                        readResult.InvokeCallback();
                }
            }
        }
 private FtpControlStream QueueOrCreateConnection()
 {
     FtpControlStream objectValue = (FtpControlStream) this.m_ConnectionPool.GetConnection(this, this.m_Async ? m_AsyncCallback : null, this.m_Async ? -1 : this.RemainingTimeout);
     if (objectValue == null)
     {
         return null;
     }
     lock (this.m_SyncObject)
     {
         if (this.m_Aborted)
         {
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.Web, this, "", SR.GetString("net_log_releasing_connection", new object[] { ValidationHelper.HashString(objectValue) }));
             }
             this.m_ConnectionPool.PutConnection(objectValue, this, this.RemainingTimeout);
             this.CheckError();
             throw new InternalException();
         }
         this.m_Connection = objectValue;
         if (Logging.On)
         {
             Logging.Associate(Logging.Web, this, this.m_Connection);
         }
     }
     return objectValue;
 }