Exemple #1
0
        static void ReenableWatcherOnConfigLocation(object state)
        {
            string path = state as string;

            if (String.IsNullOrEmpty(path))
            {
                return;
            }

            DateTime lastWrite;

            lock (saveLocationsCacheLock) {
                if (!saveLocationsCache.TryGetValue(path, out lastWrite))
                {
                    lastWrite = DateTime.MinValue;
                }
            }

            DateTime now = DateTime.Now;

            if (lastWrite == DateTime.MinValue || now.Subtract(lastWrite).TotalMilliseconds >= SAVE_LOCATIONS_CHECK_INTERVAL)
            {
                saveLocationsTimer.Dispose();
                saveLocationsTimer = null;
                HttpApplicationFactory.EnableWatcher(VirtualPathUtility.RemoveTrailingSlash(HttpRuntime.AppDomainAppPath), "?eb.?onfig");
            }
            else
            {
                saveLocationsTimer.Change(SAVE_LOCATIONS_CHECK_INTERVAL, SAVE_LOCATIONS_CHECK_INTERVAL);
            }
        }
Exemple #2
0
 internal void RaiseOnEnd(HttpSessionState sessionState)
 {
     if (this._sessionEndEventHandlerCount > 0)
     {
         HttpApplicationFactory.EndSession(sessionState, this, EventArgs.Empty);
     }
 }
Exemple #3
0
        //
        // callbacks
        //

        private static void HandleErrorWithoutContext(Exception e)
        {
            HttpApplicationFactory.RaiseError(e);
            try {
                WebBaseEvent.RaiseRuntimeError(e, typeof(OutputCache));
            }
            catch {
            }
        }
Exemple #4
0
        static StateRuntime()
        {
            StateApplication app = new StateApplication();

            HttpApplicationFactory.SetCustomApplication(app);

            PerfCounters.Open(null);
            ResetStateServerCounters();
        }
Exemple #5
0
        internal void OnSessionRemoved(string key, object value, CacheItemRemovedReason reason)
        {
            SessionConfig cfg = GetConfig();

            // Only invoked for InProc (see msdn2 docs on SessionStateModule.End)
            if (cfg.Mode == SessionStateMode.InProc)
            {
                HttpApplicationFactory.InvokeSessionEnd(value);
            }
        }
Exemple #6
0
        public static void MarkAsSafe(LowerCodeCharts lowerCodeCharts, LowerMidCodeCharts lowerMidCodeCharts,
                                      MidCodeCharts midCodeCharts, UpperMidCodeCharts upperMidCodeCharts, UpperCodeCharts upperCodeCharts)
        {
            // should be callable from console apps
            if (HostingEnvironment.IsHosted)
            {
                HttpApplicationFactory.ThrowIfApplicationOnStartCalled();
            }

            UnicodeCharacterEncoder.MarkAsSafe(lowerCodeCharts, lowerMidCodeCharts, midCodeCharts, upperMidCodeCharts, upperCodeCharts);
        }
