private static void OnCacheItemRemoved(string key, object value, CacheItemRemovedReason reason)
        {
            CachedPathData data = (CachedPathData)value;

            data._flags[0x40] = true;
            data.Close();
        }
        internal static void RemoveBadPathData(CachedPathData pathData)
        {
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            string        configPath    = pathData._configPath;
            string        key           = CreateKey(configPath);

            while (((pathData != null) && !pathData.CompletedFirstRequest) && !pathData.Exists)
            {
                cacheInternal.Remove(key);
                configPath = System.Configuration.ConfigPathUtility.GetParent(configPath);
                if (configPath == null)
                {
                    return;
                }
                key      = CreateKey(configPath);
                pathData = (CachedPathData)cacheInternal.Get(key);
            }
        }
        internal static void MarkCompleted(CachedPathData pathData)
        {
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            string        configPath    = pathData._configPath;

Label_000D:
            pathData.CompletedFirstRequest = true;
            configPath = System.Configuration.ConfigPathUtility.GetParent(configPath);
            if (configPath != null)
            {
                string key = CreateKey(configPath);
                pathData = (CachedPathData)cacheInternal.Get(key);
                if ((pathData != null) && !pathData.CompletedFirstRequest)
                {
                    goto Label_000D;
                }
            }
        }
Ejemplo n.º 4
0
        // Mark CachedPathData as completed when the first request for the path results in a
        // status outside the 400 range. We need to mark all data up the path to account for
        // virtual files.
        static internal void MarkCompleted(CachedPathData pathData)
        {
            CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache;

            string configPath = pathData._configPath;

            do
            {
                pathData.CompletedFirstRequest = true;

                configPath = ConfigPathUtility.GetParent(configPath);
                if (configPath == null)
                {
                    break;
                }

                string key = CreateKey(configPath);
                pathData = (CachedPathData)cacheInternal.Get(key);
            } while (pathData != null && !pathData.CompletedFirstRequest);
        }
 private void Init(CachedPathData parentData)
 {
     if (!HttpConfigurationSystem.UseHttpConfigurationSystem)
     {
         this._runtimeConfig = null;
     }
     else
     {
         IInternalConfigRecord uniqueConfigRecord = HttpConfigurationSystem.GetUniqueConfigRecord(this._configPath);
         if (uniqueConfigRecord.ConfigPath.Length == this._configPath.Length)
         {
             this._flags[0x10]   = true;
             this._runtimeConfig = new System.Web.Configuration.RuntimeConfig(uniqueConfigRecord);
         }
         else
         {
             this._runtimeConfig = parentData._runtimeConfig;
         }
     }
 }
Ejemplo n.º 6
0
        // Remove CachedPathData when the first request for the path results in a
        // 400 range error. We need to remove all data up the path to account for
        // virtual files.
        // An example of a 400 range error is "path not found".
        static internal void RemoveBadPathData(CachedPathData pathData)
        {
            CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache;

            string configPath = pathData._configPath;
            string key        = CreateKey(configPath);

            while (pathData != null && !pathData.CompletedFirstRequest && !pathData.Exists)
            {
                cacheInternal.Remove(key);

                configPath = ConfigPathUtility.GetParent(configPath);
                if (configPath == null)
                {
                    break;
                }

                key      = CreateKey(configPath);
                pathData = (CachedPathData)cacheInternal.Get(key);
            }
        }
Ejemplo n.º 7
0
        // Initialize the data
        void Init(CachedPathData parentData)
        {
            // Note that _runtimeConfig will be set to the singleton instance of ErrorRuntimeConfig
            // if a ThreadAbortException is thrown during this method.
            Debug.Assert(_runtimeConfig == RuntimeConfig.GetErrorRuntimeConfig(), "_runtimeConfig == RuntimeConfig.GetErrorRuntimeConfig()");

            if (!HttpConfigurationSystem.UseHttpConfigurationSystem)
            {
                //
                // configRecord may legitimately be null if we are not using the HttpConfigurationSystem.
                //
                _runtimeConfig = null;
            }
            else
            {
                IInternalConfigRecord configRecord = HttpConfigurationSystem.GetUniqueConfigRecord(_configPath);
                Debug.Assert(configRecord != null, "configRecord != null");

                if (configRecord.ConfigPath.Length == _configPath.Length)
                {
                    //
                    // The config is unique to this path, so this make this record the owner of the config.
                    //
                    _flags[FOwnsConfigRecord] = true;
                    _runtimeConfig            = new RuntimeConfig(configRecord);
                }
                else
                {
                    //
                    // The config record is the same as an ancestor's, so use the parent's RuntimeConfig.
                    //
                    Debug.Assert(parentData != null, "parentData != null");
                    _runtimeConfig = parentData._runtimeConfig;
                }
            }
        }
