Code:
/ DotNET / DotNET / 8.0 / untmp / Orcas / RTM / ndp / fx / src / xsp / System / Web / Extensions / Handlers / ScriptResourceHandler.cs / 2 / ScriptResourceHandler.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.Handlers { using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Globalization; using System.IO; using System.IO.Compression; using System.Reflection; using System.Resources; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Web; using System.Web.UI; using System.Web.Configuration; using System.Web.Handlers; using System.Web.Hosting; using System.Web.Script.Serialization; using System.Web.Resources; using System.Web.Util; using Debug = System.Diagnostics.Debug; [ AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), ] public class ScriptResourceHandler : IHttpHandler { private const string _scriptResourceUrl = "~/ScriptResource.axd"; private static readonly IDictionary _assemblyInfoCache = Hashtable.Synchronized(new Hashtable()); private static readonly IDictionary _cultureCache = Hashtable.Synchronized(new Hashtable()); private static readonly Object _getMethodLock = new Object(); private static MethodInfo _getWebResourceUrl; private static IScriptResourceHandler _scriptResourceHandler = new RuntimeScriptResourceHandler(); private static string _scriptResourceAbsolutePath; private static string ScriptResourceAbsolutePath { get { if (_scriptResourceAbsolutePath == null) { _scriptResourceAbsolutePath = VirtualPathUtility.ToAbsolute(_scriptResourceUrl); } return _scriptResourceAbsolutePath; } } private static Exception Create404(Exception innerException) { return new HttpException(404, AtlasWeb.ScriptResourceHandler_InvalidRequest, innerException); } private static string DecryptParameter(NameValueCollection queryString) { string encryptedData = queryString["d"]; if (String.IsNullOrEmpty(encryptedData)) { Throw404(); } try { return Page.DecryptString(encryptedData); } catch (CryptographicException ex) { throw Create404(ex); } } internal static CultureInfo DetermineNearestAvailableCulture( Assembly assembly, string scriptResourceName, CultureInfo culture) { if (String.IsNullOrEmpty(scriptResourceName)) return CultureInfo.InvariantCulture; Tuple cacheKey = new Tuple(assembly, scriptResourceName, culture); CultureInfo cachedCulture = (CultureInfo)_cultureCache[cacheKey]; if (cachedCulture == null) { string releaseResourceName = scriptResourceName.EndsWith(".debug.js", StringComparison.OrdinalIgnoreCase) ? scriptResourceName.Substring(0, scriptResourceName.Length - 9) + ".js" : null; ScriptResourceInfo resourceInfo = ScriptResourceInfo.GetInstance(assembly, scriptResourceName); ScriptResourceInfo releaseResourceInfo = (releaseResourceName != null) ? ScriptResourceInfo.GetInstance(assembly, releaseResourceName) : null; if (!String.IsNullOrEmpty(resourceInfo.ScriptResourceName) || ((releaseResourceInfo != null) && !String.IsNullOrEmpty(releaseResourceInfo.ScriptResourceName))) { ResourceManager resourceManager = ScriptResourceAttribute.GetResourceManager(resourceInfo.ScriptResourceName, assembly); ResourceManager releaseResourceManager = (releaseResourceInfo != null) ? ScriptResourceAttribute.GetResourceManager(releaseResourceInfo.ScriptResourceName, assembly) : null; ResourceSet localizedSet = null; ResourceSet releaseSet = null; if (resourceManager != null) { resourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, true); // Look for the explicitly localized version of the resources that is nearest the culture. localizedSet = resourceManager.GetResourceSet(culture, true, false); } if (releaseResourceManager != null) { releaseResourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, true); // Look for the explicitly localized version of the resources that is nearest the culture. releaseSet = releaseResourceManager.GetResourceSet(culture, true, false); } if ((resourceManager != null) || (releaseResourceManager != null)) { while ((localizedSet == null) && (releaseSet == null)) { culture = culture.Parent; if (culture.Equals(CultureInfo.InvariantCulture)) break; localizedSet = resourceManager.GetResourceSet(culture, true, false); releaseSet = (releaseResourceManager != null) ? releaseResourceManager.GetResourceSet(culture, true, false) : null; } } else { culture = CultureInfo.InvariantCulture; } } else { culture = CultureInfo.InvariantCulture; } cachedCulture = culture; _cultureCache[cacheKey] = cachedCulture; } return cachedCulture; } private static void EnsureScriptResourceRequest(string path) { if (!IsScriptResourceRequest(path)) { Throw404(); } } private static Assembly GetAssembly(string assemblyName) { string[] parts = assemblyName.Split(','); if ((parts.Length != 1) && (parts.Length != 4)) { Throw404(); } AssemblyName realName = new AssemblyName(); realName.Name = parts[0]; if (parts.Length == 4) { realName.Version = new Version(parts[1]); string cultureString = parts[2]; realName.CultureInfo = (cultureString.Length > 0) ? new CultureInfo(cultureString) : CultureInfo.InvariantCulture; realName.SetPublicKeyToken(HexParser.Parse(parts[3])); } Assembly assembly = null; try { assembly = Assembly.Load(realName); } catch (FileNotFoundException fnf) { Throw404(fnf); } catch (FileLoadException fl) { Throw404(fl); } catch (BadImageFormatException badImage) { Throw404(badImage); } return assembly; } private static PairGetAssemblyInfo(Assembly assembly) { Pair assemblyInfo = (Pair )_assemblyInfoCache[assembly]; if (assemblyInfo == null) { assemblyInfo = GetAssemblyInfoInternal(assembly); _assemblyInfoCache[assembly] = assemblyInfo; } Debug.Assert(assemblyInfo != null, "Assembly info should not be null"); return assemblyInfo; } private static Pair GetAssemblyInfoInternal(Assembly assembly) { AssemblyName assemblyName = new AssemblyName(assembly.FullName); return new Pair (assemblyName, GetLastWriteTime(assembly)); } // AspNetHostingPermission attributes must be copied to this method, to satisfy FxCop rule // CA2114:MethodSecurityShouldBeASupersetOfType. [ AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), FileIOPermission(SecurityAction.Assert, AllFiles = FileIOPermissionAccess.PathDiscovery), SecurityCritical ] private static string GetCodeBaseWithAssert(Assembly assembly) { return assembly.CodeBase; } [ SecurityCritical, SecurityTreatAsSafe ] private static DateTime GetLastWriteTime(Assembly assembly) { string codeBase = GetCodeBaseWithAssert(assembly); Uri codeBaseUri = new Uri(codeBase); if (!codeBaseUri.IsFile) { throw new InvalidOperationException(AtlasWeb.ScriptResourceHandler_AssemblyNotFileBased); } string localPath = codeBaseUri.LocalPath; FileIOPermission p = new FileIOPermission(FileIOPermissionAccess.Read, localPath); p.Assert(); return File.GetLastWriteTime(localPath); } internal static string GetScriptResourceUrl( Assembly assembly, string resourceName, CultureInfo culture, bool zip, bool notifyScriptLoaded) { return _scriptResourceHandler .GetScriptResourceUrl(assembly, resourceName, culture, zip, notifyScriptLoaded); } // AspNetHostingPermission attributes must be copied to this method, to satisfy FxCop rule // CA2114:MethodSecurityShouldBeASupersetOfType. [ AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), ReflectionPermission(SecurityAction.Assert, Unrestricted = true), SecurityCritical, SecurityTreatAsSafe ] internal static string GetWebResourceUrl(Assembly assembly, string resourceName) { if (_getWebResourceUrl == null) { lock (_getMethodLock) { if (_getWebResourceUrl == null) { _getWebResourceUrl = typeof(AssemblyResourceLoader) .GetMethod("GetWebResourceUrlInternal", BindingFlags.Static | BindingFlags.NonPublic); } } } return (string)_getWebResourceUrl.Invoke(null, new object[] { assembly, resourceName, false }); } protected virtual bool IsReusable { get { return true; } } private static bool IsCompressionEnabled(HttpContext context) { return ScriptingScriptResourceHandlerSection.ApplicationSettings.EnableCompression && ((context == null) || !context.Request.Browser.IsBrowser("IE") || (context.Request.Browser.MajorVersion > 6)); } internal static bool IsScriptResourceRequest(string path) { return !String.IsNullOrEmpty(path) && String.Equals(path, ScriptResourceAbsolutePath, StringComparison.OrdinalIgnoreCase); } private static void PrepareResponseCache(HttpResponse response, Assembly assembly) { HttpCachePolicy cachePolicy = response.Cache; cachePolicy.SetCacheability(HttpCacheability.Public); cachePolicy.VaryByParams["d"] = true; cachePolicy.SetOmitVaryStar(true); cachePolicy.SetExpires(DateTime.Now + TimeSpan.FromDays(365)); cachePolicy.SetValidUntilExpires(true); cachePolicy.SetLastModified((DateTime)GetAssemblyInfo(assembly).Second); } private static void PrepareResponseNoCache(HttpResponse response, Assembly assembly) { HttpCachePolicy cachePolicy = response.Cache; cachePolicy.SetCacheability(HttpCacheability.Public); cachePolicy.SetExpires(DateTime.Now + TimeSpan.FromDays(365)); cachePolicy.SetValidUntilExpires(true); cachePolicy.SetLastModified((DateTime)GetAssemblyInfo(assembly).Second); cachePolicy.SetNoServerCaching(); } protected virtual void ProcessRequest(HttpContext context) { HttpResponse response = context.Response; response.Clear(); // Checking that the handler is not being called from a different path. EnsureScriptResourceRequest(context.Request.Path); string decryptedString = DecryptParameter(context.Request.QueryString); bool zip = false; bool notifyScriptLoaded = true; // See GetScriptResourceUrl comment below for first character meanings. switch(decryptedString[0]) { case 'Z': zip = true; break; case 'z': zip = true; notifyScriptLoaded = false; break; case 'u': notifyScriptLoaded = false; break; } string[] decryptedData = decryptedString.Substring(1).Split('|'); Debug.Assert(decryptedData.Length == 3, "The decrypted data must have three parts separated by pipes."); string assemblyName = decryptedData[0]; string resourceName = decryptedData[1]; string cultureName = decryptedData[2]; if (String.IsNullOrEmpty(resourceName) || String.IsNullOrEmpty(assemblyName)) { Throw404(); } Assembly assembly = GetAssembly(assemblyName); if (assembly != null) { string script = null; Encoding encoding; string contentType; try { script = ScriptResourceAttribute.GetScriptFromWebResourceInternal( assembly, resourceName, String.IsNullOrEmpty(cultureName) ? CultureInfo.InvariantCulture : new CultureInfo(cultureName), zip, notifyScriptLoaded, out encoding, out contentType); } catch (MissingManifestResourceException ex) { throw Create404(ex); } catch (HttpException ex) { throw Create404(ex); } if (ScriptingScriptResourceHandlerSection.ApplicationSettings.EnableCaching) { PrepareResponseCache(response, assembly); } else { PrepareResponseNoCache(response, assembly); } response.ContentType = contentType; if (zip) { using (MemoryStream zipped = new MemoryStream()) { using (Stream outputStream = new GZipStream(zipped, CompressionMode.Compress)) { using (StreamWriter writer = new StreamWriter(outputStream, encoding)) { writer.Write(script); } } byte[] zippedBytes = zipped.ToArray(); response.AddHeader("Content-encoding", "gzip"); response.OutputStream.Write(zippedBytes, 0, zippedBytes.Length); } } else { response.ContentEncoding = encoding; response.Write(script); } } else { Throw404(); } } internal static void SetScriptResourceHandler(IScriptResourceHandler scriptResourceHandler) { _scriptResourceHandler = scriptResourceHandler; } private static void Throw404() { throw Create404(null); } private static void Throw404(Exception innerException) { throw Create404(innerException); } #region IHttpHandler implementation void IHttpHandler.ProcessRequest(HttpContext context) { ProcessRequest(context); } bool IHttpHandler.IsReusable { get { return IsReusable; } } #endregion private class RuntimeScriptResourceHandler : IScriptResourceHandler { private static readonly IDictionary _urlCache = Hashtable.Synchronized(new Hashtable()); private static string _absoluteScriptResourceUrl; string IScriptResourceHandler.GetScriptResourceUrl( Assembly assembly, string resourceName, CultureInfo culture, bool zip, bool notifyScriptLoaded) { if (!IsCompressionEnabled(HttpContext.Current)) { zip = false; } Tuple cacheKey = new Tuple(assembly, resourceName, culture, zip, notifyScriptLoaded); string url = (string)_urlCache[cacheKey]; if (url == null) { // Check if the resources exist ScriptResourceInfo resourceInfo = ScriptResourceInfo.GetInstance(assembly, resourceName); if (resourceInfo == ScriptResourceInfo.Empty) { ThrowUnknownResource(resourceName); } Stream scriptStream = assembly.GetManifestResourceStream(resourceInfo.ScriptName); if (scriptStream == null) { ThrowUnknownResource(resourceName); } culture = DetermineNearestAvailableCulture(assembly, resourceName, culture); Pair assemblyInfo = GetAssemblyInfo(assembly); AssemblyName assemblyName = (AssemblyName)assemblyInfo.First; DateTime assemblyDate = (DateTime)assemblyInfo.Second; string urlAssemblyName; if (assembly.GlobalAssemblyCache) { // If the assembly is in the GAC, we need to store a full name to load the assembly later // Pack the necessary values into a more compact format than FullName StringBuilder builder = new StringBuilder(); builder.Append(assemblyName.Name); builder.Append(','); builder.Append(assemblyName.Version); builder.Append(','); if (assemblyName.CultureInfo != null) { builder.Append(assemblyName.CultureInfo); } builder.Append(','); builder.Append(HexParser.ToString(assemblyName.GetPublicKeyToken())); urlAssemblyName = builder.ToString(); } else { // Otherwise, we can just use a partial name urlAssemblyName = assemblyName.Name; } // First character of the encoded string is: // Z: compressed, append notifycriptLoaded // z: compressed, don't append notifyScriptLoaded // U: non-compressed, append notifyScriptLoaded // u: non-compressed, don't append notifyScriptLoaded if (_absoluteScriptResourceUrl == null) { _absoluteScriptResourceUrl = VirtualPathUtility.ToAbsolute(_scriptResourceUrl); } url = _absoluteScriptResourceUrl + "?d=" + Page.EncryptString( (zip ? (notifyScriptLoaded ? "Z" : "z") : (notifyScriptLoaded ? "U" : "u")) + urlAssemblyName + "|" + resourceName + "|" + culture.ToString()) + "&t=" + assemblyDate.Ticks; _urlCache[cacheKey] = url; } return url; } private static void ThrowUnknownResource(string resourceName) { throw new HttpException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ScriptResourceHandler_UnknownResource, resourceName)); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TimeSpan.cs
- TimeEnumHelper.cs
- PersonalizationStateQuery.cs
- BitmapPalettes.cs
- AssemblyNameProxy.cs
- ApplicationGesture.cs
- ResourceManagerWrapper.cs
- RowTypePropertyElement.cs
- MsmqIntegrationProcessProtocolHandler.cs
- ScalarOps.cs
- TextParagraphProperties.cs
- AppSettingsSection.cs
- RouteParser.cs
- CaseInsensitiveComparer.cs
- Selector.cs
- Image.cs
- GCHandleCookieTable.cs
- RefreshPropertiesAttribute.cs
- FilterQuery.cs
- Vector.cs
- ObjectListItemCollection.cs
- XmlLanguageConverter.cs
- SoapProtocolImporter.cs
- ExtensibleClassFactory.cs
- Bitmap.cs
- Queue.cs
- AnchorEditor.cs
- BindingWorker.cs
- TemplateControlCodeDomTreeGenerator.cs
- CollectionEditor.cs
- ConstraintManager.cs
- BaseAsyncResult.cs
- XmlWriterTraceListener.cs
- GiveFeedbackEventArgs.cs
- Int64.cs
- DataPagerFieldItem.cs
- FormViewDeletedEventArgs.cs
- GifBitmapEncoder.cs
- TextElement.cs
- GridEntry.cs
- xml.cs
- XmlIlTypeHelper.cs
- UdpDuplexChannel.cs
- XmlHierarchyData.cs
- SharedStatics.cs
- VariableReference.cs
- LogLogRecordHeader.cs
- MetabaseReader.cs
- CustomErrorsSection.cs
- DrawListViewSubItemEventArgs.cs
- IntranetCredentialPolicy.cs
- DataGridPagerStyle.cs
- UiaCoreTypesApi.cs
- GenericRootAutomationPeer.cs
- BamlResourceDeserializer.cs
- SamlAttribute.cs
- AnnotationHighlightLayer.cs
- DeploymentSection.cs
- DataSourceComponent.cs
- ObjectView.cs
- _SafeNetHandles.cs
- autovalidator.cs
- ZipIOBlockManager.cs
- SiteMapNode.cs
- RenderData.cs
- IPCCacheManager.cs
- TextSpan.cs
- DataGridViewLinkCell.cs
- StructuralCache.cs
- RsaSecurityTokenParameters.cs
- SelectionEditor.cs
- ColumnMapProcessor.cs
- XmlQualifiedNameTest.cs
- MaterializeFromAtom.cs
- updatecommandorderer.cs
- PropertyDescriptorGridEntry.cs
- QilUnary.cs
- XamlStyleSerializer.cs
- Attributes.cs
- ClientTargetSection.cs
- DeliveryStrategy.cs
- CannotUnloadAppDomainException.cs
- ListBoxChrome.cs
- RoutingExtensionElement.cs
- CodePageEncoding.cs
- UiaCoreTypesApi.cs
- FormCollection.cs
- CodePageUtils.cs
- SqlDataSourceSummaryPanel.cs
- DataFormats.cs
- SqlVisitor.cs
- ResourceDisplayNameAttribute.cs
- SafeSecurityHandles.cs
- TableStyle.cs
- CompilerTypeWithParams.cs
- MsiStyleLogWriter.cs
- XmlSchemaInclude.cs
- SafeSecurityHandles.cs
- DataSysAttribute.cs
- DataFormats.cs