Exemple #7
0
        static void ConfigurationSaveHandler(_Configuration sender, ConfigurationSaveEventArgs args)
        {
            bool locked = false;

            try {
#if SYSTEMCORE_DEP
                sectionCacheLock.EnterWriteLock();
#endif
                locked = true;
                sectionCache.Clear();
            } finally {
#if SYSTEMCORE_DEP
                if (locked)
                {
                    sectionCacheLock.ExitWriteLock();
                }
#endif
            }

            lock (suppressAppReloadLock) {
                string rootConfigPath = WebConfigurationHost.GetWebConfigFileName(HttpRuntime.AppDomainAppPath);
                if (String.Compare(args.StreamPath, rootConfigPath, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    SuppressAppReload(args.Start);
                    if (args.Start)
                    {
                        HttpApplicationFactory.DisableWatcher(VirtualPathUtility.RemoveTrailingSlash(HttpRuntime.AppDomainAppPath), "?eb.?onfig");

                        lock (saveLocationsCacheLock) {
                            if (saveLocationsCache == null)
                            {
                                saveLocationsCache = new Dictionary <string, DateTime> (StringComparer.Ordinal);
                            }
                            if (saveLocationsCache.ContainsKey(rootConfigPath))
                            {
                                saveLocationsCache [rootConfigPath] = DateTime.Now;
                            }
                            else
                            {
                                saveLocationsCache.Add(rootConfigPath, DateTime.Now);
                            }

                            if (saveLocationsTimer == null)
                            {
                                saveLocationsTimer = new Timer(ReenableWatcherOnConfigLocation,
                                                               rootConfigPath,
                                                               SAVE_LOCATIONS_CHECK_INTERVAL,
                                                               SAVE_LOCATIONS_CHECK_INTERVAL);
                            }
                        }
                    }
                }
            }
        }
        static StateRuntime()
        {
            WebConfigurationFileMap fileMap       = new WebConfigurationFileMap();
            UserMapPath             configMapPath = new UserMapPath(fileMap);

            HttpConfigurationSystem.EnsureInit(configMapPath, false, true);
            StateApplication customApplication = new StateApplication();

            HttpApplicationFactory.SetCustomApplication(customApplication);
            PerfCounters.OpenStateCounters();
            ResetStateServerCounters();
        }
Exemple #9
0
        public AppResourceFilesCollection(string parserDir)
        {
            if (String.IsNullOrEmpty(parserDir))
            {
                throw new ArgumentException("parserDir cannot be empty");
            }
            this.isGlobal = true;
            this.files    = new List <AppResourceFileInfo> ();

            string resourcePath;

            resourcePath = Path.Combine(parserDir, "App_LocalResources");
            if (Directory.Exists(resourcePath))
            {
                sourceDir = resourcePath;
                HttpApplicationFactory.WatchLocationForRestart(sourceDir, "*");
            }
        }
        public void InitializeApplication(IntPtr appContext)
        {
            s_ApplicationContext = appContext;
            HttpApplication app = null;

            try
            {
                HttpRuntime.UseIntegratedPipeline = true;
                if (!HttpRuntime.HostingInitFailed)
                {
                    HttpWorkerRequest wr      = new SimpleWorkerRequest("", "", new StringWriter(CultureInfo.InvariantCulture));
                    HttpContext       context = new HttpContext(wr);
                    app = HttpApplicationFactory.GetPipelineApplicationInstance(appContext, context);
                }
            }
            catch (Exception exception)
            {
                if (HttpRuntime.InitializationException == null)
                {
                    HttpRuntime.InitializationException = exception;
                }
            }
            finally
            {
                s_InitializationCompleted = true;
                if (HttpRuntime.InitializationException != null)
                {
                    int errorCode = UnsafeIISMethods.MgdRegisterEventSubscription(appContext, "AspNetInitializationExceptionModule", RequestNotification.BeginRequest, 0, "AspNetInitializationExceptionModule", "", new IntPtr(-1), false);
                    if (errorCode < 0)
                    {
                        throw new COMException(System.Web.SR.GetString("Failed_Pipeline_Subscription", new object[] { "AspNetInitializationExceptionModule" }), errorCode);
                    }
                    errorCode = UnsafeIISMethods.MgdRegisterEventSubscription(appContext, "ManagedPipelineHandler", RequestNotification.ExecuteRequestHandler, 0, string.Empty, "managedHandler", new IntPtr(-1), false);
                    if (errorCode < 0)
                    {
                        throw new COMException(System.Web.SR.GetString("Failed_Pipeline_Subscription", new object[] { "ManagedPipelineHandler" }), errorCode);
                    }
                }
                if (app != null)
                {
                    HttpApplicationFactory.RecyclePipelineApplicationInstance(app);
                }
            }
        }
 private void CallCacheItemRemovedCallback(CacheItemRemovedCallback callback, CacheItemRemovedReason reason)
 {
     if (base.IsPublic)
     {
         try
         {
             if (HttpContext.Current == null)
             {
                 using (new ApplicationImpersonationContext())
                 {
                     callback(base._key, this._value, reason);
                     return;
                 }
             }
             callback(base._key, this._value, reason);
         }
         catch (Exception exception)
         {
             HttpApplicationFactory.RaiseError(exception);
             try
             {
                 WebBaseEvent.RaiseRuntimeError(exception, this);
             }
             catch
             {
             }
         }
     }
     else
     {
         try
         {
             using (new ApplicationImpersonationContext())
             {
                 callback(base._key, this._value, reason);
             }
         }
         catch
         {
         }
     }
 }
Exemple #12
0
        /*
         * Helper to call the on-remove callback
         */

        private void CallCacheItemRemovedCallback(CacheItemRemovedCallback callback, CacheItemRemovedReason reason)
        {
            if (IsPublic)
            {
                try {
                    // for public need to impersonate if called outside of request context
                    if (HttpContext.Current == null)
                    {
                        using (new ApplicationImpersonationContext()) {
                            callback(_key, _value, reason);
                        }
                    }
                    else
                    {
                        callback(_key, _value, reason);
                    }
                }
                catch (Exception e) {
                    // for public need to report application error
                    HttpApplicationFactory.RaiseError(e);

                    try {
                        WebBaseEvent.RaiseRuntimeError(e, this);
                    }
                    catch {
                    }
                }
            }
            else
            {
                // for private items just make the call and eat any exceptions
                try {
                    using (new ApplicationImpersonationContext()) {
                        callback(_key, _value, reason);
                    }
                }
                catch {
                }
            }
        }
Exemple #13
0
        /*
         * Helper to call the on-remove callback
         */

        private void CallCacheItemRemovedCallback(CacheItemRemovedCallback callback, CacheItemRemovedReason reason)
        {
            if (IsPublic)
            {
                try {
                    // for public need to impersonate if called outside of request context
                    HttpContext.ImpersonationData impersonation = null;
                    if (HttpContext.Current == null)
                    {
                        impersonation = HttpContext.GetAppLevelImpersonation();
                        impersonation.Start(true /*forGlobalCode*/, false /*throwOnError*/);
                    }

                    try {
                        callback(_key, _value, reason);
                    }
                    finally {
                        if (impersonation != null)
                        {
                            impersonation.Stop();
                        }
                    }
                }
                catch (Exception e) {
                    // for public need to report application error
                    HttpApplicationFactory.RaiseError(e);
                }
            }
            else
            {
                // for private items just make the call and eat any exceptions
                try {
                    callback(_key, _value, reason);
                }
                catch {
                }
            }
        }
 public void Setup()
 {
     Client = HttpApplicationFactory.CreateClient();
 }
Exemple #15
0
        /*
         * Perform initialization work that should only be done once (per app domain).
         */
        private static void DoFirstTimeInit(HttpContext context)
        {
            // Find out how many recompilations we allow before restarting the appdomain
            s_maxRecompilations = CompilationConfiguration.GetRecompilationsBeforeAppRestarts(context);

            // Create the temp files directory if it's not already there
            string tempFilePath = HttpRuntime.CodegenDirInternal;

            if (!FileUtil.DirectoryExists(tempFilePath))
            {
                try {
                    Directory.CreateDirectory(tempFilePath);
                }
                catch (IOException e) {
                    throw new HttpException(HttpRuntime.FormatResourceString(SR.Failed_to_create_temp_dir, HttpRuntime.GetSafePath(tempFilePath)), e);
                }
            }

            long specialFilesCombinedHash = ReadPreservedSpecialFilesCombinedHash();

            Debug.Trace("PreservedAssemblyEntry", "specialFilesCombinedHash=" + specialFilesCombinedHash);

            // Delete all the non essential files left over in the codegen dir, unless
            // specialFilesCombinedHash is 0, in which case we delete *everything* further down
            if (specialFilesCombinedHash != 0)
            {
                RemoveOldTempFiles();
            }

            // Use a DateTimeCombiner object to handle the time stamps of all the 'special'
            // files that all compilations depend on:
            // - The config files (excluding the ones from subdirectories)
            // - global.asax
            // - System.Web.dll (in case there is a newer version of ASP.NET)

            DateTimeCombiner specialFilesDateTimeCombiner = new DateTimeCombiner();

            // Add a check for the app's physical path, in case it changes (ASURT 12975)
            specialFilesDateTimeCombiner.AddObject(context.Request.PhysicalApplicationPath);

            // Process the config files. Note that this only includes the top level ones,
            // namely the machine one, and the one in the root of the app.  The others are
            // handled as regular dependencies.
            string appPath = context.Request.ApplicationPath;

            string[] configFiles = context.GetConfigurationDependencies(appPath);
            _numTopLevelConfigFiles = configFiles.Length;
            for (int i = 0; i < _numTopLevelConfigFiles; i++)
            {
                specialFilesDateTimeCombiner.AddFile(configFiles[i]);
            }

            // Process global.asax
            string appFileName = HttpApplicationFactory.GetApplicationFile(context);

            specialFilesDateTimeCombiner.AddFile(appFileName);

            // Process System.Web.dll
            string aspBinaryFileName = typeof(HttpRuntime).Module.FullyQualifiedName;

            specialFilesDateTimeCombiner.AddFile(aspBinaryFileName);

            // If they don't match, cleanup everything and write the new hash file
            if (specialFilesDateTimeCombiner.CombinedHash != specialFilesCombinedHash)
            {
                Debug.Trace("PreservedAssemblyEntry", "EnsureFirstTimeInit: hash codes don't match.  Old=" +
                            specialFilesCombinedHash + " New=" + specialFilesDateTimeCombiner.CombinedHash);
                RemoveAllCodeGenFiles();
                WritePreservedSpecialFilesCombinedHash(specialFilesDateTimeCombiner.CombinedHash);
            }
            else
            {
                Debug.Trace("PreservedAssemblyEntry", "PreservedAssemblyEntry: the special files are up to date");
            }
        }
Exemple #16
0
        internal static string CreateOutputCachedItemKey(
            string path,
            CacheRequestMethod method,
            HttpContext context,
            CachedVary cachedVary)
        {
            StringBuilder sb;
            int           i, j, n;
            string        name, value;

            string[]            a;
            byte[]              buf, hash;
            HttpRequest         request;
            NameValueCollection col;
            int contentLength;

            if (method == CacheRequestMethod.Post)
            {
                sb = new StringBuilder("System.Web.Http.HttpRawResponse\nM=3\n");
            }
            else
            {
                sb = new StringBuilder("System.Web.Http.HttpRawResponse\nM=2\n");
            }

            sb.Append(CultureInfo.InvariantCulture.TextInfo.ToLower(path));

            /* key for cached vary item has additional information */
            if (cachedVary != null)
            {
                request = context.Request;

                /* params part */
                for (j = 0; j <= 2; j++)
                {
                    switch (j)
                    {
                    case 0:
                        sb.Append("\nVH");
                        a   = cachedVary._headers;
                        col = request.ServerVariables;
                        break;

                    case 1:
                        sb.Append("\nVPQ");
                        a   = cachedVary._params;
                        col = request.QueryString;
                        break;

                    case 2:
                    default:
                        sb.Append("\nVPF");
                        a   = cachedVary._params;
                        col = request.Form;
                        if (method != CacheRequestMethod.Post)
                        {
                            col = null;
                        }

                        break;
                    }

                    if (col == null)
                    {
                        continue;
                    }

                    /* handle all params case (VaryByParams[*] = true) */
                    if (a == null && cachedVary._varyByAllParams && j != 0)
                    {
                        a = col.AllKeys;
                        for (i = a.Length - 1; i >= 0; i--)
                        {
                            if (a[i] != null)
                            {
                                a[i] = CultureInfo.InvariantCulture.TextInfo.ToLower(a[i]);
                            }
                        }

                        Array.Sort(a, InvariantComparer.Default);
                    }

                    if (a != null)
                    {
                        for (i = 0, n = a.Length; i < n; i++)
                        {
                            name  = a[i];
                            value = col[name];
                            if (value == null)
                            {
                                value = NULL_VARYBY_VALUE;
                            }

                            sb.Append("\tPN:");
                            sb.Append(name);
                            sb.Append("\tPV:");
                            sb.Append(value);
                        }
                    }
                }

                /* custom string part */
                sb.Append("\nVC");
                if (cachedVary._varyByCustom != null)
                {
                    sb.Append("\tCN:");
                    sb.Append(cachedVary._varyByCustom);
                    sb.Append("\tCV:");

                    try {
                        value = context.ApplicationInstance.GetVaryByCustomString(
                            context, cachedVary._varyByCustom);
                        if (value == null)
                        {
                            value = NULL_VARYBY_VALUE;
                        }
                    }
                    catch (Exception e) {
                        value = ERROR_VARYBY_VALUE;
                        HttpApplicationFactory.RaiseError(e);
                    }

                    sb.Append(value);
                }

                /*
                 * if VaryByParms=*, and method is not a form, then
                 * use a cryptographically strong hash of the data as
                 * part of the key.
                 */
                sb.Append("\nVPD");
                if (method == CacheRequestMethod.Post &&
                    cachedVary._varyByAllParams &&
                    request.Form.Count == 0)
                {
                    contentLength = request.ContentLength;
                    if (contentLength > MAX_POST_KEY_LENGTH || contentLength < 0)
                    {
                        return(null);
                    }

                    if (contentLength > 0)
                    {
                        buf = ((HttpInputStream)request.InputStream).Data;
                        if (buf == null)
                        {
                            return(null);
                        }

                        hash  = MachineKey.HashData(buf, s_hashModifier, 0, buf.Length);
                        value = Convert.ToBase64String(hash);
                        sb.Append(value);
                    }
                }

                sb.Append("\nEOV");
            }

            return(sb.ToString());
        }
Exemple #17
0
        /*
         * Try to find this request in the cache. If so, return it. Otherwise,
         * store the cache key for use on Leave.
         */
        /// <include file='doc\OutputCacheModule.uex' path='docs/doc[@for="OutputCacheModule.OnEnter"]/*' />
        /// <devdoc>
        /// <para>Raises the <see langword='Enter'/>
        /// event, which searches the output cache for an item to satisfy the HTTP request. </para>
        /// </devdoc>
        internal /*public*/ void OnEnter(Object source, EventArgs eventArgs)
        {
            HttpApplication         app;
            HttpContext             context;
            string                  key;
            HttpRequest             request;
            HttpResponse            response;
            Object                  item;
            CachedRawResponse       cachedRawResponse;
            HttpCachePolicySettings settings;
            int  i, n;
            bool sendBody;
            HttpValidationStatus   validationStatus, validationStatusFinal;
            ValidationCallbackInfo callbackInfo;
            string   ifModifiedSinceHeader;
            DateTime utcIfModifiedSince;
            string   etag;

            string[] etags;
            int      send304;
            string   cacheControl;

            string[] cacheDirectives = null;
            string   pragma;

            string[]      pragmaDirectives = null;
            string        directive;
            int           maxage;
            int           minfresh;
            int           age;
            int           fresh;
            bool          hasValidationPolicy;
            CachedVary    cachedVary;
            CacheInternal cacheInternal;

            Debug.Trace("OutputCacheModuleEnter", "Beginning OutputCacheModule::Enter");

            app                = (HttpApplication)source;
            context            = app.Context;
            request            = context.Request;
            response           = context.Response;
            _key               = null;
            _recordedCacheMiss = false;
            _method            = CacheRequestMethod.Invalid;

            /*
             * Check if the request can be resolved for this method.
             */
            switch (request.HttpMethod)
            {
            case "HEAD":
                _method = CacheRequestMethod.Head;
                break;

            case "GET":
                _method = CacheRequestMethod.Get;
                break;

            case "POST":
                _method = CacheRequestMethod.Post;
                break;

            default:
                Debug.Trace("OutputCacheModuleEnter", "Output cache miss, Http method not GET, POST, or HEAD" +
                            "\nReturning from OutputCacheModule::Enter");

                return;
            }

            /*
             * Create a lookup key. Remember the key for use inside Leave()
             */
            _key = key = CreateOutputCachedItemKey(context, null);
            Debug.Assert(_key != null, "_key != null");

            /*
             *  Lookup the cached item.
             */
            cacheInternal = HttpRuntime.CacheInternal;
            item          = cacheInternal.Get(key);
            if (item == null)
            {
                Debug.Trace("OutputCacheModuleEnter", "Output cache miss, item not found.\n\tkey=" + key +
                            "\nReturning from OutputCacheModule::Enter");

                return;
            }

            cachedVary = item as CachedVary;
            if (cachedVary != null)
            {
                /*
                 * This cached output has a Vary policy. Create a new key based
                 * on the vary headers in cachedRawResponse and try again.
                 */
                Debug.Trace("OutputCacheModuleEnter", "Output cache found CachedVary, \n\tkey=" + key);
                key = CreateOutputCachedItemKey(context, cachedVary);
                if (key == null)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache miss, key could not be created for vary-by item." +
                                "\nReturning from OutputCacheModule::Enter");

                    return;
                }

                item = cacheInternal.Get(key);
                if (item == null)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache miss, item not found.\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");

                    return;
                }
            }

            Debug.Assert(item.GetType() == typeof(CachedRawResponse), "item.GetType() == typeof(CachedRawResponse)");
            cachedRawResponse = (CachedRawResponse)item;
            settings          = cachedRawResponse._settings;
            if (cachedVary == null && !settings.IgnoreParams)
            {
                /*
                 * This cached output has no vary policy, so make sure it doesn't have a query string or form post.
                 */
                if (_method == CacheRequestMethod.Post)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache item found but method is POST and no VaryByParam specified." +
                                "\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");
                    RecordCacheMiss();
                    return;
                }

                string queryStringText = request.QueryStringText;
                if (queryStringText != null && queryStringText.Length > 0)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache item found but contains a querystring and no VaryByParam specified." +
                                "\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");
                    RecordCacheMiss();
                    return;
                }
            }

            hasValidationPolicy = settings.HasValidationPolicy();

            /*
             * Determine whether the client can accept a cached copy, and
             * get values of other cache control directives.
             *
             * We do this after lookup so we don't have to crack the headers
             * if the item is not found. Cracking the headers is expensive.
             */
            if (!hasValidationPolicy)
            {
                cacheControl = request.Headers["Cache-Control"];
                if (cacheControl != null)
                {
                    cacheDirectives = cacheControl.Split(s_fieldSeparators);
                    for (i = 0; i < cacheDirectives.Length; i++)
                    {
                        directive = cacheDirectives[i];
                        if (directive == "no-cache")
                        {
                            Debug.Trace("OutputCacheModuleEnter",
                                        "Skipping lookup because of Cache-Control: no-cache directive." +
                                        "\nReturning from OutputCacheModule::Enter");

                            RecordCacheMiss();
                            return;
                        }

                        if (directive.StartsWith("max-age="))
                        {
                            try {
                                maxage = Convert.ToInt32(directive.Substring(8));
                            }
                            catch {
                                maxage = -1;
                            }

                            if (maxage >= 0)
                            {
                                age = (int)((context.UtcTimestamp.Ticks - settings.UtcTimestampCreated.Ticks) / TimeSpan.TicksPerSecond);
                                if (age >= maxage)
                                {
                                    Debug.Trace("OutputCacheModuleEnter",
                                                "Not returning found item due to Cache-Control: max-age directive." +
                                                "\nReturning from OutputCacheModule::Enter");

                                    RecordCacheMiss();
                                    return;
                                }
                            }
                        }
                        else if (directive.StartsWith("min-fresh="))
                        {
                            try {
                                minfresh = Convert.ToInt32(directive.Substring(10));
                            }
                            catch {
                                minfresh = -1;
                            }

                            if (minfresh >= 0 && settings.IsExpiresSet && !settings.SlidingExpiration)
                            {
                                fresh = (int)((settings.UtcExpires.Ticks - context.UtcTimestamp.Ticks) / TimeSpan.TicksPerSecond);
                                if (fresh < minfresh)
                                {
                                    Debug.Trace("OutputCacheModuleEnter",
                                                "Not returning found item due to Cache-Control: min-fresh directive." +
                                                "\nReturning from OutputCacheModule::Enter");

                                    RecordCacheMiss();
                                    return;
                                }
                            }
                        }
                    }
                }

                pragma = request.Headers["Pragma"];
                if (pragma != null)
                {
                    pragmaDirectives = pragma.Split(s_fieldSeparators);
                    for (i = 0; i < pragmaDirectives.Length; i++)
                    {
                        if (pragmaDirectives[i] == "no-cache")
                        {
                            Debug.Trace("OutputCacheModuleEnter",
                                        "Skipping lookup because of Pragma: no-cache directive." +
                                        "\nReturning from OutputCacheModule::Enter");

                            RecordCacheMiss();
                            return;
                        }
                    }
                }
            }
            else if (settings.ValidationCallbackInfo != null)
            {
                /*
                 * Check if the item is still valid.
                 */
                validationStatus      = HttpValidationStatus.Valid;
                validationStatusFinal = validationStatus;
                for (i = 0, n = settings.ValidationCallbackInfo.Length; i < n; i++)
                {
                    callbackInfo = settings.ValidationCallbackInfo[i];
                    try {
                        callbackInfo.handler(context, callbackInfo.data, ref validationStatus);
                    }
                    catch (Exception e) {
                        validationStatus = HttpValidationStatus.Invalid;
                        HttpApplicationFactory.RaiseError(e);
                    }

                    switch (validationStatus)
                    {
                    case HttpValidationStatus.Invalid:
                        Debug.Trace("OutputCacheModuleEnter", "Output cache item found but callback invalidated it." +
                                    "\n\tkey=" + key +
                                    "\nReturning from OutputCacheModule::Enter");

                        cacheInternal.Remove(key);
                        RecordCacheMiss();
                        return;

                    case HttpValidationStatus.IgnoreThisRequest:
                        validationStatusFinal = HttpValidationStatus.IgnoreThisRequest;
                        break;

                    case HttpValidationStatus.Valid:
                        break;

                    default:
                        Debug.Trace("OutputCacheModuleEnter", "Invalid validation status, ignoring it, status=" + validationStatus +
                                    "\n\tkey=" + key);

                        validationStatus = validationStatusFinal;
                        break;
                    }
                }

                if (validationStatusFinal == HttpValidationStatus.IgnoreThisRequest)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache item found but callback status is IgnoreThisRequest." +
                                "\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");


                    RecordCacheMiss();
                    return;
                }

                Debug.Assert(validationStatusFinal == HttpValidationStatus.Valid,
                             "validationStatusFinal == HttpValidationStatus.Valid");
            }

            /*
             * Try to satisfy a conditional request. The cached response
             * must satisfy all conditions that are present.
             *
             * We can only satisfy a conditional request if the response
             * is buffered and has no substitution blocks.
             *
             * N.B. RFC 2616 says conditional requests only occur
             * with the GET method, but we try to satisfy other
             * verbs (HEAD, POST) as well.
             */
            send304 = -1;

            if (response.IsBuffered() && !cachedRawResponse._rawResponse.HasSubstBlocks)
            {
                /* Check "If-Modified-Since" header */
                ifModifiedSinceHeader = request.IfModifiedSince;
                if (ifModifiedSinceHeader != null)
                {
                    send304 = 0;
                    try {
                        utcIfModifiedSince = HttpDate.UtcParse(ifModifiedSinceHeader);
                        if (settings.IsLastModifiedSet &&
                            settings.UtcLastModified <= utcIfModifiedSince &&
                            utcIfModifiedSince <= context.UtcTimestamp)
                        {
                            send304 = 1;
                        }
                    }
                    catch {
                        Debug.Trace("OutputCacheModuleEnter", "Ignore If-Modified-Since header, invalid format: " + ifModifiedSinceHeader);
                    }
                }

                /* Check "If-None-Match" header */
                if (send304 != 0)
                {
                    etag = request.IfNoneMatch;
                    if (etag != null)
                    {
                        send304 = 0;
                        etags   = etag.Split(s_fieldSeparators);
                        for (i = 0, n = etags.Length; i < n; i++)
                        {
                            if (i == 0 && etags[i].Equals("*"))
                            {
                                send304 = 1;
                                break;
                            }

                            if (etags[i].Equals(settings.ETag))
                            {
                                send304 = 1;
                                break;
                            }
                        }
                    }
                }
            }

            if (send304 == 1)
            {
                /*
                 * Send 304 Not Modified
                 */
                Debug.Trace("OutputCacheModuleEnter", "Output cache hit & conditional request satisfied, status=304." +
                            "\n\tkey=" + key +
                            "\nReturning from OutputCacheModule::Enter");

                response.ClearAll();
                response.StatusCode = 304;
            }
            else
            {
                /*
                 * Send the full response.
                 */
#if DBG
                if (send304 == -1)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache hit.\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");
                }
                else
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache hit but conditional request not satisfied.\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");
                }