Ejemplo n.º 8
0
        // Remove CachedPathData when the first request for the path results in a 
        // 400 range error. We need to remove all data up the path to account for
        // virtual files.
        // An example of a 400 range error is "path not found". 
        static internal void RemoveBadPathData(CachedPathData pathData) {
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;

            string configPath = pathData._configPath;
            string key = CreateKey(configPath);
            while (pathData != null && !pathData.CompletedFirstRequest && !pathData.Exists) {

                cacheInternal.Remove(key);

                configPath = ConfigPathUtility.GetParent(configPath);
                if (configPath == null)
                    break;

                key = CreateKey(configPath);
                pathData = (CachedPathData) cacheInternal.Get(key);
            }
        }
Ejemplo n.º 9
0
        // Example of configPath = "machine/webroot/1/fxtest/sub/foo.aspx"
        // The configPath parameter must be lower case.
        static private CachedPathData GetConfigPathData(string configPath) {
            Debug.Assert(ConfigPathUtility.IsValid(configPath), "ConfigPathUtility.IsValid(configPath)");
            Debug.Assert(configPath == configPath.ToLower(CultureInfo.InvariantCulture), "configPath == configPath.ToLower(CultureInfo.InvariantCulture)");
            bool exists = false;
            bool isDirectory = false;
            bool isRemovable = IsCachedPathDataRemovable(configPath);
            // if the sliding expiration is zero, we won't cache it unless it is a configPath for root web.config or above
            if (isRemovable && DoNotCacheUrlMetadata) {
                string pathSiteID = null;
                VirtualPath virtualFilePath = null;
                string physicalFilePath = null;
                WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPath, out pathSiteID, out virtualFilePath);
                physicalFilePath = GetPhysicalPath(virtualFilePath);

                string parentConfigPath = ConfigPathUtility.GetParent(configPath);
                CachedPathData pathParentData = GetConfigPathData(parentConfigPath);
                if (!String.IsNullOrEmpty(physicalFilePath)) {
                    FileUtil.PhysicalPathStatus(physicalFilePath, false, false, out exists, out isDirectory);
                }
                CachedPathData pathData = new CachedPathData(configPath, virtualFilePath, physicalFilePath, exists);
                pathData.Init(pathParentData);

                return pathData;
            }

            //
            // First, see if the CachedPathData is in the cache.
            // we don't use Add for this lookup, as doing so requires
            // creating a CacheDependency, which can be slow as it may hit
            // the filesystem.
            //
            string key = CreateKey(configPath);
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            CachedPathData data = (CachedPathData) cacheInternal.Get(key);

            // if found, return the data
            if (data != null) {
                data.WaitForInit();
                return data;
            }
            
            // WOS 


            bool cacheEntryIsNotRemovable = false;

            // if not found, try to add it
            string siteID = null;
            VirtualPath virtualPath = null;
            CachedPathData parentData = null;
            CacheDependency dependency = null;
            string physicalPath = null;
            string[] fileDependencies = null;
            string[] cacheItemDependencies = null;

            if (WebConfigurationHost.IsMachineConfigPath(configPath)) {
                cacheEntryIsNotRemovable = true;
            }
            else {
                // Make sure we have the parent data so we can create a dependency on the parent.
                // The parent dependency will ensure that configuration data in the parent 
                // will be referenced by a cache hit on the child. (see UtcUpdateUsageRecursive in Cache.cs)
                string parentConfigPath = ConfigPathUtility.GetParent(configPath);
                parentData = GetConfigPathData(parentConfigPath);
                string parentKey = CreateKey(parentConfigPath);
                cacheItemDependencies = new string[1] {parentKey};

                if (!WebConfigurationHost.IsVirtualPathConfigPath(configPath)) {
                    // assume hardcoded levels above the path, such as root web.config, exist
                    cacheEntryIsNotRemovable = true;
                }
                else {
                    cacheEntryIsNotRemovable = !isRemovable;
                    WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPath, out siteID, out virtualPath);
                    physicalPath = GetPhysicalPath(virtualPath);

                    // Add a dependency on the path itself, if it is a file,
                    // to handle the case where a file is deleted and replaced
                    // with a directory of the same name.
                    if (!String.IsNullOrEmpty(physicalPath)) {
                        FileUtil.PhysicalPathStatus(physicalPath, false, false, out exists, out isDirectory);
                        if (exists && !isDirectory) {
                            fileDependencies = new string[1] {physicalPath};
                        }
                    }
                }

                try {
                    dependency = new CacheDependency(0, fileDependencies, cacheItemDependencies);
                }
                catch {
                    // CacheDependency ctor could fail because of bogus file path
                    // and it is ok not to watch those
                }
            }

            // Try to add the CachedPathData to the cache.
            CachedPathData    dataAdd = null;
            bool              isDataCreator = false;
            bool              initCompleted = false;
            CacheItemPriority priority = cacheEntryIsNotRemovable ? CacheItemPriority.NotRemovable : CacheItemPriority.Normal;
            TimeSpan          slidingExpiration = cacheEntryIsNotRemovable ? Cache.NoSlidingExpiration : UrlMetadataSlidingExpiration;
            try {
                using (dependency) {
                    dataAdd = new CachedPathData(configPath, virtualPath, physicalPath, exists);
                    try {
                    }
                    finally {
                        data = (CachedPathData) cacheInternal.UtcAdd(key, dataAdd, dependency, 
                            Cache.NoAbsoluteExpiration, slidingExpiration, 
                            priority, s_callback);
                        
                        if (data == null) {
                            isDataCreator = true;
                        }
                    }
                }

                // If another thread added it first, return the data
                if (!isDataCreator) {
                    data.WaitForInit();
                    return data;
                }

                // This thread is the creator of the CachedPathData, initialize it
                lock (dataAdd) {
                    try {
                        dataAdd.Init(parentData);
                        initCompleted = true;
                    }
                    finally {
                        // free waiters
                        dataAdd._flags[FInited] = true;
                
                        // Wake up waiters.
                        Monitor.PulseAll(dataAdd);
                
                        if (dataAdd._flags[FCloseNeeded]) {
                            // If we have received a call back to close, then lets 
                            // make sure that our config object is cleaned up
                            dataAdd.Close();
                        }
                    }
                }
            }
            finally {
                // All the work in this finally block is for the case where we're the
                // creator of the CachedPathData.
                if (isDataCreator) {

                    // 




                    if (!dataAdd._flags[FInited]) {
                        lock (dataAdd) {
                            // free waiters
                            dataAdd._flags[FInited] = true;
                    
                            // Wake up waiters.
                            Monitor.PulseAll(dataAdd);
                            
                            if (dataAdd._flags[FCloseNeeded]) {
                                // If we have received a call back to close, then lets 
                                // make sure that our config object is cleaned up
                                dataAdd.Close();
                            }
                        }
                    }
                    
                    //
                    // Even though there is a try/catch handler surrounding the call to Init,
                    // a ThreadAbortException can still cause the handler to be bypassed.
                    //
                    // If there is an error, either a thread abort or an error in the config
                    // file itself, we do want to leave the item cached for a short period
                    // so that we do not revisit the error and potentially reparse the config file
                    // on every request.
                    // 
                    // The reason we simply do not leave the item in the cache forever is that the 
                    // problem that caused the configuration exception may be fixed without touching
                    // the config file in a way that causes a file change notification (for example, an 
                    // acl change in a parent directory, or a change of path mapping in the metabase).
                    //
                    // NOTE: It is important to reinsert the item into the cache AFTER dropping
                    // the lock on dataAdd, in order to prevent the possibility of deadlock.
                    //
                    Debug.Assert(dataAdd._flags[FInited], "_flags[FInited]");
                    if (!initCompleted || (dataAdd.ConfigRecord != null && dataAdd.ConfigRecord.HasInitErrors)) {
                        //
                        // Create a new dependency object as the old one cannot be reused.
                        // Do not include a file dependency if initialization could not be completed,
                        // as invoking the file system could lead to further errors during a thread abort.
                        //
                        if (dependency != null) {
                            if (!initCompleted) {
                                dependency = new CacheDependency(0, null, cacheItemDependencies);
                            }
                            else {
                                dependency = new CacheDependency(0, fileDependencies, cacheItemDependencies);
                            }
                        }
                    
                        using (dependency) {
                            cacheInternal.UtcInsert(key, dataAdd, dependency, 
                                DateTime.UtcNow.AddSeconds(5), Cache.NoSlidingExpiration,
                                CacheItemPriority.Normal, s_callback);
                        }
                    }
                    
                }
            }

            return dataAdd;
        }
