System.Net.ConnectStream.DrainSocket C# (CSharp) Method

DrainSocket() private method

private DrainSocket ( ) : bool
return bool
        private bool DrainSocket() {
            GlobalLog.Enter("ConnectStream::DrainSocket");
            GlobalLog.ThreadContract(ThreadKinds.Unknown, "ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket");

            if (IgnoreSocketErrors)
            {
                GlobalLog.Leave("ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket() IgnoreSocketErrors == true, stream is dead.", true);
                return true;
            }

            //
            // If its not chunked and we have a read buffer, don't waste time coping the data
            //  around againg, just pretend its gone, i.exception. make it die
            //
            long ReadBytes = m_ReadBytes;

            if (!m_Chunked) {

                GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket() m_ReadBytes:" + m_ReadBytes.ToString() + " m_ReadBufferSize:" + m_ReadBufferSize.ToString());

                if (m_ReadBufferSize != 0) {
                    //
                    // There's stuff in our read buffer.
                    // Update our internal read buffer state with what we took.
                    //
                    m_ReadOffset += m_ReadBufferSize;

                    GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket() m_ReadBytes:" + m_ReadBytes.ToString() + " m_ReadOffset:" + m_ReadOffset.ToString());

                    if (m_ReadBytes != -1) {

                        m_ReadBytes -= m_ReadBufferSize;

                        GlobalLog.Print("m_ReadBytes = "+m_ReadBytes);

                        // error handling, we shouldn't hang here if trying to drain, and there
                        //  is a mismatch with Content-Length and actual bytes.
                        //
                        //  Note: I've seen this often happen with some sites where they return 204
                        //  in violation of HTTP/1.1 with a Content-Length > 0

                        if (m_ReadBytes < 0) {
                            GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket() m_ReadBytes:" + m_ReadBytes.ToString() + " incorrect Content-Length? setting m_ReadBytes to 0 and returning false.");
                            m_ReadBytes = 0;
                            GlobalLog.Leave("ConnectStream::DrainSocket", false);
                            return false;
                        }
                    }
                    m_ReadBufferSize = 0;

                    // If the read buffer size has gone to 0, null out our pointer
                    // to it so maybe it'll be garbage-collected faster.
                    m_ReadBuffer = null;
                }

                // exit out of drain Socket when there is no connection-length,
                // it doesn't make sense to drain a possible empty socket,
                // when we're just going to close it.
                if (ReadBytes == -1) {
                    GlobalLog.Leave("ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket() ReadBytes==-1, returning true");
                    return true;
                }
            }

            //
            // in error or Eof, we may be in a weird state
            //  so we need return if we as if we don't have any more
            //  space to read, note Eof is true when there is an error
            //

            if (this.Eof) {
                GlobalLog.Leave("ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket() Eof, returning true");
                return true;
            }


            //
            // If we're draining more than 64K, then we should
            //  just close the socket, since it would be costly to
            //  do this.
            //

            if (m_ReadBytes > c_MaxDrainBytes) {
                GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket() m_ReadBytes:" + m_ReadBytes.ToString() + " too large, Closing the Connection");
                m_Connection.AbortSocket(false);
                GlobalLog.Leave("ConnectStream::DrainSocket", true);
                return true;
            }

            //
            // Now drain the socket the old, slow way by reading or pasing Chunked stuff
            //
            m_Draining = true;
            int bytesRead;
            for (;;) {
                try {
                    bytesRead = ReadWithoutValidation(s_DrainingBuffer, 0, s_DrainingBuffer.Length, false);
                    GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::DrainSocket() drained bytesRead:" + bytesRead.ToString() + " bytes");
                    if (bytesRead<=0) {
                        break;
                    }
                }
                catch (Exception exception) {
                    if (NclUtilities.IsFatal(exception)) throw;

                    GlobalLog.Print("exception" + exception.ToString());
                    bytesRead = -1;
                    break;
                }
            }
            GlobalLog.Leave("ConnectStream::DrainSocket", true);
            return bytesRead > 0;
        }