#endif

                sendBody = (_method != CacheRequestMethod.Head);

                // UseSnapshot calls ClearAll
                response.UseSnapshot(cachedRawResponse._rawResponse, sendBody);
            }

            response.Cache.ResetFromHttpCachePolicySettings(settings, context.UtcTimestamp);

            PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_RATIO_BASE);
            PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_HITS);

            _key = null;
            _recordedCacheMiss = false;
            _method            = CacheRequestMethod.Invalid;

            app.CompleteRequest();
        }
        public static void RaiseSessionEnd(IHttpSessionState session, Object eventSource, EventArgs eventArgs)
        {
            HttpSessionState state = new HttpSessionState(session);

            HttpApplicationFactory.InvokeSessionEnd(state, eventSource, eventArgs);
        }
Exemple #19
0
        /// <summary>
        /// Initiates the incoming connection socket for the network server
        /// and initialises an instance of the HttpApplication.
        /// </summary>
        /// <returns></returns>
        public async void Start <T>(HttpApplicationFactory <T> factory) where T : IHttpAsyncHandler, new()
        {
            _getInstance = factory.GetApplicationInstance;

            try
            {
                // Find an IPv4 address on the host computer and attempt to establish
                // an incoming network socket over it on the specified port number.
                var entries = await Dns.GetHostEntryAsync(_host);

                if (0 == entries.AddressList.Length)
                {
                    throw new Exception($"Could not bind to address on host {_host}");
                }

                IPAddress address = null;
                foreach (var a in entries.AddressList)
                {
                    if (AddressFamily.InterNetwork == a.AddressFamily)
                    {
                        address = a;
                        break;
                    }
                }

                var localEndPoint = new IPEndPoint(address, _port);

                var listener = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                listener.Bind(localEndPoint);
                listener.Listen(10);

                var incomingBuffer = new ArraySegment <byte>(new byte[1024]);
                var message        = new StringBuilder();

                _handlerCompletionCallback = new AsyncCallback(OnHandlerCompletion);

                // Go into an infinite loop and wait for incoming
                // connections. When a connection is made, the application
                // receives the message sent by the client and pumps it
                // into the processing pipeline.
                while (true)
                {
                    _client = await listener.AcceptAsync();

                    var length = await _client.ReceiveAsync(incomingBuffer, SocketFlags.None);

                    message.Append(Encoding.ASCII.GetString(incomingBuffer.Array, 0, length));
                    Log.Verbose(message.ToString());
                    Log.Information("Received {length} bytes from client", length);

                    // Deserialize the incoming message buffer into a TcpServerWorkerRequest instance
                    var wr = TcpServerWorkerRequest.CreateWorkerRequest(incomingBuffer.Array);
                    ProcessRequest(wr);
                }
            }
            catch (SocketException exception)
            {
                Log.Fatal($"Could not start a server at {_host}:{_port}.\r\nError: {exception.Message}");
            }
            catch (SecurityException exception)
            {
                Log.Fatal($"A security violation occurred while starting a server at {_host}:{_port}.\r\nError: {exception.Message}");
            }
        }
        internal void OnEnter(object source, EventArgs eventArgs)
        {
            this._key = null;
            this._recordedCacheMiss = false;
            if (OutputCache.InUse)
            {
                string[]        strArray2   = null;
                string[]        strArray3   = null;
                HttpApplication application = (HttpApplication)source;
                HttpContext     context     = application.Context;
                context.GetFilePathData();
                HttpRequest  request  = context.Request;
                HttpResponse response = context.Response;
                switch (request.HttpVerb)
                {
                case HttpVerb.GET:
                case HttpVerb.HEAD:
                case HttpVerb.POST:
                {
                    string str;
                    this._key = str = this.CreateOutputCachedItemKey(context, null);
                    object obj2 = OutputCache.Get(str);
                    if (obj2 != null)
                    {
                        int        num;
                        int        length;
                        CachedVary cachedVary = obj2 as CachedVary;
                        if (cachedVary != null)
                        {
                            str = this.CreateOutputCachedItemKey(context, cachedVary);
                            if (str == null)
                            {
                                return;
                            }
                            if (cachedVary._contentEncodings == null)
                            {
                                obj2 = OutputCache.Get(str);
                            }
                            else
                            {
                                obj2 = null;
                                bool   flag3 = true;
                                string knownRequestHeader = context.WorkerRequest.GetKnownRequestHeader(0x16);
                                if (knownRequestHeader != null)
                                {
                                    string[] contentEncodings = cachedVary._contentEncodings;
                                    int      startIndex       = 0;
                                    bool     flag4            = false;
                                    while (!flag4)
                                    {
                                        flag4 = true;
                                        int index = GetAcceptableEncoding(contentEncodings, startIndex, knownRequestHeader);
                                        if (index > -1)
                                        {
                                            flag3 = false;
                                            obj2  = OutputCache.Get(str + contentEncodings[index]);
                                            if (obj2 == null)
                                            {
                                                startIndex = index + 1;
                                                if (startIndex < contentEncodings.Length)
                                                {
                                                    flag4 = false;
                                                }
                                            }
                                        }
                                        else if (index == -2)
                                        {
                                            flag3 = false;
                                        }
                                    }
                                }
                                if ((obj2 == null) && flag3)
                                {
                                    obj2 = OutputCache.Get(str);
                                }
                            }
                            if ((obj2 == null) || (((CachedRawResponse)obj2)._cachedVaryId != cachedVary.CachedVaryId))
                            {
                                if (obj2 != null)
                                {
                                    OutputCache.Remove(str, context);
                                }
                                return;
                            }
                        }
                        CachedRawResponse       response2 = (CachedRawResponse)obj2;
                        HttpCachePolicySettings settings  = response2._settings;
                        if ((cachedVary == null) && !settings.IgnoreParams)
                        {
                            if (request.HttpVerb == HttpVerb.POST)
                            {
                                this.RecordCacheMiss();
                                return;
                            }
                            if (request.HasQueryString)
                            {
                                this.RecordCacheMiss();
                                return;
                            }
                        }
                        if (settings.IgnoreRangeRequests)
                        {
                            string str8 = request.Headers["Range"];
                            if (StringUtil.StringStartsWithIgnoreCase(str8, "bytes"))
                            {
                                return;
                            }
                        }
                        if (!settings.HasValidationPolicy())
                        {
                            string str4 = request.Headers["Cache-Control"];
                            if (str4 != null)
                            {
                                strArray2 = str4.Split(s_fieldSeparators);
                                for (num = 0; num < strArray2.Length; num++)
                                {
                                    string str6 = strArray2[num];
                                    switch (str6)
                                    {
                                    case "no-cache":
                                    case "no-store":
                                        this.RecordCacheMiss();
                                        return;
                                    }
                                    if (StringUtil.StringStartsWith(str6, "max-age="))
                                    {
                                        int num4;
                                        try
                                        {
                                            num4 = Convert.ToInt32(str6.Substring(8), CultureInfo.InvariantCulture);
                                        }
                                        catch
                                        {
                                            num4 = -1;
                                        }
                                        if (num4 >= 0)
                                        {
                                            int num6 = (int)((context.UtcTimestamp.Ticks - settings.UtcTimestampCreated.Ticks) / 0x989680L);
                                            if (num6 >= num4)
                                            {
                                                this.RecordCacheMiss();
                                                return;
                                            }
                                        }
                                    }
                                    else if (StringUtil.StringStartsWith(str6, "min-fresh="))
                                    {
                                        int num5;
                                        try
                                        {
                                            num5 = Convert.ToInt32(str6.Substring(10), CultureInfo.InvariantCulture);
                                        }
                                        catch
                                        {
                                            num5 = -1;
                                        }
                                        if (((num5 >= 0) && settings.IsExpiresSet) && !settings.SlidingExpiration)
                                        {
                                            int num7 = (int)((settings.UtcExpires.Ticks - context.UtcTimestamp.Ticks) / 0x989680L);
                                            if (num7 < num5)
                                            {
                                                this.RecordCacheMiss();
                                                return;
                                            }
                                        }
                                    }
                                }
                            }
                            string str5 = request.Headers["Pragma"];
                            if (str5 != null)
                            {
                                strArray3 = str5.Split(s_fieldSeparators);
                                for (num = 0; num < strArray3.Length; num++)
                                {
                                    if (strArray3[num] == "no-cache")
                                    {
                                        this.RecordCacheMiss();
                                        return;
                                    }
                                }
                            }
                        }
                        else if (settings.ValidationCallbackInfo != null)
                        {
                            HttpValidationStatus valid             = HttpValidationStatus.Valid;
                            HttpValidationStatus ignoreThisRequest = valid;
                            num    = 0;
                            length = settings.ValidationCallbackInfo.Length;
                            while (num < length)
                            {
                                ValidationCallbackInfo info = settings.ValidationCallbackInfo[num];
                                try
                                {
                                    info.handler(context, info.data, ref valid);
                                }
                                catch (Exception exception)
                                {
                                    valid = HttpValidationStatus.Invalid;
                                    HttpApplicationFactory.RaiseError(exception);
                                }
                                switch (valid)
                                {
                                case HttpValidationStatus.Invalid:
                                    OutputCache.Remove(str, context);
                                    this.RecordCacheMiss();
                                    return;

                                case HttpValidationStatus.IgnoreThisRequest:
                                    ignoreThisRequest = HttpValidationStatus.IgnoreThisRequest;
                                    break;

                                case HttpValidationStatus.Valid:
                                    break;

                                default:
                                    valid = ignoreThisRequest;
                                    break;
                                }
                                num++;
                            }
                            if (ignoreThisRequest == HttpValidationStatus.IgnoreThisRequest)
                            {
                                this.RecordCacheMiss();
                                return;
                            }
                        }
                        HttpRawResponse rawResponse = response2._rawResponse;
                        if ((cachedVary == null) || (cachedVary._contentEncodings == null))
                        {
                            string    acceptEncoding  = request.Headers["Accept-Encoding"];
                            string    contentEncoding = null;
                            ArrayList headers         = rawResponse.Headers;
                            if (headers != null)
                            {
                                foreach (HttpResponseHeader header in headers)
                                {
                                    if (header.Name == "Content-Encoding")
                                    {
                                        contentEncoding = header.Value;
                                        break;
                                    }
                                }
                            }
                            if (!IsAcceptableEncoding(contentEncoding, acceptEncoding))
                            {
                                this.RecordCacheMiss();
                                return;
                            }
                        }
                        int num3 = -1;
                        if (!rawResponse.HasSubstBlocks)
                        {
                            string ifModifiedSince = request.IfModifiedSince;
                            if (ifModifiedSince != null)
                            {
                                num3 = 0;
                                try
                                {
                                    DateTime time = HttpDate.UtcParse(ifModifiedSince);
                                    if ((settings.IsLastModifiedSet && (settings.UtcLastModified <= time)) && (time <= context.UtcTimestamp))
                                    {
                                        num3 = 1;
                                    }
                                }
                                catch
                                {
                                }
                            }
                            if (num3 != 0)
                            {
                                string ifNoneMatch = request.IfNoneMatch;
                                if (ifNoneMatch != null)
                                {
                                    num3 = 0;
                                    string[] strArray = ifNoneMatch.Split(s_fieldSeparators);
                                    num    = 0;
                                    length = strArray.Length;
                                    while (num < length)
                                    {
                                        if ((num == 0) && strArray[num].Equals("*"))
                                        {
                                            num3 = 1;
                                            break;
                                        }
                                        if (strArray[num].Equals(settings.ETag))
                                        {
                                            num3 = 1;
                                            break;
                                        }
                                        num++;
                                    }
                                }
                            }
                        }
                        if (num3 == 1)
                        {
                            response.ClearAll();
                            response.StatusCode = 0x130;
                        }
                        else
                        {
                            bool sendBody = request.HttpVerb != HttpVerb.HEAD;
                            response.UseSnapshot(rawResponse, sendBody);
                        }
                        response.Cache.ResetFromHttpCachePolicySettings(settings, context.UtcTimestamp);
                        string originalCacheUrl = response2._kernelCacheUrl;
                        if (originalCacheUrl != null)
                        {
                            response.SetupKernelCaching(originalCacheUrl);
                        }
                        PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_RATIO_BASE);
                        PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_HITS);
                        this._key = null;
                        this._recordedCacheMiss = false;
                        application.CompleteRequest();
                        return;
                    }
                    return;
                }
                }
            }
        }
