StateWorkerRequest.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / State / StateWorkerRequest.cs / 1305376 / StateWorkerRequest.cs

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

/* 
 * StateHttpWorkerRequest 
 *
 * Copyright (c) 1998-1999, Microsoft Corporation 
 *
 */

namespace System.Web.SessionState { 

    using System.Text; 
    using System.Configuration.Assemblies; 
    using System.Runtime.InteropServices;
    using System.Collections; 
    using System.Web;
    using System.Web.Util;
    using System.Globalization;
 
    class StateHttpWorkerRequest : HttpWorkerRequest {
        // 
        const int ADDRESS_LENGTH_MAX = 15; /* "xxx.xxx.xxx.xxx" */ 

        IntPtr                                  _tracker; 
        string                                  _uri;
        UnsafeNativeMethods.StateProtocolExclusive    _exclusive;
        int                                     _extraFlags;
        int                                     _timeout; 
        int                                     _lockCookie;
        bool                                    _lockCookieExists; 
        int                                     _contentLength; 
        byte[]                                  _content;
 

        UnsafeNativeMethods.StateProtocolVerb   _methodIndex;
        string                                  _method;
 
        string                                  _remoteAddress;
        int                                     _remotePort; 
        string                                  _localAddress; 
        int                                     _localPort;
 
        StringBuilder                           _status;
        int                                     _statusCode;
        StringBuilder                           _headers;
        IntPtr                           _unmanagedState; 
        bool                                    _sent;
 
        internal StateHttpWorkerRequest( 
                   IntPtr tracker,
                   UnsafeNativeMethods.StateProtocolVerb methodIndex, 
                   string uri,
                   UnsafeNativeMethods.StateProtocolExclusive exclusive,
                   int extraFlags,
                   int timeout, 
                   int lockCookieExists,
                   int lockCookie, 
                   int contentLength, 
                   IntPtr content
                   ) { 
            _tracker = tracker;
            _methodIndex = methodIndex;
            switch (_methodIndex) {
                case UnsafeNativeMethods.StateProtocolVerb.GET: 
                    _method = "GET";
                    break; 
 
                case UnsafeNativeMethods.StateProtocolVerb.PUT:
                    _method = "PUT"; 
                    break;

                case UnsafeNativeMethods.StateProtocolVerb.HEAD:
                    _method = "HEAD"; 
                    break;
 
                case UnsafeNativeMethods.StateProtocolVerb.DELETE: 
                    _method = "DELETE";
                    break; 

                default:
                    Debug.Assert(false, "Shouldn't get here!");
                    break; 
            }
 
            _uri = uri; 
            // Handle the ASP1.1 case which prepends an extra / to the URI
            if (_uri.StartsWith("//", StringComparison.Ordinal)) { 
                _uri = _uri.Substring(1);
            }
            _exclusive = exclusive;
            _extraFlags = extraFlags; 
            _timeout = timeout;
            _lockCookie = lockCookie; 
            _lockCookieExists = lockCookieExists != 0; 
            _contentLength = contentLength;
            if (contentLength != 0) { 
                Debug.Assert(_contentLength == IntPtr.Size);
                // Need to convert 'content', which is a ptr to native StateItem,
                // into a byte array because that's what GetPreloadedEntityBody
                // must return, and GetPreloadedEntityBody is what the pipeline uses 
                // to read the body of the request, which in our case is just a pointer
                // to a native StateItem object. 
#if WIN64 
                ulong p = (ulong) content;
                _content = new byte[8] 
                {
                    (byte) ((p & 0x00000000000000ff)),
                    (byte) ((p & 0x000000000000ff00) >> 8),
                    (byte) ((p & 0x0000000000ff0000) >> 16), 
                    (byte) ((p & 0x00000000ff000000) >> 24),
                    (byte) ((p & 0x000000ff00000000) >> 32), 
                    (byte) ((p & 0x0000ff0000000000) >> 40), 
                    (byte) ((p & 0x00ff000000000000) >> 48),
                    (byte) ((p & 0xff00000000000000) >> 56), 
                };
#else
                uint p = (uint) content;
                _content = new byte[4] 
                {
                    (byte) ((p & 0x000000ff)), 
                    (byte) ((p & 0x0000ff00) >> 8), 
                    (byte) ((p & 0x00ff0000) >> 16),
                    (byte) ((p & 0xff000000) >> 24), 
                };
#endif
            }
 
            _status  = new StringBuilder(256);
            _headers = new StringBuilder(256); 
        } 

        public override string GetUriPath() { 
            return HttpUtility.UrlDecode(_uri);
        }

        // The file path is used as the path for configuration. 
        // This path should always be null, in order to retrieve
        // the machine configuration. 
        public override string GetFilePath() { 
            return null;
        } 