Ejemplo n.º 10
0
        internal CachedPathData GetConfigurationPathData() {
            if (_configurationPath == null) {
                return GetFilePathData();
            }

            // 
            if (_configurationPathData == null) {
                _configurationPathData = CachedPathData.GetVirtualPathData(_configurationPath, true);
            }

            return _configurationPathData;
        }
Ejemplo n.º 11
0
        internal CachedPathData GetFilePathData() {
            if (_filePathData == null) {
                _filePathData = CachedPathData.GetVirtualPathData(_request.FilePathObject, false);
            }

            return _filePathData;
        }
        private static CachedPathData GetConfigPathData(string configPath)
        {
            bool exists      = false;
            bool isDirectory = false;
            bool flag3       = IsCachedPathDataRemovable(configPath);

            if (flag3 && DoNotCacheUrlMetadata)
            {
                string      str          = null;
                VirtualPath path         = null;
                string      physicalPath = null;
                WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPath, out str, out path);
                physicalPath = GetPhysicalPath(path);
                CachedPathData configPathData = GetConfigPathData(System.Configuration.ConfigPathUtility.GetParent(configPath));
                if (!string.IsNullOrEmpty(physicalPath))
                {
                    System.Web.Util.FileUtil.PhysicalPathStatus(physicalPath, false, false, out exists, out isDirectory);
                }
                CachedPathData data2 = new CachedPathData(configPath, path, physicalPath, exists);
                data2.Init(configPathData);
                return(data2);
            }
            string         key           = CreateKey(configPath);
            CacheInternal  cacheInternal = HttpRuntime.CacheInternal;
            CachedPathData data3         = (CachedPathData)cacheInternal.Get(key);

            if (data3 != null)
            {
                data3.WaitForInit();
                return(data3);
            }
            bool            flag4        = false;
            string          siteID       = null;
            VirtualPath     vpath        = null;
            CachedPathData  parentData   = null;
            CacheDependency dependencies = null;
            string          str6         = null;

            string[] filenames = null;
            string[] cachekeys = null;
            if (WebConfigurationHost.IsMachineConfigPath(configPath))
            {
                flag4 = true;
            }
            else
            {
                string parent = System.Configuration.ConfigPathUtility.GetParent(configPath);
                parentData = GetConfigPathData(parent);
                string str8 = CreateKey(parent);
                cachekeys = new string[] { str8 };
                if (!WebConfigurationHost.IsVirtualPathConfigPath(configPath))
                {
                    flag4 = true;
                }
                else
                {
                    flag4 = !flag3;
                    WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPath, out siteID, out vpath);
                    str6 = GetPhysicalPath(vpath);
                    if (!string.IsNullOrEmpty(str6))
                    {
                        System.Web.Util.FileUtil.PhysicalPathStatus(str6, false, false, out exists, out isDirectory);
                        if (exists && !isDirectory)
                        {
                            filenames = new string[] { str6 };
                        }
                    }
                }
                try
                {
                    dependencies = new CacheDependency(0, filenames, cachekeys);
                }
                catch
                {
                }
            }
            CachedPathData    data5             = null;
            bool              flag5             = false;
            bool              flag6             = false;
            CacheItemPriority priority          = flag4 ? CacheItemPriority.NotRemovable : CacheItemPriority.Normal;
            TimeSpan          slidingExpiration = flag4 ? Cache.NoSlidingExpiration : UrlMetadataSlidingExpiration;

            try
            {
                using (dependencies)
                {
                    data5 = new CachedPathData(configPath, vpath, str6, exists);
                    try
                    {
                    }
                    finally
                    {
                        data3 = (CachedPathData)cacheInternal.UtcAdd(key, data5, dependencies, Cache.NoAbsoluteExpiration, slidingExpiration, priority, s_callback);
                        if (data3 == null)
                        {
                            flag5 = true;
                        }
                    }
                }
                if (!flag5)
                {
                    data3.WaitForInit();
                    return(data3);
                }
                lock (data5)
                {
                    try
                    {
                        data5.Init(parentData);
                        flag6 = true;
                    }
                    finally
                    {
                        data5._flags[1] = true;
                        Monitor.PulseAll(data5);
                        if (data5._flags[0x40])
                        {
                            data5.Close();
                        }
                    }
                    return(data5);
                }
            }
            finally
            {
                if (flag5)
                {
                    if (!data5._flags[1])
                    {
                        lock (data5)
                        {
                            data5._flags[1] = true;
                            Monitor.PulseAll(data5);
                            if (data5._flags[0x40])
                            {
                                data5.Close();
                            }
                        }
                    }
                    if (!flag6 || ((data5.ConfigRecord != null) && data5.ConfigRecord.HasInitErrors))
                    {
                        if (dependencies != null)
                        {
                            if (!flag6)
                            {
                                dependencies = new CacheDependency(0, null, cachekeys);
                            }
                            else
                            {
                                dependencies = new CacheDependency(0, filenames, cachekeys);
                            }
                        }
                        using (dependencies)
                        {
                            cacheInternal.UtcInsert(key, data5, dependencies, DateTime.UtcNow.AddSeconds(5.0), Cache.NoSlidingExpiration, CacheItemPriority.Normal, s_callback);
                        }
                    }
                }
            }
            return(data5);
        }
 internal CachedPathData GetConfigurationPathData()
 {
     if (this._configurationPath == null)
     {
         return this.GetFilePathData();
     }
     if (this._configurationPathData == null)
     {
         this._configurationPathData = CachedPathData.GetVirtualPathData(this._configurationPath, true);
     }
     return this._configurationPathData;
 }
