File: SessionStateUtil.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (221 lines) | stat: -rw-r--r-- 9,391 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//------------------------------------------------------------------------------
// <copyright file="SessionStateUtil.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

/*
 * SessionStateUtil
 *
 */
namespace System.Web.SessionState {
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.IO.Compression;
    using System.Runtime.Serialization;
    using System.Security.Permissions;
    using System.Web;
    using System.Web.Util;
    using System.Xml;

    public static class SessionStateUtility {
        internal const String SESSION_KEY = "AspSession";

        // Used by AltSerialization's BinaryFormatter for session serialization customization
        public static ISurrogateSelector SerializationSurrogateSelector {
            [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
            get;
            [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
            set;
        }

        // Called by custom session state module if they want to raise Session_End.
        static public void RaiseSessionEnd(IHttpSessionState session, Object eventSource, EventArgs eventArgs) {
            HttpApplicationFactory.EndSession(new HttpSessionState(session), eventSource, eventArgs);
        }

        // Called by custom session state module
        static public void AddHttpSessionStateToContext(HttpContext context, IHttpSessionState container) {
            HttpSessionState sessionState = new HttpSessionState(container);

            try {
                context.Items.Add(SESSION_KEY, sessionState);
            }
            catch (ArgumentException) {
                throw new HttpException(SR.GetString(SR.Cant_have_multiple_session_module));
            }
        }

        static internal void AddHttpSessionStateModuleToContext(HttpContext context, SessionStateModule module, bool delayed) {
            context.AddHttpSessionStateModule(module, delayed);
        }

        static internal void RemoveHttpSessionStateFromContext(HttpContext context, bool delayed) {
            if (!delayed) {
                context.Items.Remove(SESSION_KEY);
            }

            context.RemoveHttpSessionStateModule();
         }

        // Called by custom session state module
        static public void RemoveHttpSessionStateFromContext(HttpContext context) {
            RemoveHttpSessionStateFromContext(context, false);
        }

        // Called by custom session state module
        static public IHttpSessionState GetHttpSessionStateFromContext(HttpContext context) {
                return context.Session.Container;
        }

        static public HttpStaticObjectsCollection GetSessionStaticObjects(HttpContext context) {
            return context.Application.SessionStaticObjects.Clone();
        }

        /// <summary>
        /// Gets a value that indicates whether session state is required by the context.
        /// </summary>
        /// <param name="context">The HttpContext.</param>
        /// <returns>A value that indicates whether session state is required by the context.</returns>
        static public bool IsSessionStateRequired(HttpContext context) {
            return context.RequiresSessionState;
        }

        /// <summary>
        /// Gets a value that indicates whether session state is read-only in the context.
        /// </summary>
        /// <param name="context">The HttpContext.</param>
        /// <returns>A value that indicates whether session state is read-only in the context.</returns>
        static public bool IsSessionStateReadOnly(HttpContext context) {
            return context.ReadOnlySessionState;
        }

        internal static SessionStateStoreData CreateLegitStoreData(HttpContext context,
                                                    ISessionStateItemCollection sessionItems,
                                                    HttpStaticObjectsCollection staticObjects,
                                                    int timeout) {
            if (sessionItems == null) {
                sessionItems = new SessionStateItemCollection();
            }

            if (staticObjects == null && context != null) {
                staticObjects = SessionStateUtility.GetSessionStaticObjects(context);
            }

            return new SessionStateStoreData(sessionItems, staticObjects, timeout);
        }


        // This method will take an item and serialize it
        [SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)]
        internal static void Serialize(SessionStateStoreData item, Stream stream) {
            bool    hasItems = true;
            bool    hasStaticObjects = true;

            BinaryWriter writer = new BinaryWriter(stream);
            writer.Write(item.Timeout);

            if (item.Items == null || item.Items.Count == 0) {
                hasItems = false;
            }
            writer.Write(hasItems);

            if (item.StaticObjects == null || item.StaticObjects.NeverAccessed) {
                hasStaticObjects = false;
            }
            writer.Write(hasStaticObjects);

            if (hasItems) {
                ((SessionStateItemCollection)item.Items).Serialize(writer);
            }

            if (hasStaticObjects) {
                item.StaticObjects.Serialize(writer);
            }

            // Prevent truncation of the stream
            writer.Write(unchecked((byte)0xff));
        }

        // This will deserialize and return an item.
        // This version uses the default classes for SessionStateItemCollection, HttpStaticObjectsCollection
        // and SessionStateStoreData
        [SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)]
        internal static SessionStateStoreData Deserialize(HttpContext context, Stream    stream) {

            int                 timeout;
            SessionStateItemCollection   sessionItems;
            bool                hasItems;
            bool                hasStaticObjects;
            HttpStaticObjectsCollection staticObjects;
            Byte                eof;

            Debug.Assert(context != null);

            try {
                BinaryReader reader = new BinaryReader(stream);
                timeout = reader.ReadInt32();
                hasItems = reader.ReadBoolean();
                hasStaticObjects = reader.ReadBoolean();

                if (hasItems) {
                    sessionItems = SessionStateItemCollection.Deserialize(reader);
                }
                else {
                    sessionItems = new SessionStateItemCollection();
                }

                if (hasStaticObjects) {
                    staticObjects = HttpStaticObjectsCollection.Deserialize(reader);
                }
                else {
                    staticObjects = SessionStateUtility.GetSessionStaticObjects(context);
                }

                eof = reader.ReadByte();
                if (eof != 0xff) {
                    throw new HttpException(SR.GetString(SR.Invalid_session_state));
                }
            }
            catch (EndOfStreamException) {
                throw new HttpException(SR.GetString(SR.Invalid_session_state));
            }

            return new SessionStateStoreData(sessionItems, staticObjects, timeout);
        }

        static internal void SerializeStoreData(SessionStateStoreData item, int initialStreamSize, out byte[] buf, out int length, bool compressionEnabled) {
            using(MemoryStream s = new MemoryStream(initialStreamSize)) {
                SessionStateUtility.Serialize(item, s);
                if(compressionEnabled) {
                    byte[] serializedBuffer = s.GetBuffer();
                    int serializedLength = (int)s.Length;
                    // truncate the MemoryStream so we can write the compressed data in it
                    s.SetLength(0);
                    // compress the serialized bytes
                    using(DeflateStream zipStream = new DeflateStream(s, CompressionMode.Compress, true)) {
                        zipStream.Write(serializedBuffer, 0, serializedLength);
                    }
                    // if the session state tables have ANSI_PADDING disabled, last )s are trimmed.
                    // This shouldn't happen, but to be sure, we are padding with an extra byte
                    s.WriteByte((byte)0xff);
                }
                buf = s.GetBuffer();
                length = (int) s.Length;
            }
        }

        static internal SessionStateStoreData DeserializeStoreData(HttpContext context, Stream stream, bool compressionEnabled) {
            if(compressionEnabled) {
                // apply the compression decorator on top of the stream
                // the data should not be bigger than 4GB - compression doesn't work for more than that
                using(DeflateStream zipStream = new DeflateStream(stream, CompressionMode.Decompress, true)) {
                    return SessionStateUtility.Deserialize(context, zipStream);
                }
            }
            return SessionStateUtility.Deserialize(context, stream);
        }
    }

}