        public override string GetQueryString() {
            return null;
        } 

        public override string GetRawUrl() { 
            return _uri; 
        }
 
        public override string GetHttpVerbName() {
            return _method;
        }
 
        public override string GetHttpVersion() {
            return "HTTP/1.0"; 
        } 

        public override string GetRemoteAddress() { 
            StringBuilder   buf;

            if (_remoteAddress == null) {
                buf = new StringBuilder(ADDRESS_LENGTH_MAX); 
                UnsafeNativeMethods.STWNDGetRemoteAddress(_tracker, buf);
                _remoteAddress = buf.ToString(); 
            } 

            return _remoteAddress; 
        }

        public override int GetRemotePort() {
            if (_remotePort == 0) { 
                _remotePort = UnsafeNativeMethods.STWNDGetRemotePort(_tracker);
            } 
 
            return _remotePort;
        } 

        public override string GetLocalAddress() {
            StringBuilder   buf;
 
            if (_localAddress == null) {
                buf = new StringBuilder(ADDRESS_LENGTH_MAX); 
                UnsafeNativeMethods.STWNDGetLocalAddress(_tracker, buf); 
                _localAddress = buf.ToString();
            } 

            return _localAddress;
        }
 
        public override int GetLocalPort() {
            if (_localPort == 0) { 
                _localPort = UnsafeNativeMethods.STWNDGetLocalPort(_tracker); 
            }
 
            return _localPort;
        }

        public override byte[] GetPreloadedEntityBody() { 
            return _content;
        } 
 

        public override bool IsEntireEntityBodyIsPreloaded() { 
            /* Request is always preloaded */
            return true;
        }
 

        public override string MapPath(string virtualPath) { 
            /* 
             * Physical and virtual are identical to state server.
             */ 
            return virtualPath;
        }

        public override int ReadEntityBody(byte[] buffer, int size) { 
            /* pretend everything is preloaded */
            return 0; 
        } 

        public override long GetBytesRead() { 
            /* State web doesn't support partial reads */
            throw new NotSupportedException(SR.GetString(SR.Not_supported));
        }
 
        public override string GetKnownRequestHeader(int index) {
            string s = null; 
 
            switch (index) {
                /* special case important ones */ 
                case HeaderContentLength:
                    s = (_contentLength).ToString(CultureInfo.InvariantCulture);
                    break;
            } 

            return s; 
        } 

        public override string GetUnknownRequestHeader(string name) { 
            string s = null;

            if (name.Equals(StateHeaders.EXCLUSIVE_NAME)) {
                switch (_exclusive) { 
                    case UnsafeNativeMethods.StateProtocolExclusive.ACQUIRE:
                        s = StateHeaders.EXCLUSIVE_VALUE_ACQUIRE; 
                        break; 

                    case UnsafeNativeMethods.StateProtocolExclusive.RELEASE: 
                        s = StateHeaders.EXCLUSIVE_VALUE_RELEASE;
                        break;
                }
            } 
            else if (name.Equals(StateHeaders.TIMEOUT_NAME)) {
                if (_timeout != -1) { 
                    s = (_timeout).ToString(CultureInfo.InvariantCulture); 
                }
            } 
            else if (name.Equals(StateHeaders.LOCKCOOKIE_NAME)) {
                if (_lockCookieExists) {
                    s = (_lockCookie).ToString(CultureInfo.InvariantCulture);
                } 
            }
            else if (name.Equals(StateHeaders.EXTRAFLAGS_NAME)) { 
                if (_extraFlags != -1) { 
                    s = (_extraFlags).ToString(CultureInfo.InvariantCulture);
                } 
            }

            return s;
        } 

        public override string[][] GetUnknownRequestHeaders() { 
            string [][] ret; 
            int         c, i;
 
            c = 0;
            if (_exclusive != (UnsafeNativeMethods.StateProtocolExclusive) (-1)) {
                c++;
            } 

            if (_extraFlags != -1) { 
                c++; 
            }
 
            if (_timeout != -1) {
                c++;
            }
 
            if (_lockCookieExists) {
                c++; 
            } 

            if (c == 0) 
                return null;

            ret = new string[c][];
            i = 0; 
            if (_exclusive != (UnsafeNativeMethods.StateProtocolExclusive) (-1)) {
                ret[0] = new string[2]; 
                ret[0][0] = StateHeaders.EXCLUSIVE_NAME; 
                if (_exclusive == UnsafeNativeMethods.StateProtocolExclusive.ACQUIRE) {
                    ret[0][1] = StateHeaders.EXCLUSIVE_VALUE_ACQUIRE; 
                }
                else {
                    Debug.Assert(_exclusive == UnsafeNativeMethods.StateProtocolExclusive.RELEASE, "_exclusive == UnsafeNativeMethods.StateProtocolExclusive.RELEASE");
                    ret[0][1] = StateHeaders.EXCLUSIVE_VALUE_RELEASE; 
                }
 
                i++; 
            }
 
            if (_timeout != -1) {
                ret[i] = new string[2];
                ret[i][0] = StateHeaders.TIMEOUT_NAME;
                ret[i][1] = (_timeout).ToString(CultureInfo.InvariantCulture); 

                i++; 
            } 

            if (_lockCookieExists) { 
                ret[i] = new string[2];
                ret[i][0] = StateHeaders.LOCKCOOKIE_NAME;
                ret[i][1] = (_lockCookie).ToString(CultureInfo.InvariantCulture);
 
                i++;
            } 
 
            if (_extraFlags != -1) {
                ret[i] = new string[2]; 
                ret[i][0] = StateHeaders.EXTRAFLAGS_NAME;
                ret[i][1] = (_extraFlags).ToString(CultureInfo.InvariantCulture);

                i++; 
            }
 
            return ret; 
        }
 