Ejemplo n.º 14
0
        // Mark CachedPathData as completed when the first request for the path results in a 
        // status outside the 400 range. We need to mark all data up the path to account for
        // virtual files.
        static internal void MarkCompleted(CachedPathData pathData) {
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;

            string configPath = pathData._configPath;
            do {
                pathData.CompletedFirstRequest = true;

                configPath = ConfigPathUtility.GetParent(configPath);
                if (configPath == null)
                    break;

                string key = CreateKey(configPath);
                pathData = (CachedPathData) cacheInternal.Get(key);
            } while (pathData != null && !pathData.CompletedFirstRequest);
        }
 private static CachedPathData GetConfigPathData(string configPath)
 {
     bool exists = false;
     bool isDirectory = false;
     bool flag3 = IsCachedPathDataRemovable(configPath);
     if (flag3 && DoNotCacheUrlMetadata)
     {
         string str = null;
         VirtualPath path = null;
         string physicalPath = null;
         WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPath, out str, out path);
         physicalPath = GetPhysicalPath(path);
         CachedPathData configPathData = GetConfigPathData(System.Configuration.ConfigPathUtility.GetParent(configPath));
         if (!string.IsNullOrEmpty(physicalPath))
         {
             System.Web.Util.FileUtil.PhysicalPathStatus(physicalPath, false, false, out exists, out isDirectory);
         }
         CachedPathData data2 = new CachedPathData(configPath, path, physicalPath, exists);
         data2.Init(configPathData);
         return data2;
     }
     string key = CreateKey(configPath);
     CacheInternal cacheInternal = HttpRuntime.CacheInternal;
     CachedPathData data3 = (CachedPathData) cacheInternal.Get(key);
     if (data3 != null)
     {
         data3.WaitForInit();
         return data3;
     }
     bool flag4 = false;
     string siteID = null;
     VirtualPath vpath = null;
     CachedPathData parentData = null;
     CacheDependency dependencies = null;
     string str6 = null;
     string[] filenames = null;
     string[] cachekeys = null;
     if (WebConfigurationHost.IsMachineConfigPath(configPath))
     {
         flag4 = true;
     }
     else
     {
         string parent = System.Configuration.ConfigPathUtility.GetParent(configPath);
         parentData = GetConfigPathData(parent);
         string str8 = CreateKey(parent);
         cachekeys = new string[] { str8 };
         if (!WebConfigurationHost.IsVirtualPathConfigPath(configPath))
         {
             flag4 = true;
         }
         else
         {
             flag4 = !flag3;
             WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPath, out siteID, out vpath);
             str6 = GetPhysicalPath(vpath);
             if (!string.IsNullOrEmpty(str6))
             {
                 System.Web.Util.FileUtil.PhysicalPathStatus(str6, false, false, out exists, out isDirectory);
                 if (exists && !isDirectory)
                 {
                     filenames = new string[] { str6 };
                 }
             }
         }
         try
         {
             dependencies = new CacheDependency(0, filenames, cachekeys);
         }
         catch
         {
         }
     }
     CachedPathData data5 = null;
     bool flag5 = false;
     bool flag6 = false;
     CacheItemPriority priority = flag4 ? CacheItemPriority.NotRemovable : CacheItemPriority.Normal;
     TimeSpan slidingExpiration = flag4 ? Cache.NoSlidingExpiration : UrlMetadataSlidingExpiration;
     try
     {
         using (dependencies)
         {
             data5 = new CachedPathData(configPath, vpath, str6, exists);
             try
             {
             }
             finally
             {
                 data3 = (CachedPathData) cacheInternal.UtcAdd(key, data5, dependencies, Cache.NoAbsoluteExpiration, slidingExpiration, priority, s_callback);
                 if (data3 == null)
                 {
                     flag5 = true;
                 }
             }
         }
         if (!flag5)
         {
             data3.WaitForInit();
             return data3;
         }
         lock (data5)
         {
             try
             {
                 data5.Init(parentData);
                 flag6 = true;
             }
             finally
             {
                 data5._flags[1] = true;
                 Monitor.PulseAll(data5);
                 if (data5._flags[0x40])
                 {
                     data5.Close();
                 }
             }
             return data5;
         }
     }
     finally
     {
         if (flag5)
         {
             if (!data5._flags[1])
             {
                 lock (data5)
                 {
                     data5._flags[1] = true;
                     Monitor.PulseAll(data5);
                     if (data5._flags[0x40])
                     {
                         data5.Close();
                     }
                 }
             }
             if (!flag6 || ((data5.ConfigRecord != null) && data5.ConfigRecord.HasInitErrors))
             {
                 if (dependencies != null)
                 {
                     if (!flag6)
                     {
                         dependencies = new CacheDependency(0, null, cachekeys);
                     }
                     else
                     {
                         dependencies = new CacheDependency(0, filenames, cachekeys);
                     }
                 }
                 using (dependencies)
                 {
                     cacheInternal.UtcInsert(key, data5, dependencies, DateTime.UtcNow.AddSeconds(5.0), Cache.NoSlidingExpiration, CacheItemPriority.Normal, s_callback);
                 }
             }
         }
     }
     return data5;
 }
 internal static void RemoveBadPathData(CachedPathData pathData)
 {
     CacheInternal cacheInternal = HttpRuntime.CacheInternal;
     string configPath = pathData._configPath;
     string key = CreateKey(configPath);
     while (((pathData != null) && !pathData.CompletedFirstRequest) && !pathData.Exists)
     {
         cacheInternal.Remove(key);
         configPath = System.Configuration.ConfigPathUtility.GetParent(configPath);
         if (configPath == null)
         {
             return;
         }
         key = CreateKey(configPath);
         pathData = (CachedPathData) cacheInternal.Get(key);
     }
 }
 internal static void MarkCompleted(CachedPathData pathData)
 {
     CacheInternal cacheInternal = HttpRuntime.CacheInternal;
     string configPath = pathData._configPath;
 Label_000D:
     pathData.CompletedFirstRequest = true;
     configPath = System.Configuration.ConfigPathUtility.GetParent(configPath);
     if (configPath != null)
     {
         string key = CreateKey(configPath);
         pathData = (CachedPathData) cacheInternal.Get(key);
         if ((pathData != null) && !pathData.CompletedFirstRequest)
         {
             goto Label_000D;
         }
     }
 }
 private void Init(CachedPathData parentData)
 {
     if (!HttpConfigurationSystem.UseHttpConfigurationSystem)
     {
         this._runtimeConfig = null;
     }
     else
     {
         IInternalConfigRecord uniqueConfigRecord = HttpConfigurationSystem.GetUniqueConfigRecord(this._configPath);
         if (uniqueConfigRecord.ConfigPath.Length == this._configPath.Length)
         {
             this._flags[0x10] = true;
             this._runtimeConfig = new System.Web.Configuration.RuntimeConfig(uniqueConfigRecord);
         }
         else
         {
             this._runtimeConfig = parentData._runtimeConfig;
         }
     }
 }
