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
- CatchBlock.cs
- XmlElementList.cs
- Function.cs
- CFGGrammar.cs
- x509utils.cs
- TCPListener.cs
- BufferBuilder.cs
- StatusBarPanel.cs
- WindowsHyperlink.cs
- MulticastOption.cs
- RegexCapture.cs
- TokenBasedSet.cs
- SoapObjectInfo.cs
- BindingManagerDataErrorEventArgs.cs
- PointAnimationUsingKeyFrames.cs
- Debug.cs
- ClientUtils.cs
- NewArrayExpression.cs
- sqlstateclientmanager.cs
- SystemWebCachingSectionGroup.cs
- DataViewManager.cs
- WizardSideBarListControlItem.cs
- RootBrowserWindow.cs
- LayoutInformation.cs
- GroupBox.cs
- HtmlGenericControl.cs
- SqlDataSourceConfigureSortForm.cs
- JsonWriterDelegator.cs
- RegexMatchCollection.cs
- ZipIOModeEnforcingStream.cs
- TraversalRequest.cs
- Control.cs
- AuthenticationManager.cs
- IsolatedStorageFileStream.cs
- SafeFileMapViewHandle.cs
- SegmentInfo.cs
- Math.cs
- PackageDigitalSignature.cs
- DataGridViewSortCompareEventArgs.cs
- ApplicationDirectory.cs
- XmlSerializerFactory.cs
- InstanceNameConverter.cs
- DesignOnlyAttribute.cs
- WinCategoryAttribute.cs
- InteropTrackingRecord.cs
- UIElement3D.cs
- GeometryCollection.cs
- WsatServiceCertificate.cs
- ActivityDesignerResources.cs
- SimpleType.cs
- ConnectivityStatus.cs
- Icon.cs
- WebPartAuthorizationEventArgs.cs
- Permission.cs
- StorageMappingItemCollection.cs
- PrintDialogException.cs
- NTAccount.cs
- OdbcReferenceCollection.cs
- CodeAttributeDeclaration.cs
- ProtocolElement.cs
- PageRanges.cs
- WebBrowserContainer.cs
- DataGridColumnCollection.cs
- SessionStateSection.cs
- DesignTimeVisibleAttribute.cs
- WindowsSecurityToken.cs
- TimeEnumHelper.cs
- SqlFactory.cs
- FocusManager.cs
- PrintingPermission.cs
- CapabilitiesPattern.cs
- Variant.cs
- HostingEnvironmentSection.cs
- RequestCacheEntry.cs
- AppliesToBehaviorDecisionTable.cs
- UnsettableComboBox.cs
- SmiRequestExecutor.cs
- RuntimeHelpers.cs
- BaseValidator.cs
- ProfilePropertyNameValidator.cs
- DataServiceStreamProviderWrapper.cs
- AuthenticationServiceManager.cs
- SwitchAttribute.cs
- ExpandCollapsePattern.cs
- XPathQilFactory.cs
- WebDescriptionAttribute.cs
- DbConnectionPoolGroupProviderInfo.cs
- iisPickupDirectory.cs
- PngBitmapEncoder.cs
- ContentPathSegment.cs
- ClaimComparer.cs
- ObjectReaderCompiler.cs
- CodeTypeOfExpression.cs
- SizeFConverter.cs
- SchemaHelper.cs
- AutomationPropertyInfo.cs
- NaturalLanguageHyphenator.cs
- GlobalProxySelection.cs
- RichListBox.cs
- ISAPIWorkerRequest.cs