Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / ServiceModel / Web / CachingParameterInspector.cs / 1305376 / CachingParameterInspector.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics; using System.Runtime; using System.Runtime.Serialization; using System.Security; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Diagnostics; using System.ServiceModel.Dispatcher; using System.Web; using System.Web.Caching; using System.Web.Configuration; using System.Web.UI; using System.ServiceModel.Activation; namespace System.ServiceModel.Web { class CachingParameterInspector : IParameterInspector { const char seperatorChar = ';'; const char escapeChar = '\\'; const char tableDbSeperatorChar = ':'; const string invalidSqlDependencyString = "Invalid Sql dependency string."; [Fx.Tag.SecurityNote(Critical = "A config object, which should not be leaked.")] [SecurityCritical] OutputCacheProfile cacheProfile; SqlDependencyInfo[] cacheDependencyInfoArray; [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.", Safe="The config object never leaves the CachingParameterInspector.")] [SecuritySafeCritical] public CachingParameterInspector(string cacheProfileName) { if (string.IsNullOrEmpty(cacheProfileName)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.CacheProfileNameNullOrEmpty)); } OutputCacheSettingsSection cacheSettings = AspNetEnvironment.Current.UnsafeGetConfigurationSection("system.web/caching/outputCacheSettings") as OutputCacheSettingsSection; if (cacheSettings == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileNotConfigured, cacheProfileName))); } this.cacheProfile = cacheSettings.OutputCacheProfiles[cacheProfileName]; if (this.cacheProfile == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileNotConfigured, cacheProfileName))); } // Validate the cacheProfile if (this.cacheProfile.Location != OutputCacheLocation.None) { // Duration must be set; Duration default value is -1 if (this.cacheProfile.Duration == -1) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileValueMissing, this.cacheProfile.Name, "Duration"))); } if (this.cacheProfile.VaryByParam == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileValueMissing, this.cacheProfile.Name, "VaryByParam"))); } } if (string.Equals(this.cacheProfile.SqlDependency, "CommandNotification", StringComparison.OrdinalIgnoreCase)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.CommandNotificationSqlDependencyNotSupported)); } if (!string.IsNullOrEmpty(this.cacheProfile.SqlDependency)) { ParseSqlDependencyString(cacheProfile.SqlDependency); } } [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.", Safe = "The config object never leaves the CachingParameterInspector.")] [SecuritySafeCritical] public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) { if (this.cacheProfile != null && this.cacheProfile.Enabled && OperationContext.Current.IncomingMessage.Version == MessageVersion.None) { if (DiagnosticUtility.ShouldTraceWarning && !IsAnonymous()) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.AddingAuthenticatedResponseToOutputCache, SR2.GetString(SR2.TraceCodeAddingAuthenticatedResponseToOutputCache, operationName)); } else if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.AddingResponseToOutputCache, SR2.GetString(SR2.TraceCodeAddingResponseToOutputCache, operationName)); } SetCacheFromCacheProfile(); } } public object BeforeCall(string operationName, object[] inputs) { return null; } bool IsAnonymous() { if (HttpContext.Current.User.Identity.IsAuthenticated) { return false; } else { if (OperationContext.Current.ServiceSecurityContext == null) { return true; } else { return OperationContext.Current.ServiceSecurityContext.IsAnonymous; } } } static SqlDependencyInfo[] ParseSqlDependencyString(string sqlDependencyString) { // The code for this method was taken from private code in // System.Web.SqlCacheDependency.ParseSql7OutputCacheDependency. // Alter if only absolutely necessary since we want to reproduce the same ASP.NET caching behavior. ListdependencyList = new List (); bool escapeSequenceFlag = false; int startIndexForDatabaseName = 0; int startIndexForTableName = -1; string databaseName = null; try { for (int currentIndex = 0; currentIndex < (sqlDependencyString.Length + 1); currentIndex++) { if (escapeSequenceFlag) { escapeSequenceFlag = false; } else if ((currentIndex != sqlDependencyString.Length) && (sqlDependencyString[currentIndex] == escapeChar)) { escapeSequenceFlag = true; } else { int subStringLength; if ((currentIndex == sqlDependencyString.Length) || (sqlDependencyString[currentIndex] == seperatorChar)) { if (databaseName == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(invalidSqlDependencyString); } subStringLength = currentIndex - startIndexForTableName; if (subStringLength == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(invalidSqlDependencyString); } string tableName = sqlDependencyString.Substring(startIndexForTableName, subStringLength); SqlDependencyInfo info = new SqlDependencyInfo(); info.Database = VerifyAndRemoveEscapeCharacters(databaseName); info.Table = VerifyAndRemoveEscapeCharacters(tableName); dependencyList.Add(info); startIndexForDatabaseName = currentIndex + 1; databaseName = null; } if (currentIndex == sqlDependencyString.Length) { break; } if (sqlDependencyString[currentIndex] == tableDbSeperatorChar) { if (databaseName != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(invalidSqlDependencyString); } subStringLength = currentIndex - startIndexForDatabaseName; if (subStringLength == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(invalidSqlDependencyString); } databaseName = sqlDependencyString.Substring(startIndexForDatabaseName, subStringLength); startIndexForTableName = currentIndex + 1; } } } } catch (ArgumentException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileSqlDependencyIsInvalid, sqlDependencyString))); } if (dependencyList.Count == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileSqlDependencyIsInvalid, sqlDependencyString))); } return dependencyList.ToArray(); } static string VerifyAndRemoveEscapeCharacters(string str) { // The code for this method was taken from private code in // System.Web.SqlCacheDependency.VerifyAndRemoveEscapeCharacters. // Alter if only absolutely necessary since we want to reproduce the same ASP.NET caching behavior. bool escapeSequenceFlag = false; for (int currentIndex = 0; currentIndex < str.Length; currentIndex++) { if (escapeSequenceFlag) { if (((str[currentIndex] != escapeChar) && (str[currentIndex] != tableDbSeperatorChar)) && (str[currentIndex] != seperatorChar)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(str); } escapeSequenceFlag = false; } else if (str[currentIndex] == escapeChar) { if ((currentIndex + 1) == str.Length) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(str); } escapeSequenceFlag = true; str = str.Remove(currentIndex, 1); currentIndex--; } } return str; } CacheDependency CreateSingleCacheDependency(string sqlDependency) { if (this.cacheDependencyInfoArray == null) { this.cacheDependencyInfoArray = CachingParameterInspector.ParseSqlDependencyString(sqlDependency); } // cacheDependencyInfoArray will never have length = 0 if (this.cacheDependencyInfoArray.Length == 1) { return new SqlCacheDependency(this.cacheDependencyInfoArray[0].Database, this.cacheDependencyInfoArray[0].Table); } AggregateCacheDependency cacheDependency = new AggregateCacheDependency(); foreach (SqlDependencyInfo dependencyInfo in this.cacheDependencyInfoArray) { cacheDependency.Add(new CacheDependency[] { new SqlCacheDependency(dependencyInfo.Database, dependencyInfo.Table) }); } return cacheDependency; } [Fx.Tag.SecurityNote(Critical = "Uses config object to set properties of the HttpCachePolicy.", Safe = "The config object itself doesn't leak.")] [SecuritySafeCritical] void SetCacheFromCacheProfile() { HttpCachePolicy cache = HttpContext.Current.Response.Cache; if (this.cacheProfile.NoStore) { cache.SetNoStore(); } // Location is not required to be set in the config. The default is Any, // but if it is not set in the config the value will be -1. So must correct for this. if ((int)(this.cacheProfile.Location) == -1) { cache.SetCacheability(HttpCacheability.Public); } else { switch (this.cacheProfile.Location) { case OutputCacheLocation.Any: cache.SetCacheability(HttpCacheability.Public); break; case OutputCacheLocation.Client: cache.SetCacheability(HttpCacheability.Private); break; case OutputCacheLocation.Downstream: cache.SetCacheability(HttpCacheability.Public); cache.SetNoServerCaching(); break; case OutputCacheLocation.None: cache.SetCacheability(HttpCacheability.NoCache); break; case OutputCacheLocation.Server: cache.SetCacheability(HttpCacheability.ServerAndNoCache); break; case OutputCacheLocation.ServerAndClient: cache.SetCacheability(HttpCacheability.ServerAndPrivate); break; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.CacheProfileLocationNotSupported, this.cacheProfile.Location))); } } if (this.cacheProfile.Location != OutputCacheLocation.None) { cache.SetExpires(HttpContext.Current.Timestamp.AddSeconds((double)this.cacheProfile.Duration)); cache.SetMaxAge(new TimeSpan(0, 0, this.cacheProfile.Duration)); cache.SetValidUntilExpires(true); cache.SetLastModified(HttpContext.Current.Timestamp); if (this.cacheProfile.Location != OutputCacheLocation.Client) { if (!string.IsNullOrEmpty(this.cacheProfile.VaryByContentEncoding)) { foreach (string contentEncoding in this.cacheProfile.VaryByContentEncoding.Split(seperatorChar)) { cache.VaryByContentEncodings[contentEncoding.Trim()] = true; } } if (!string.IsNullOrEmpty(this.cacheProfile.VaryByHeader)) { foreach (string header in this.cacheProfile.VaryByHeader.Split(seperatorChar)) { cache.VaryByHeaders[header.Trim()] = true; } } if (this.cacheProfile.Location != OutputCacheLocation.Downstream) { if (!string.IsNullOrEmpty(this.cacheProfile.VaryByCustom)) { cache.SetVaryByCustom(this.cacheProfile.VaryByCustom); } if (!string.IsNullOrEmpty(this.cacheProfile.VaryByParam)) { foreach (string parameter in cacheProfile.VaryByParam.Split(seperatorChar)) { cache.VaryByParams[parameter.Trim()] = true; } } if (!string.IsNullOrEmpty(this.cacheProfile.SqlDependency)) { CacheDependency cacheDependency = this.CreateSingleCacheDependency(cacheProfile.SqlDependency); HttpContext.Current.Response.AddCacheDependency(new CacheDependency[] { cacheDependency }); } } } } } private struct SqlDependencyInfo { public string Database; public string Table; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ButtonChrome.cs
- DataGridPageChangedEventArgs.cs
- WmfPlaceableFileHeader.cs
- URLMembershipCondition.cs
- XmlElementAttributes.cs
- BindingBase.cs
- DataGridCaption.cs
- FixedSOMSemanticBox.cs
- MenuItemStyle.cs
- XmlQuerySequence.cs
- HttpValueCollection.cs
- ValidationErrorCollection.cs
- ValidationSummary.cs
- ListViewSelectEventArgs.cs
- QueryableDataSource.cs
- PrintDialog.cs
- RequestBringIntoViewEventArgs.cs
- GroupedContextMenuStrip.cs
- Queue.cs
- XmlQueryTypeFactory.cs
- MouseBinding.cs
- FixedHyperLink.cs
- WebServicesInteroperability.cs
- OpCopier.cs
- BufferCache.cs
- NumericUpDownAcceleration.cs
- UIPermission.cs
- ObjectContextServiceProvider.cs
- ShaderEffect.cs
- ControlPaint.cs
- filewebrequest.cs
- TcpTransportBindingElement.cs
- Logging.cs
- MenuItem.cs
- metrodevice.cs
- Roles.cs
- COM2EnumConverter.cs
- XmlName.cs
- MaskedTextBoxDesignerActionList.cs
- VisualStyleRenderer.cs
- mongolianshape.cs
- HttpProfileGroupBase.cs
- DefaultPropertyAttribute.cs
- cache.cs
- Debugger.cs
- SerTrace.cs
- EventLogSession.cs
- WinOEToolBoxItem.cs
- SqlDataSource.cs
- SmiEventStream.cs
- FontFamilyValueSerializer.cs
- ListControl.cs
- ClientApiGenerator.cs
- StickyNoteAnnotations.cs
- GifBitmapEncoder.cs
- SafeJobHandle.cs
- UrlPropertyAttribute.cs
- SqlUnionizer.cs
- OleDbParameter.cs
- PropertyInformationCollection.cs
- ChtmlLinkAdapter.cs
- DataListCommandEventArgs.cs
- AsyncPostBackTrigger.cs
- CounterCreationDataCollection.cs
- TraceUtils.cs
- PropertyStore.cs
- AvTraceDetails.cs
- MulticastDelegate.cs
- Hash.cs
- CodeNamespaceImportCollection.cs
- CachedFontFace.cs
- EditorBrowsableAttribute.cs
- SimpleBitVector32.cs
- OdbcInfoMessageEvent.cs
- PingOptions.cs
- LinearGradientBrush.cs
- DrawingAttributesDefaultValueFactory.cs
- ScrollContentPresenter.cs
- Tile.cs
- PreviewKeyDownEventArgs.cs
- ListView.cs
- HorizontalAlignConverter.cs
- XmlNavigatorStack.cs
- x509utils.cs
- CustomDictionarySources.cs
- DrawTreeNodeEventArgs.cs
- CompiledQueryCacheKey.cs
- MenuItem.cs
- SendingRequestEventArgs.cs
- VirtualizingStackPanel.cs
- MailWriter.cs
- EnumerableWrapperWeakToStrong.cs
- AutomationFocusChangedEventArgs.cs
- BooleanKeyFrameCollection.cs
- PreviewPageInfo.cs
- AssemblyAttributesGoHere.cs
- BamlRecords.cs
- CopyNamespacesAction.cs
- CodeDomExtensionMethods.cs
- ElementAtQueryOperator.cs