Ejemplo n.º 19
0
        // Initialize the data
        void Init(CachedPathData parentData) {
            // Note that _runtimeConfig will be set to the singleton instance of ErrorRuntimeConfig
            // if a ThreadAbortException is thrown during this method.
            Debug.Assert(_runtimeConfig == RuntimeConfig.GetErrorRuntimeConfig(), "_runtimeConfig == RuntimeConfig.GetErrorRuntimeConfig()");

            if (!HttpConfigurationSystem.UseHttpConfigurationSystem) {
                // 
                // configRecord may legitimately be null if we are not using the HttpConfigurationSystem.
                //
                _runtimeConfig = null;
            }
            else {
                IInternalConfigRecord configRecord = HttpConfigurationSystem.GetUniqueConfigRecord(_configPath);
                Debug.Assert(configRecord != null, "configRecord != null");

                if (configRecord.ConfigPath.Length == _configPath.Length) {
                    //
                    // The config is unique to this path, so this make this record the owner of the config.
                    //
                    _flags[FOwnsConfigRecord] = true;
                    _runtimeConfig = new RuntimeConfig(configRecord);
                }
                else {
                    //
                    // The config record is the same as an ancestor's, so use the parent's RuntimeConfig.
                    //
                    Debug.Assert(parentData != null, "parentData != null");
                    _runtimeConfig = parentData._runtimeConfig;
                }
            }
        }
