summaryrefslogtreecommitdiff
path: root/external/aspnetwebstack/src/System.Web.WebPages/WebPageHttpModule.cs
blob: 8f29d5a4e056501733f2e6c0410f1f09b6112c58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.

namespace System.Web.WebPages
{
    internal class WebPageHttpModule : IHttpModule
    {
        internal static EventHandler Initialize;
        internal static EventHandler ApplicationStart;
        internal static EventHandler BeginRequest;
        internal static EventHandler EndRequest;
        private static bool _appStartExecuted = false;
        private static readonly object _appStartExecutedLock = new object();
        private static readonly object _hasBeenRegisteredKey = new object();

        internal static bool AppStartExecuteCompleted { get; set; }

        public void Dispose()
        {
        }

        public void Init(HttpApplication application)
        {
            if (application.Context.Items[_hasBeenRegisteredKey] != null)
            {
                // registration for this module has already run for this HttpApplication instance
                return;
            }

            application.Context.Items[_hasBeenRegisteredKey] = true;

            InitApplication(application);
        }

        internal static void InitApplication(HttpApplication application)
        {
            // We need to run StartApplication first, so that any exception thrown during execution of the StartPage gets
            // recorded on StartPage.Exception
            StartApplication(application);
            InitializeApplication(application);
        }

        internal static void InitializeApplication(HttpApplication application)
        {
            InitializeApplication(application, OnApplicationPostResolveRequestCache, Initialize);
        }

        internal static void InitializeApplication(HttpApplication application, EventHandler onApplicationPostResolveRequestCache, EventHandler initialize)
        {
            if (initialize != null)
            {
                initialize(application, EventArgs.Empty);
            }
            application.PostResolveRequestCache += onApplicationPostResolveRequestCache;
            if (ApplicationStartPage.Exception != null || BeginRequest != null)
            {
                application.BeginRequest += OnBeginRequest;
            }

            application.EndRequest += OnEndRequest;
        }

        internal static void StartApplication(HttpApplication application)
        {
            StartApplication(application, ApplicationStartPage.ExecuteStartPage, ApplicationStart);
        }

        internal static void StartApplication(HttpApplication application, Action<HttpApplication> executeStartPage, EventHandler applicationStart)
        {
            // Application start events should happen only once per application life time.
            lock (_appStartExecutedLock)
            {
                if (!_appStartExecuted)
                {
                    _appStartExecuted = true;

                    executeStartPage(application);
                    AppStartExecuteCompleted = true;
                    if (applicationStart != null)
                    {
                        applicationStart(application, EventArgs.Empty);
                    }
                }
            }
        }

        internal static void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
        {
            HttpContextBase context = new HttpContextWrapper(((HttpApplication)sender).Context);
            new WebPageRoute().DoPostResolveRequestCache(context);
        }

        internal static void OnBeginRequest(object sender, EventArgs e)
        {
            if (ApplicationStartPage.Exception != null)
            {
                // Throw it as a HttpException so as to
                // display the original stack trace information.
                throw new HttpException(null, ApplicationStartPage.Exception);
            }
            if (BeginRequest != null)
            {
                BeginRequest(sender, e);
            }
        }

        internal static void OnEndRequest(object sender, EventArgs e)
        {
            if (EndRequest != null)
            {
                EndRequest(sender, e);
            }

            var app = (HttpApplication)sender;
            RequestResourceTracker.DisposeResources(new HttpContextWrapper(app.Context));
        }
    }
}