HttpBufferlessInputStream.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / HttpBufferlessInputStream.cs / 1305376 / HttpBufferlessInputStream.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 * Bufferless Input stream used in response and uploaded file objects 
 *
 * Copyright (c) 2009 Microsoft Corporation 
 */

namespace System.Web {
 
    using System.IO;
    using System.Security; 
    using System.Security.Permissions; 
    using System.Web.Hosting;
    using System.Web.Configuration; 
    using System.Web.Management;

    internal class HttpBufferlessInputStream : Stream {
        private long           _CurrentPosition    = 0; 
        private long           _Length             = -1;
        private long           _MaxRequestLength; 
        private bool           _PreloadedConsumed  = false; 
        private bool           _MaxLengthRead = false;
        private HttpContext    _Context; 
        // private Stream         _PreviousReadSteam;

        internal HttpBufferlessInputStream(HttpContext context /*, Stream previousReadSteam*/ ) {
            _Context = context; 
            //_PreviousReadSteam = previousReadSteam;
        } 
 
        /////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////
        public override bool CanRead {
            get {
                return true; 
            }
        } 
 
        public override bool CanSeek {
            get { 
                return false;
            }
        }
 
        public override bool CanWrite {
            get { 
                return false; 
            }
        } 

        public override long Length {
            get {
                //if (_PreviousReadSteam != null) 
                //    return _PreviousReadSteam.Length;
                if (_Length < 0) 
                    _Length = _Context.Request.ContentLength; 
                return _Length;
            } 
        }

        public override long Position {
            get { 
                //if (_PreviousReadSteam != null)
                //    return _PreviousReadSteam.Position; 
                return _CurrentPosition; 
            }
            set { 
                throw new NotSupportedException();
            }
        }
 
        public override void Flush() {
        } 
 
        public override void SetLength(long length) {
            throw new NotSupportedException(); 
        }
        public override long Seek(long offset, SeekOrigin origin) {
            throw new NotSupportedException();
        } 

        public override void Write(byte[] buffer, int offset, int count) { 
            throw new NotSupportedException(); 
        }
 
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        public override int Read(byte[] buffer, int offset, int count) { 
            //if (_PreviousReadSteam != null)
            //    return _PreviousReadSteam.Read(buffer, offset, count); 
 
            if (_Context.WorkerRequest == null || count == 0)
                return 0; 
            if (buffer == null)
                throw new ArgumentNullException("buffer");
            if (offset < 0 || offset + count > buffer.Length)
                throw new ArgumentException(null, "offset"); 
            if (count < 0)
                throw new ArgumentException(null, "count"); 
 
            int numBytesRead = 0;
 
            //////////////////////////////////////////////////////////////////
            // Step 1: Check max-request-length for preloaded content
            if (!_MaxLengthRead) {
                _MaxRequestLength = RuntimeConfig.GetConfig(_Context).HttpRuntime.MaxRequestLengthBytes; 
                if (Length > _MaxRequestLength) {
                    if ( !(_Context.WorkerRequest is IIS7WorkerRequest) ) { 
                        _Context.Response.CloseConnectionAfterError(); 
                    }
                    throw new HttpException(SR.GetString(SR.Max_request_length_exceeded), null, WebEventCodes.RuntimeErrorPostTooLarge); 
                }
                _MaxLengthRead = true;
            }
 

            ////////////////////////////////////////////////////////////////// 
            // Step 2: Consume preloaded content 
            if (!_PreloadedConsumed) {
                // Get the preloaded content 
                byte [] preloadedContent = _Context.WorkerRequest.GetPreloadedEntityBody();
                if (preloadedContent != null) {

                    // Figure out how much of the preloaded content we can use 
                    int preloadedRemaining = preloadedContent.Length - (int) _CurrentPosition;
                    int bytesRead = Math.Min(count, preloadedRemaining); 
 
                    // Copy the preloaded content
                    Buffer.BlockCopy(preloadedContent, (int) _CurrentPosition, buffer, offset, bytesRead); 
                    UpdateCounters(bytesRead, ref offset, ref count, ref numBytesRead);
                    _PreloadedConsumed = (numBytesRead == preloadedRemaining); // did we use up all the preloaded content
                }
                else { 
                    _PreloadedConsumed = true;
                } 
            } 

            // We are done if the count == 0 or there is no more content 
            if (count == 0 || _Context.WorkerRequest.IsEntireEntityBodyIsPreloaded())
                return numBytesRead;

            ////////////////////////////////////////////////////////////////// 
            // Step 4: Read entity body in a loop
            while (count > 0) { 
                // Figure out how much to read 
                long currentLimit = _MaxRequestLength - _CurrentPosition; // Number of bytes we can read before crossing the limit
                int bytesToRead = (int) Math.Min((long) Int32.MaxValue, Math.Min(count, currentLimit + 1)); // Read at-most 1 byte over the limit 

                // Do the actual read
                int bytesRead = _Context.WorkerRequest.ReadEntityBody(buffer, offset, bytesToRead);
                if (bytesRead <= 0) { // nothing left to read 
                    if (!_Context.WorkerRequest.IsClientConnected())
                        throw new HttpException(SR.GetString(SR.ViewState_ClientDisconnected)); 
                    break; 
                }
                UpdateCounters(bytesRead, ref offset, ref count, ref numBytesRead); 
            }
            return numBytesRead;
        }
 