Ejemplo n.º 20
0
        // Example of configPath = "machine/webroot/1/fxtest/sub/foo.aspx"
        // The configPath parameter must be lower case.
        static private CachedPathData GetConfigPathData(string configPath)
        {
            Debug.Assert(ConfigPathUtility.IsValid(configPath), "ConfigPathUtility.IsValid(configPath)");
            Debug.Assert(configPath == configPath.ToLower(CultureInfo.InvariantCulture), "configPath == configPath.ToLower(CultureInfo.InvariantCulture)");
            bool exists      = false;
            bool isDirectory = false;
            bool isRemovable = IsCachedPathDataRemovable(configPath);

            // if the sliding expiration is zero, we won't cache it unless it is a configPath for root web.config or above
            if (isRemovable && DoNotCacheUrlMetadata)
            {
                string      pathSiteID       = null;
                VirtualPath virtualFilePath  = null;
                string      physicalFilePath = null;
                WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPath, out pathSiteID, out virtualFilePath);
                physicalFilePath = GetPhysicalPath(virtualFilePath);

                string         parentConfigPath = ConfigPathUtility.GetParent(configPath);
                CachedPathData pathParentData   = GetConfigPathData(parentConfigPath);
                if (!String.IsNullOrEmpty(physicalFilePath))
                {
                    FileUtil.PhysicalPathStatus(physicalFilePath, false, false, out exists, out isDirectory);
                }
                CachedPathData pathData = new CachedPathData(configPath, virtualFilePath, physicalFilePath, exists);
                pathData.Init(pathParentData);

                return(pathData);
            }

            //
            // First, see if the CachedPathData is in the cache.
            // we don't use Add for this lookup, as doing so requires
            // creating a CacheDependency, which can be slow as it may hit
            // the filesystem.
            //
            string             key           = CreateKey(configPath);
            CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache;
            CachedPathData     data          = (CachedPathData)cacheInternal.Get(key);

            // if found, return the data
            if (data != null)
            {
                data.WaitForInit();
                return(data);
            }

            // WOS


            bool cacheEntryIsNotRemovable = false;

            // if not found, try to add it
            string          siteID       = null;
            VirtualPath     virtualPath  = null;
            CachedPathData  parentData   = null;
            CacheDependency dependency   = null;
            string          physicalPath = null;

            string[] fileDependencies      = null;
            string[] cacheItemDependencies = null;

            if (WebConfigurationHost.IsMachineConfigPath(configPath))
            {
                cacheEntryIsNotRemovable = true;
            }
            else
            {
                // Make sure we have the parent data so we can create a dependency on the parent.
                // The parent dependency will ensure that configuration data in the parent
                // will be referenced by a cache hit on the child. (see UtcUpdateUsageRecursive in Cache.cs)
                string parentConfigPath = ConfigPathUtility.GetParent(configPath);
                parentData = GetConfigPathData(parentConfigPath);
                string parentKey = CreateKey(parentConfigPath);
                cacheItemDependencies = new string[1] {
                    parentKey
                };

                if (!WebConfigurationHost.IsVirtualPathConfigPath(configPath))
                {
                    // assume hardcoded levels above the path, such as root web.config, exist
                    cacheEntryIsNotRemovable = true;
                }
                else
                {
                    cacheEntryIsNotRemovable = !isRemovable;
                    WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPath, out siteID, out virtualPath);
                    physicalPath = GetPhysicalPath(virtualPath);

                    // Add a dependency on the path itself, if it is a file,
                    // to handle the case where a file is deleted and replaced
                    // with a directory of the same name.
                    if (!String.IsNullOrEmpty(physicalPath))
                    {
                        FileUtil.PhysicalPathStatus(physicalPath, false, false, out exists, out isDirectory);
                        if (exists && !isDirectory)
                        {
                            fileDependencies = new string[1] {
                                physicalPath
                            };
                        }
                    }
                }

                try {
                    dependency = new CacheDependency(0, fileDependencies, cacheItemDependencies);
                }
                catch {
                    // CacheDependency ctor could fail because of bogus file path
                    // and it is ok not to watch those
                }
            }

            // Try to add the CachedPathData to the cache.
            CachedPathData    dataAdd           = null;
            bool              isDataCreator     = false;
            bool              initCompleted     = false;
            CacheItemPriority priority          = cacheEntryIsNotRemovable ? CacheItemPriority.NotRemovable : CacheItemPriority.Normal;
            TimeSpan          slidingExpiration = cacheEntryIsNotRemovable ? Cache.NoSlidingExpiration : UrlMetadataSlidingExpiration;

            try {
                using (dependency) {
                    dataAdd = new CachedPathData(configPath, virtualPath, physicalPath, exists);
                    try {
                    }
                    finally {
                        data = (CachedPathData)cacheInternal.Add(key, dataAdd, new CacheInsertOptions()
                        {
                            Dependencies      = dependency,
                            SlidingExpiration = slidingExpiration,
                            Priority          = priority,
                            OnRemovedCallback = s_callback
                        });

                        if (data == null)
                        {
                            isDataCreator = true;
                        }
                    }
                }

                // If another thread added it first, return the data
                if (!isDataCreator)
                {
                    data.WaitForInit();
                    return(data);
                }

                // This thread is the creator of the CachedPathData, initialize it
                lock (dataAdd) {
                    try {
                        dataAdd.Init(parentData);
                        initCompleted = true;
                    }
                    finally {
                        // free waiters
                        dataAdd._flags[FInited] = true;

                        // Wake up waiters.
                        Monitor.PulseAll(dataAdd);

                        if (dataAdd._flags[FCloseNeeded])
                        {
                            // If we have received a call back to close, then lets
                            // make sure that our config object is cleaned up
                            dataAdd.Close();
                        }
                    }
                }
            }
            finally {
                // All the work in this finally block is for the case where we're the
                // creator of the CachedPathData.
                if (isDataCreator)
                {
                    //



                    if (!dataAdd._flags[FInited])
                    {
                        lock (dataAdd) {
                            // free waiters
                            dataAdd._flags[FInited] = true;

                            // Wake up waiters.
                            Monitor.PulseAll(dataAdd);

                            if (dataAdd._flags[FCloseNeeded])
                            {
                                // If we have received a call back to close, then lets
                                // make sure that our config object is cleaned up
                                dataAdd.Close();
                            }
                        }
                    }

                    //
                    // Even though there is a try/catch handler surrounding the call to Init,
                    // a ThreadAbortException can still cause the handler to be bypassed.
                    //
                    // If there is an error, either a thread abort or an error in the config
                    // file itself, we do want to leave the item cached for a short period
                    // so that we do not revisit the error and potentially reparse the config file
                    // on every request.
                    //
                    // The reason we simply do not leave the item in the cache forever is that the
                    // problem that caused the configuration exception may be fixed without touching
                    // the config file in a way that causes a file change notification (for example, an
                    // acl change in a parent directory, or a change of path mapping in the metabase).
                    //
                    // NOTE: It is important to reinsert the item into the cache AFTER dropping
                    // the lock on dataAdd, in order to prevent the possibility of deadlock.
                    //
                    Debug.Assert(dataAdd._flags[FInited], "_flags[FInited]");
                    if (!initCompleted || (dataAdd.ConfigRecord != null && dataAdd.ConfigRecord.HasInitErrors))
                    {
                        //
                        // Create a new dependency object as the old one cannot be reused.
                        // Do not include a file dependency if initialization could not be completed,
                        // as invoking the file system could lead to further errors during a thread abort.
                        //
                        if (dependency != null)
                        {
                            if (!initCompleted)
                            {
                                dependency = new CacheDependency(0, null, cacheItemDependencies);
                            }
                            else
                            {
                                dependency = new CacheDependency(0, fileDependencies, cacheItemDependencies);
                            }
                        }

                        using (dependency) {
                            cacheInternal.Insert(key, dataAdd, new CacheInsertOptions()
                            {
                                Dependencies       = dependency,
                                AbsoluteExpiration = DateTime.UtcNow.AddSeconds(5),
                                OnRemovedCallback  = s_callback
                            });
                        }
                    }
                }
            }

            return(dataAdd);
        }