Exemple #21
0
 // Called by custom session state module if they want to raise Session_End.
 static public void RaiseSessionEnd(IHttpSessionState session, Object eventSource, EventArgs eventArgs)
 {
     HttpApplicationFactory.EndSession(new HttpSessionState(session), eventSource, eventArgs);
 }
        internal static string CreateOutputCachedItemKey(string path, HttpVerb verb, HttpContext context, CachedVary cachedVary)
        {
            StringBuilder builder;

            if (verb == HttpVerb.POST)
            {
                builder = new StringBuilder("a1", path.Length + "a1".Length);
            }
            else
            {
                builder = new StringBuilder("a2", path.Length + "a2".Length);
            }
            builder.Append(CultureInfo.InvariantCulture.TextInfo.ToLower(path));
            if (cachedVary != null)
            {
                string      varyByCustomString;
                HttpRequest request = context.Request;
                for (int i = 0; i <= 2; i++)
                {
                    int                 num;
                    string[]            array = null;
                    NameValueCollection serverVarsWithoutDemand = null;
                    bool                flag = false;
                    switch (i)
                    {
                    case 0:
                        builder.Append("H");
                        array = cachedVary._headers;
                        if (array != null)
                        {
                            serverVarsWithoutDemand = request.GetServerVarsWithoutDemand();
                        }
                        break;

                    case 1:
                        builder.Append("Q");
                        array = cachedVary._params;
                        if (request.HasQueryString && ((array != null) || cachedVary._varyByAllParams))
                        {
                            serverVarsWithoutDemand = request.QueryString;
                            flag = cachedVary._varyByAllParams;
                        }
                        break;

                    default:
                        builder.Append("F");
                        if (verb == HttpVerb.POST)
                        {
                            array = cachedVary._params;
                            if (request.HasForm && ((array != null) || cachedVary._varyByAllParams))
                            {
                                serverVarsWithoutDemand = request.Form;
                                flag = cachedVary._varyByAllParams;
                            }
                        }
                        break;
                    }
                    if (flag && (serverVarsWithoutDemand.Count > 0))
                    {
                        array = serverVarsWithoutDemand.AllKeys;
                        num   = array.Length - 1;
                        while (num >= 0)
                        {
                            if (array[num] != null)
                            {
                                array[num] = CultureInfo.InvariantCulture.TextInfo.ToLower(array[num]);
                            }
                            num--;
                        }
                        Array.Sort(array, System.InvariantComparer.Default);
                    }
                    if (array != null)
                    {
                        num = 0;
                        int length = array.Length;
                        while (num < length)
                        {
                            string str = array[num];
                            if (serverVarsWithoutDemand == null)
                            {
                                varyByCustomString = "+n+";
                            }
                            else
                            {
                                varyByCustomString = serverVarsWithoutDemand[str];
                                if (varyByCustomString == null)
                                {
                                    varyByCustomString = "+n+";
                                }
                            }
                            builder.Append("N");
                            builder.Append(str);
                            builder.Append("V");
                            builder.Append(varyByCustomString);
                            num++;
                        }
                    }
                }
                builder.Append("C");
                if (cachedVary._varyByCustom != null)
                {
                    builder.Append("N");
                    builder.Append(cachedVary._varyByCustom);
                    builder.Append("V");
                    try
                    {
                        varyByCustomString = context.ApplicationInstance.GetVaryByCustomString(context, cachedVary._varyByCustom);
                        if (varyByCustomString == null)
                        {
                            varyByCustomString = "+n+";
                        }
                    }
                    catch (Exception exception)
                    {
                        varyByCustomString = "+e+";
                        HttpApplicationFactory.RaiseError(exception);
                    }
                    builder.Append(varyByCustomString);
                }
                builder.Append("D");
                if (((verb == HttpVerb.POST) && cachedVary._varyByAllParams) && (request.Form.Count == 0))
                {
                    int contentLength = request.ContentLength;
                    if ((contentLength > 0x3a98) || (contentLength < 0))
                    {
                        return(null);
                    }
                    if (contentLength > 0)
                    {
                        byte[] asByteArray = ((HttpInputStream)request.InputStream).GetAsByteArray();
                        if (asByteArray == null)
                        {
                            return(null);
                        }
                        varyByCustomString = Convert.ToBase64String(MachineKeySection.HashData(asByteArray, null, 0, asByteArray.Length));
                        builder.Append(varyByCustomString);
                    }
                }
                builder.Append("E");
                string[] strArray2 = cachedVary._contentEncodings;
                if (strArray2 != null)
                {
                    string httpHeaderContentEncoding = context.Response.GetHttpHeaderContentEncoding();
                    if (httpHeaderContentEncoding != null)
                    {
                        for (int j = 0; j < strArray2.Length; j++)
                        {
                            if (strArray2[j] == httpHeaderContentEncoding)
                            {
                                builder.Append(httpHeaderContentEncoding);
                                break;
                            }
                        }
                    }
                }
            }
            return(builder.ToString());
        }
        public void InitializeApplication(IntPtr appContext)
        {
            s_ApplicationContext = appContext;

            // DevDiv #381425 - webengine4!RegisterModule runs *after* HostingEnvironment.Initialize (and thus the
            // HttpRuntime static ctor) when application preload is active. This means that any global state set
            // by RegisterModule (like the IIS version information, whether we're in integrated mode, misc server
            // info, etc.) will be unavailable to PreAppStart / preload code when the preload feature is active.
            // But since RegisterModule runs before InitializeApplication, we have one last chance here to collect
            // the information before the main part of the application starts, and the pipeline can depend on it
            // to be accurate.
            HttpRuntime.PopulateIISVersionInformation();

            HttpApplication app = null;

            try {
                // if HttpRuntime.HostingInit failed, do not attempt to create the application (WOS #1653963)
                if (!HttpRuntime.HostingInitFailed)
                {
                    //
                    //  On IIS7, application initialization does not provide an http context.  Theoretically,
                    //  no one should be using the context during application initialization, but people do.
                    //  Create a dummy context that is used during application initialization
                    //  to prevent breakage (ISAPI mode always provides a context)
                    //
                    HttpWorkerRequest initWorkerRequest = new SimpleWorkerRequest("" /*page*/,
                                                                                  "" /*query*/,
                                                                                  new StringWriter(CultureInfo.InvariantCulture));
                    MimeMapping.SetIntegratedApplicationContext(appContext);
                    HttpContext initHttpContext = new HttpContext(initWorkerRequest);
                    app = HttpApplicationFactory.GetPipelineApplicationInstance(appContext, initHttpContext);
                }
            }
            catch (Exception e)
            {
                if (HttpRuntime.InitializationException == null)
                {
                    HttpRuntime.InitializationException = e;
                }
            }
            finally {
                s_InitializationCompleted = true;

                if (HttpRuntime.InitializationException != null)
                {
                    // at least one module must be registered so that we
                    // call ProcessRequestNotification later and send the formatted
                    // InitializationException to the client.
                    int hresult = UnsafeIISMethods.MgdRegisterEventSubscription(
                        appContext,
                        InitExceptionModuleName,
                        RequestNotification.BeginRequest,
                        0 /*postRequestNotifications*/,
                        InitExceptionModuleName,
                        s_InitExceptionModulePrecondition,
                        new IntPtr(-1),
                        false /*useHighPriority*/);

                    if (hresult < 0)
                    {
                        throw new COMException(SR.GetString(SR.Failed_Pipeline_Subscription, InitExceptionModuleName),
                                               hresult);
                    }

                    // Always register a managed handler:
                    // WOS 1990290: VS F5 Debugging: "AspNetInitializationExceptionModule" is registered for RQ_BEGIN_REQUEST,
                    // but the DEBUG verb skips notifications until post RQ_AUTHENTICATE_REQUEST.
                    hresult = UnsafeIISMethods.MgdRegisterEventSubscription(
                        appContext,
                        HttpApplication.IMPLICIT_HANDLER,
                        RequestNotification.ExecuteRequestHandler /*requestNotifications*/,
                        0 /*postRequestNotifications*/,
                        String.Empty /*type*/,
                        HttpApplication.MANAGED_PRECONDITION /*precondition*/,
                        new IntPtr(-1),
                        false /*useHighPriority*/);

                    if (hresult < 0)
                    {
                        throw new COMException(SR.GetString(SR.Failed_Pipeline_Subscription, HttpApplication.IMPLICIT_HANDLER),
                                               hresult);
                    }
                }

                if (app != null)
                {
                    HttpApplicationFactory.RecyclePipelineApplicationInstance(app);
                }
            }
        }
        private static SuspendState SuspendImpl(ICollection <ISuspendibleRegisteredObject> allRegisteredObjects)
        {
            // Our behavior is:
            // - We'll call each registered object's suspend method serially.
            // - All methods have a combined 5 seconds to respond, at which
            //   point we'll forcibly return to our caller.
            // - If a Resume call comes in, we'll not call any Suspend methods
            //   we haven't yet gotten around to, and we'll execute each
            //   resume callback we got.
            // - Resume callbacks may fire in parallel, even if Suspend methods
            //   fire sequentially.
            // - Resume methods fire asynchronously, so other events (such as
            //   Stop or a new Suspend call) could happen while a Resume callback
            //   is in progress.

            CountdownEvent countdownEvent = new CountdownEvent(2);
            SuspendState   suspendState   = new SuspendState(allRegisteredObjects);

            // Unsafe QUWI since occurs outside the context of a request.
            // We are not concerned about impersonation, identity, etc.

            // Invoke any registered subscribers to let them know that we're about
            // to suspend. This is done in parallel with ASP.NET's own cleanup below.
            if (allRegisteredObjects.Count > 0)
            {
                ThreadPool.UnsafeQueueUserWorkItem(_ => {
                    suspendState.Suspend();
                    countdownEvent.Signal();
                }, null);
            }
            else
            {
                countdownEvent.Signal(); // nobody is subscribed
            }

            // Release any unnecessary memory that we're holding on to. The GC will
            // be able to reclaim these, which means that we'll have to page in less
            // memory when the next request comes in.
            ThreadPool.UnsafeQueueUserWorkItem(_ => {
                // Release any char[] buffers we're keeping around
                HttpWriter.ReleaseAllPooledBuffers();

                // Trim expired entries from the runtime cache
                var cache = HttpRuntime.GetCacheInternal(createIfDoesNotExist: false);
                if (cache != null)
                {
                    cache.TrimCache(0);
                }

                // Trim all pooled HttpApplication instances
                HttpApplicationFactory.TrimApplicationInstances(removeAll: true);

                countdownEvent.Signal();
            }, null);

            if (Debug.IsDebuggerPresent())
            {
                countdownEvent.Wait(); // to assist with debugging, don't time out if a debugger is attached
            }
            else
            {
                countdownEvent.Wait(_suspendMethodTimeout); // blocking call, ok for our needs since has finite wait time
            }
            return(suspendState);
        }