Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / Security / CookielessHelper.cs / 2 / CookielessHelper.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* * CookielessHelper class * * Copyright (c) 1999 Microsoft Corporation */ namespace System.Web.Security { using System; using System.Web; using System.Text; using System.Web.Configuration; using System.Web.Caching; using System.Collections; using System.Web.Util; using System.Security.Cryptography; using System.Security.Principal; using System.Threading; using System.Globalization; using System.Security.Permissions; internal sealed class CookielessHelperClass { //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// internal CookielessHelperClass(HttpContext context) { _Context = context; } private void Init() { if (_Headers != null) return; if (_Headers == null) GetCookielessValuesFromHeader(); if (_Headers == null) RemoveCookielessValuesFromPath(); if (_Headers == null) _Headers = String.Empty; _OriginalHeaders = _Headers; } private void GetCookielessValuesFromHeader() { _Headers = _Context.Request.Headers[COOKIELESS_SESSION_FILTER_HEADER]; if (!String.IsNullOrEmpty(_Headers)) { // QFE 4512: Ignore old V1.1 Session ids for cookieless in V2.0 if (_Headers.Length == 24 && !_Headers.Contains("(")) { _Headers = null; } else { _Context.Response.SetAppPathModifier("(" + _Headers + ")"); } } } // This function is called for all requests -- it must be performant. // In the common case (i.e. value not present in the URI, it must not // look at the headers collection internal void RemoveCookielessValuesFromPath() { // See if the path contains "/(XXXXX)/" string path = _Context.Request.FilePath; int endPos = path.LastIndexOf(")/", StringComparison.Ordinal); int startPos = (endPos > 2 ? path.LastIndexOf("/(", endPos - 1, endPos, StringComparison.Ordinal) : -1); if (startPos < 0) // pattern not found: common case, exit immediately return; if (_Headers == null) // Header should always be processed first GetCookielessValuesFromHeader(); if (_Headers != null) // found in the header -- disregard the path and exit return; // See if we found a valid Header if (IsValidHeader(path, startPos + 2, endPos)) { _Headers = path.Substring(startPos + 2, endPos - startPos - 2); // Rewrite the path path = path.Substring(0, startPos) + path.Substring(endPos+1); _Context.RewritePath(VirtualPath.CreateAbsolute(path), _Context.Request.PathInfoObject, null /*newQueryString*/, true /*setClientFilePath*/); if (!String.IsNullOrEmpty(_Headers)) _Context.Response.SetAppPathModifier("(" + _Headers + ")"); } } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // Get the cookie value from the header/path based on the identifying char internal string GetCookieValue(char identifier) { int startPos = 0; int endPos = 0; string returnValue; Init(); //////////////////////////////////////////////////////////// // Step 1: Get the positions if (!GetValueStartAndEnd(_Headers, identifier, out startPos, out endPos)) return null; returnValue = _Headers.Substring(startPos, endPos-startPos); // get the substring return returnValue; } internal bool DoesCookieValueExistInOriginal(char identifier) { int startPos = 0; int endPos = 0; Init(); return GetValueStartAndEnd(_OriginalHeaders, identifier, out startPos, out endPos); } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // Add/Change/Delete a cookie value, given the tag internal void SetCookieValue(char identifier, string cookieValue) { int startPos = 0; int endPos = 0; Init(); //////////////////////////////////////////////////////////// // Step 1: Remove old values while (GetValueStartAndEnd(_Headers, identifier, out startPos, out endPos)) { // find old value position _Headers = _Headers.Substring(0, startPos-2) + _Headers.Substring(endPos+1); // Remove old value } //////////////////////////////////////////////////////////// // Step 2: Add new Value if value is specified if (!String.IsNullOrEmpty(cookieValue)) { _Headers += new string(new char[] {identifier, '('}) + cookieValue + ")"; } //////////////////////////////////////////////////////////// // Step 3: Set path for redirection if (_Headers.Length > 0) _Context.Response.SetAppPathModifier("(" + _Headers + ")"); else _Context.Response.SetAppPathModifier(null); } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // Get the position (start & end) of cookie value given the identifier private static bool GetValueStartAndEnd(string headers, char identifier, out int startPos, out int endPos) { //////////////////////////////////////////////////////////// // Step 1: Check if the header is non-empty if (String.IsNullOrEmpty(headers)) { startPos = endPos = -1; return false; } //////////////////////////////////////////////////////////// // Step 2: Get the start pos string tag = new string(new char[] {identifier, '('}); // Tag is: "X(" startPos = headers.IndexOf(tag, StringComparison.Ordinal); // Search for "X(" if (startPos < 0) { // Not Found startPos = endPos = -1; return false; } startPos += 2; //////////////////////////////////////////////////////////// // Step 3: Find the end position endPos = headers.IndexOf(')', startPos); if (endPos < 0) { startPos = endPos = -1; return false; } return true; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // Look at config () and (maybe) current request, and return // whether to use cookie-less feature internal static bool UseCookieless(HttpContext context, bool doRedirect, HttpCookieMode cookieMode) { //////////////////////////////////////////////////////////// // Step 2: Look at config switch(cookieMode) { case HttpCookieMode.UseUri: // Use cookieless always return true; case HttpCookieMode.UseCookies: // Never use cookieless return false; case HttpCookieMode.UseDeviceProfile: // Use browser config if (context == null) context = HttpContext.Current; if (context == null) return false; bool fRet = (!context.Request.Browser.Cookies || !context.Request.Browser.SupportsRedirectWithCookie); return fRet; case HttpCookieMode.AutoDetect: // Detect based on whether the client supports cookieless if (context == null) context = HttpContext.Current; if (context == null) return false; if (!context.Request.Browser.Cookies || !context.Request.Browser.SupportsRedirectWithCookie) { return true; } ////////////////////////////////////////////////////////////////// // Look in the header string cookieDetectHeader = context.CookielessHelper.GetCookieValue('X'); if (cookieDetectHeader != null && cookieDetectHeader == "1") { return true; } ////////////////////////////////////////////////// // Step 3a: See if the client sent any (request) cookies string cookieHeader = context.Request.Headers["Cookie"]; if (!String.IsNullOrEmpty(cookieHeader)) { // Yes, client sent request cookies return false; } ////////////////////////////////////////////////// // Step 3b: See if we have done a challenge-response to detect cookie support string qs = context.Request.QueryString[s_AutoDetectName]; if (qs != null && qs == s_AutoDetectValue) { // Yes, we have done a challenge-response: No cookies present => no cookie support context.CookielessHelper.SetCookieValue('X', "1"); return true; } ////////////////////////////////////////////////// // Step 3c: Do a challenge-response (redirect) to detect cookie support if (doRedirect) { context.CookielessHelper.RedirectWithDetection(null); } // Note: if doRedirect==true, execution won't reach here return false; default: // Config broken? return false; } } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // Do a redirect to figure out cookies are supported or not. /// The way we do it: write the cookie and in the query-string, // write the cookie-name value pair. internal void RedirectWithDetection(string redirectPath) { Init(); //////////////////////////////////////////////////////////// // Step 1: If URL to redirect to, has not been specified, // the use the current URL if (String.IsNullOrEmpty(redirectPath)) { redirectPath = _Context.Request.PathWithQueryString; } //////////////////////////////////////////////////////////// // Step 2: Add cookie name and value to query-string if (redirectPath.IndexOf("?", StringComparison.Ordinal) > 0) redirectPath += "&" + s_AutoDetectName + "=" + s_AutoDetectValue; else redirectPath += "?" + s_AutoDetectName + "=" + s_AutoDetectValue; //////////////////////////////////////////////////////////// // Step 3: Add cookie _Context.Response.Cookies.Add(new HttpCookie(s_AutoDetectName, s_AutoDetectValue)); //////////////////////////////////////////////////////////// // Step 4: Do redirect _Context.Response.Redirect(redirectPath, true); } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // RedirectWithDetection if we need to internal void RedirectWithDetectionIfRequired(string redirectPath, HttpCookieMode cookieMode) { Init(); //////////////////////////////////////////////////////////// // Step 1: Check if config wants us to do a challenge-reponse if (cookieMode != HttpCookieMode.AutoDetect) { return; } //////////////////////////////////////////////////////////// // Step 2: Check browser caps if (!_Context.Request.Browser.Cookies || !_Context.Request.Browser.SupportsRedirectWithCookie) { return; } //////////////////////////////////////////////////////////// // Step 3: Check header string cookieDetectHeader = GetCookieValue('X'); if (cookieDetectHeader != null && cookieDetectHeader == "1") { return; } //////////////////////////////////////////////////////////// // Step 4: see if the client sent any cookies string cookieHeader = _Context.Request.Headers["Cookie"]; if (!String.IsNullOrEmpty(cookieHeader)) { return; } //////////////////////////////////////////////////////////// // Step 5: See if we already did a challenge-reponse string qs = _Context.Request.QueryString[s_AutoDetectName]; if (qs != null && qs == s_AutoDetectValue) { // Yes, we have done a challenge-response // No cookies present => no cookie support SetCookieValue('X', "1"); return; } //////////////////////////////////////////////////////////// // Do a challenge response RedirectWithDetection(redirectPath); } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Make sure sub-string if of the pattern: A(XXXX)N(XXXXX)P(XXXXX) and so on. static private bool IsValidHeader(string path, int startPos, int endPos) { if (endPos - startPos < 3) // Minimum len is "X()" return false; while (startPos <= endPos - 3) { // Each iteration deals with one "A(XXXX)" pattern if (path[startPos] < 'A' || path[startPos] > 'Z') // Make sure pattern starts with a capital letter return false; if (path[startPos + 1] != '(') // Make sure next char is '(' return false; startPos += 2; bool found = false; for (; startPos < endPos; startPos++) { // Find the ending ')' if (path[startPos] == ')') { // found it! startPos++; // Set position for the next pattern found = true; break; // Break out of this for-loop. } if (path[startPos] == '/') { // Can't contain path separaters return false; } } if (!found) { return false; // Ending ')' not found! } } if (startPos < endPos) // All chars consumed? return false; return true; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // Static data const String COOKIELESS_SESSION_FILTER_HEADER = "AspFilterSessionId"; const string s_AutoDetectName = "AspxAutoDetectCookieSupport"; const string s_AutoDetectValue = "1"; // Private instance data private HttpContext _Context; private string _Headers; private string _OriginalHeaders; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// internal enum CookiesSupported { Supported, NotSupported, Unknown } }
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- OverflowException.cs
- namescope.cs
- TrackingProfileManager.cs
- UpdateRecord.cs
- ChtmlPhoneCallAdapter.cs
- SqlClientWrapperSmiStream.cs
- ByteStream.cs
- SQLMoney.cs
- PermissionSetEnumerator.cs
- DropDownList.cs
- ResourcesBuildProvider.cs
- ConfigPathUtility.cs
- DomNameTable.cs
- BitStack.cs
- ToRequest.cs
- Compiler.cs
- AmbientValueAttribute.cs
- ClusterRegistryConfigurationProvider.cs
- DataBindingHandlerAttribute.cs
- SessionEndedEventArgs.cs
- Operand.cs
- PointIndependentAnimationStorage.cs
- StatusStrip.cs
- PeerTransportCredentialType.cs
- DocumentationServerProtocol.cs
- SBCSCodePageEncoding.cs
- SizeAnimationClockResource.cs
- RequestTimeoutManager.cs
- SafeFindHandle.cs
- ProcessHost.cs
- TextProviderWrapper.cs
- Binding.cs
- PenCursorManager.cs
- TraceSwitch.cs
- DataGridViewRowPrePaintEventArgs.cs
- CodeDomSerializerException.cs
- CodeTypeConstructor.cs
- OutOfProcStateClientManager.cs
- CancellationHandlerDesigner.cs
- BamlBinaryWriter.cs
- Socket.cs
- IDQuery.cs
- TypeSystem.cs
- DropTarget.cs
- DesignTableCollection.cs
- TypeValidationEventArgs.cs
- XPathConvert.cs
- LinkUtilities.cs
- LineUtil.cs
- XmlAnyElementAttribute.cs
- UInt16Storage.cs
- SafeProcessHandle.cs
- Registry.cs
- SRDisplayNameAttribute.cs
- Formatter.cs
- EntityProviderFactory.cs
- EntityContainerRelationshipSetEnd.cs
- LocatorGroup.cs
- figurelength.cs
- WebResourceAttribute.cs
- XPathDocument.cs
- ToolStripContentPanel.cs
- SolidColorBrush.cs
- SmiEventSink_DeferedProcessing.cs
- ArithmeticException.cs
- TextLineResult.cs
- XmlComplianceUtil.cs
- HostVisual.cs
- SafeEventLogWriteHandle.cs
- Form.cs
- ValueTable.cs
- PropertyValueChangedEvent.cs
- SqlCacheDependency.cs
- ContextBase.cs
- CodeGeneratorAttribute.cs
- KeyManager.cs
- VirtualizingStackPanel.cs
- KnownTypes.cs
- ProtocolsConfigurationEntry.cs
- SecurityCriticalDataForSet.cs
- DataSourceConverter.cs
- ValidationErrorEventArgs.cs
- FontStyleConverter.cs
- MaterializeFromAtom.cs
- ClientBuildManagerCallback.cs
- FixedDocument.cs
- Mappings.cs
- HostProtectionException.cs
- User.cs
- WebPartConnectionsDisconnectVerb.cs
- TranslateTransform.cs
- OdbcException.cs
- ParserExtension.cs
- Int16Storage.cs
- ScriptModule.cs
- RequestQueue.cs
- BasicExpressionVisitor.cs
- CodeRemoveEventStatement.cs
- XmlSchemaComplexContentRestriction.cs
- ConditionalBranch.cs