        public override void SendStatus(int statusCode, string statusDescription) {
            Debug.Assert(!_sent);
            _statusCode = statusCode;
            _status.Append((statusCode).ToString(CultureInfo.InvariantCulture) + " " + statusDescription + "\r\n"); 
        }
 
        public override void SendKnownResponseHeader(int index, string value) { 
            Debug.Assert(!_sent);
            _headers.Append(GetKnownResponseHeaderName(index)); 
            _headers.Append(": ");
            _headers.Append(value);
            _headers.Append("\r\n");
        } 

        public override void SendUnknownResponseHeader(string name, string value) { 
            Debug.Assert(!_sent); 
            _headers.Append(name);
            _headers.Append(": "); 
            _headers.Append(value);
            _headers.Append("\r\n");
        }
 
        public override void SendCalculatedContentLength(int contentLength) {
            Debug.Assert(!_sent); 
            /* 
             * Do nothing - we append the content-length in STWNDSendResponse.
             */ 
        }

        public override bool HeadersSent() {
            return _sent; 
        }
 
        public override bool IsClientConnected() { 
            return UnsafeNativeMethods.STWNDIsClientConnected(_tracker);
        } 

        public override void CloseConnection() {
            UnsafeNativeMethods.STWNDCloseConnection(_tracker);
        } 

        private void SendResponse() { 
            if (!_sent) { 
                _sent = true;
                UnsafeNativeMethods.STWNDSendResponse( 
                                    _tracker,
                                    _status,
                                    _status.Length,
                                    _headers, 
                                    _headers.Length,
                                    _unmanagedState); 
            } 
        }
 
        public override void SendResponseFromMemory(byte[] data, int length) {
            /*
             * The only content besides error message text is the pointer
             * to the state item in unmanaged memory. 
             */
            if (_statusCode == 200) { 
                Debug.Assert(_unmanagedState == IntPtr.Zero, "_unmanagedState == 0"); 
                Debug.Assert(length == IntPtr.Size, "length == IntPtr.Size");
                Debug.Assert(_methodIndex == UnsafeNativeMethods.StateProtocolVerb.GET, "verb == GET"); 
                Debug.Assert(_exclusive != UnsafeNativeMethods.StateProtocolExclusive.RELEASE,
                             "correct exclusive method");

                if (IntPtr.Size == 4) { 
                    _unmanagedState = (IntPtr)
                        (((int)data[0])       | 
                         ((int)data[1] << 8)  | 
                         ((int)data[2] << 16) |
                         ((int)data[3] << 24)); 
                }
                else {
                    _unmanagedState = (IntPtr)
                        (((long)data[0])       | 
                         ((long)data[1] << 8)  |
                         ((long)data[2] << 16) | 
                         ((long)data[3] << 24) | 
                         ((long)data[4] << 32) |
                         ((long)data[5] << 40) | 
                         ((long)data[6] << 48) |
                         ((long)data[7] << 56));
                }
 
                Debug.Assert(_unmanagedState != IntPtr.Zero, "_unmanagedState != 0");
            } 
 
            SendResponse();
        } 

        public override void SendResponseFromFile(string filename, long offset, long length) {
            /* Not needed by state application */
            throw new NotSupportedException(SR.GetString(SR.Not_supported)); 
        }
 
        public override void SendResponseFromFile(IntPtr handle, long offset, long length) { 
            /* Not needed by state application */
            throw new NotSupportedException(SR.GetString(SR.Not_supported)); 
        }

        public override void FlushResponse(bool finalFlush) {
            SendResponse(); 
        }
 
        public override void EndOfRequest() { 
            SendResponse();
            UnsafeNativeMethods.STWNDEndOfRequest(_tracker); 
        }
    }
}

// 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