        /////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////// 
        // Helper function to increment variables in Read API 
        private void UpdateCounters(int bytesRead, ref int offset, ref int count, ref int numBytesRead) {
            _Context.WorkerRequest.UpdateRequestCounters(bytesRead); 
            count -= bytesRead;
            offset += bytesRead;
            _CurrentPosition += bytesRead;
            numBytesRead += bytesRead; 
            if (_Length < _CurrentPosition)
                _Length = _CurrentPosition; 
            if (Length > _MaxRequestLength) { 
                if ( !(_Context.WorkerRequest is IIS7WorkerRequest) ) {
                    _Context.Response.CloseConnectionAfterError(); 
                }
                throw new HttpException(SR.GetString(SR.Max_request_length_exceeded), null, WebEventCodes.RuntimeErrorPostTooLarge);
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 * Bufferless Input stream used in response and uploaded file objects 
 *
 * Copyright (c) 2009 Microsoft Corporation 
 */

namespace System.Web {
 
    using System.IO;
    using System.Security; 
    using System.Security.Permissions; 
    using System.Web.Hosting;
    using System.Web.Configuration; 
    using System.Web.Management;

    internal class HttpBufferlessInputStream : Stream {
        private long           _CurrentPosition    = 0; 
        private long           _Length             = -1;
        private long           _MaxRequestLength; 
        private bool           _PreloadedConsumed  = false; 
        private bool           _MaxLengthRead = false;
        private HttpContext    _Context; 
        // private Stream         _PreviousReadSteam;

        internal HttpBufferlessInputStream(HttpContext context /*, Stream previousReadSteam*/ ) {
            _Context = context; 
            //_PreviousReadSteam = previousReadSteam;
        } 
 
        /////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////
        public override bool CanRead {
            get {
                return true; 
            }
        } 
 
        public override bool CanSeek {
            get { 
                return false;
            }
        }
 
        public override bool CanWrite {
            get { 
                return false; 
            }
        } 

        public override long Length {
            get {
                //if (_PreviousReadSteam != null) 
                //    return _PreviousReadSteam.Length;
                if (_Length < 0) 
                    _Length = _Context.Request.ContentLength; 
                return _Length;
            } 
        }

        public override long Position {
            get { 
                //if (_PreviousReadSteam != null)
                //    return _PreviousReadSteam.Position; 
                return _CurrentPosition; 
            }
            set { 
                throw new NotSupportedException();
            }
        }
 
        public override void Flush() {
        } 
 
        public override void SetLength(long length) {
            throw new NotSupportedException(); 
        }
        public override long Seek(long offset, SeekOrigin origin) {
            throw new NotSupportedException();
        } 

        public override void Write(byte[] buffer, int offset, int count) { 
            throw new NotSupportedException(); 
        }
 
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        public override int Read(byte[] buffer, int offset, int count) { 
            //if (_PreviousReadSteam != null)
            //    return _PreviousReadSteam.Read(buffer, offset, count); 
 
            if (_Context.WorkerRequest == null || count == 0)
                return 0; 
            if (buffer == null)
                throw new ArgumentNullException("buffer");
            if (offset < 0 || offset + count > buffer.Length)
                throw new ArgumentException(null, "offset"); 
            if (count < 0)
                throw new ArgumentException(null, "count"); 
 
            int numBytesRead = 0;
 
            //////////////////////////////////////////////////////////////////
            // Step 1: Check max-request-length for preloaded content
            if (!_MaxLengthRead) {
                _MaxRequestLength = RuntimeConfig.GetConfig(_Context).HttpRuntime.MaxRequestLengthBytes; 
                if (Length > _MaxRequestLength) {
                    if ( !(_Context.WorkerRequest is IIS7WorkerRequest) ) { 
                        _Context.Response.CloseConnectionAfterError(); 
                    }
                    throw new HttpException(SR.GetString(SR.Max_request_length_exceeded), null, WebEventCodes.RuntimeErrorPostTooLarge); 
                }
                _MaxLengthRead = true;
            }
 

            ////////////////////////////////////////////////////////////////// 
            // Step 2: Consume preloaded content 
            if (!_PreloadedConsumed) {
                // Get the preloaded content 
                byte [] preloadedContent = _Context.WorkerRequest.GetPreloadedEntityBody();
                if (preloadedContent != null) {

                    // Figure out how much of the preloaded content we can use 
                    int preloadedRemaining = preloadedContent.Length - (int) _CurrentPosition;
                    int bytesRead = Math.Min(count, preloadedRemaining); 
 
                    // Copy the preloaded content
                    Buffer.BlockCopy(preloadedContent, (int) _CurrentPosition, buffer, offset, bytesRead); 
                    UpdateCounters(bytesRead, ref offset, ref count, ref numBytesRead);
                    _PreloadedConsumed = (numBytesRead == preloadedRemaining); // did we use up all the preloaded content
                }
                else { 
                    _PreloadedConsumed = true;
                } 
            } 

            // We are done if the count == 0 or there is no more content 
            if (count == 0 || _Context.WorkerRequest.IsEntireEntityBodyIsPreloaded())
                return numBytesRead;

            ////////////////////////////////////////////////////////////////// 
            // Step 4: Read entity body in a loop
            while (count > 0) { 
                // Figure out how much to read 
                long currentLimit = _MaxRequestLength - _CurrentPosition; // Number of bytes we can read before crossing the limit
                int bytesToRead = (int) Math.Min((long) Int32.MaxValue, Math.Min(count, currentLimit + 1)); // Read at-most 1 byte over the limit 

                // Do the actual read
                int bytesRead = _Context.WorkerRequest.ReadEntityBody(buffer, offset, bytesToRead);
                if (bytesRead <= 0) { // nothing left to read 
                    if (!_Context.WorkerRequest.IsClientConnected())
                        throw new HttpException(SR.GetString(SR.ViewState_ClientDisconnected)); 
                    break; 
                }
                UpdateCounters(bytesRead, ref offset, ref count, ref numBytesRead); 
            }
            return numBytesRead;
        }
 
        /////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////// 
        // Helper function to increment variables in Read API 
        private void UpdateCounters(int bytesRead, ref int offset, ref int count, ref int numBytesRead) {
            _Context.WorkerRequest.UpdateRequestCounters(bytesRead); 
            count -= bytesRead;
            offset += bytesRead;
            _CurrentPosition += bytesRead;
            numBytesRead += bytesRead; 
            if (_Length < _CurrentPosition)
                _Length = _CurrentPosition; 
            if (Length > _MaxRequestLength) { 
                if ( !(_Context.WorkerRequest is IIS7WorkerRequest) ) {
                    _Context.Response.CloseConnectionAfterError(); 
                }
                throw new HttpException(SR.GetString(SR.Max_request_length_exceeded), null, WebEventCodes.RuntimeErrorPostTooLarge);
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK