File: HttpConfigurationSystem.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (339 lines) | stat: -rw-r--r-- 14,851 bytes parent folder | download | duplicates (7)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
//------------------------------------------------------------------------------
// <copyright file="HttpConfigurationSystem.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

namespace System.Web.Configuration {
    using System.Configuration.Internal;
    using Microsoft.Win32;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Configuration;
    using System.IO;
    using System.Threading;
    using System.Web;
    using System.Web.Caching;
    using System.Web.Hosting;
    using System.Xml;
    using System.Web.Util;
    using System.Globalization;
    using System.Reflection;
    using System.Security;
    using System.Security.Permissions;

    using CultureInfo = System.Globalization.CultureInfo;
    using Debug = System.Web.Util.Debug;
    using UnicodeEncoding = System.Text.UnicodeEncoding;
    using UrlPath = System.Web.Util.UrlPath;

    internal class HttpConfigurationSystem : IInternalConfigSystem {
        private const string InternalConfigSettingsFactoryTypeString = "System.Configuration.Internal.InternalConfigSettingsFactory, " + AssemblyRef.SystemConfiguration;
        internal const string ConfigSystemTypeString = "System.Configuration.Internal.ConfigSystem, " + AssemblyRef.SystemConfiguration;

#if !PLATFORM_UNIX // File system paths must be lowercased in UNIX
        internal const string MachineConfigSubdirectory = "Config";
#else // !PLATFORM_UNIX
        internal const string MachineConfigSubdirectory = "config";
#endif // !PLATFORM_UNIX
        internal const string MachineConfigFilename = "machine.config";
        internal const string RootWebConfigFilename         = "web.config";
        internal const string WebConfigFileName             = "web.config";
        internal const string InetsrvDirectoryName          = "inetsrv";
        internal const string ApplicationHostConfigFileName = "applicationHost.config";

        static private object                           s_initLock;
        static private volatile bool                   s_inited;

        // Supports IInternalConfigSystem and the file change dependency delegate
        static private HttpConfigurationSystem          s_httpConfigSystem;
        static private IConfigSystem                    s_configSystem;

        static private IConfigMapPath                   s_configMapPath;
        static private WebConfigurationHost             s_configHost;
        static private FileChangeEventHandler           s_fileChangeEventHandler;
        static private string                           s_MsCorLibDirectory;
        static private string                           s_MachineConfigurationDirectory;
        static private string                           s_MachineConfigurationFilePath;
        static private string                           s_RootWebConfigurationFilePath;

        static private IInternalConfigRoot              s_configRoot;
        static private IInternalConfigSettingsFactory   s_configSettingsFactory;
        static private bool                             s_initComplete;

        static HttpConfigurationSystem() {
            s_initLock = new object();
        }

        HttpConfigurationSystem() {}

        //
        // Set this configuration system to the default for requests ConfigurationManager.GetSection
        //
        static internal void EnsureInit(IConfigMapPath configMapPath, bool listenToFileChanges, bool initComplete) {
            if (!s_inited) {
                lock (s_initLock) {
                    if (!s_inited) {
                        s_initComplete = initComplete;

                        // Use the IIS map path if one is not explicitly provided
                        if (configMapPath == null) {
                            configMapPath = IISMapPath.GetInstance();
                        }

                        s_configMapPath = configMapPath;

                        Type typeConfigSystem = Type.GetType(ConfigSystemTypeString, true);
                        s_configSystem = (IConfigSystem) Activator.CreateInstance(typeConfigSystem, true);
                        s_configSystem.Init(
                                typeof(WebConfigurationHost),               // The config host we'll create and use
                                // The remaining parameters are passed to the config host:
                                true,                                       // Use the supplied configMapPath
                                s_configMapPath,                            // the configMapPath to use
                                null,                                       // ConfigurationFileMap
                                HostingEnvironment.ApplicationVirtualPath,  // app path
                                HostingEnvironment.SiteNameNoDemand,        // app site name
                                HostingEnvironment.SiteID);                 // app site ID

                        s_configRoot = s_configSystem.Root;
                        s_configHost = (WebConfigurationHost) s_configSystem.Host;

                        // Register for config changed notifications
                        HttpConfigurationSystem configSystem = new HttpConfigurationSystem();

                        if (listenToFileChanges) {
                            s_configRoot.ConfigChanged += new InternalConfigEventHandler(configSystem.OnConfigurationChanged);
                        }

                        // Set the configSystem into the ConfigurationManager class.
                        // Please note that factory.SetConfigurationSystem will end up calling
                        // ConfigurationManager.SetConfigurationSystem, which is an internal static method
                        // in System.Configuration.dll.  If we want to call that here, we have to use
                        // reflection and that's what we want to avoid.
                        Type typeFactory = Type.GetType(InternalConfigSettingsFactoryTypeString, true);
                        s_configSettingsFactory = (IInternalConfigSettingsFactory) Activator.CreateInstance(typeFactory, true);
                        s_configSettingsFactory.SetConfigurationSystem(configSystem, initComplete);

                        // The system has been successfully set, so mark that we should use it.
                        s_httpConfigSystem = configSystem;

                        // Mark as having completed initialization after s_httpConfigSystem has been set.
                        // s_inited is coordinated with s_httpConfigSystem in UseHttpConfigurationSystem.
                        s_inited = true;
                    }
                }
            }

            Debug.Assert(s_httpConfigSystem != null, "s_httpConfigSystem != null - The appdomain is using the client configuration system.");
        }

        static internal void CompleteInit() {
            Debug.Assert(!s_initComplete, "!s_initComplete");
            s_configSettingsFactory.CompleteInit();
            s_configSettingsFactory = null;
        }

        // Return true if the HttpConfigurationSystem is being used
        // by ConfigurationManager.
        static internal bool UseHttpConfigurationSystem {
            get {
                if (!s_inited) {
                    lock (s_initLock) {
                        if (!s_inited) {
                            //
                            // If we ask whether the HttpConfigurationSystem is in use, and it has not
                            // been initialized, then this caller is going to end up using the client
                            // configuration system. So prevent initialization of the HttpConfigurationSystem
                            // by setting s_inited = true.
                            //
                            s_inited = true;
                            Debug.Assert(s_httpConfigSystem == null, "s_httpConfigSystem == null");
                        }
                    }
                }

                return s_httpConfigSystem != null;
            }
        }

        // Return true if the HttpConfigurationSystem is already loaded
        // by ConfigurationManager.
        static internal bool IsSet {
            get {
                return s_httpConfigSystem != null;
            }
        }


        //
        // Return the config object for the current context.
        // If the HttpContext is not available, get the config object
        // for the web application path.
        //
        object IInternalConfigSystem.GetSection(string configKey) {
            return HttpConfigurationSystem.GetSection(configKey);
        }

        // Does not support refresh - the appdomain will restart if
        // a file changes.
        void IInternalConfigSystem.RefreshConfig(string sectionName) {}

        // Supports user config
        bool IInternalConfigSystem.SupportsUserConfig {
            get {
                return false;
            }
        }

        // GetSection
        //
        // Get the Config for the current context
        //
        static internal object GetSection(string sectionName) {
            HttpContext context = HttpContext.Current;
            if (context != null) {
                return context.GetSection(sectionName);
            }
            else {
                // If there is no context, then lets get the config for
                // the application we are hosted in.
                return GetApplicationSection(sectionName);
            }
        }

        // GetSection
        //
        // Get the Config for a specific path
        //
        static internal object GetSection(string sectionName, VirtualPath path) {
            Debug.Assert(UseHttpConfigurationSystem, "UseHttpConfigurationSystem");

            CachedPathData pathData;

            pathData = CachedPathData.GetVirtualPathData(path, true);

            return pathData.ConfigRecord.GetSection(sectionName);
        }

        static internal object GetSection(string sectionName, string path) {
            return GetSection(sectionName, VirtualPath.CreateNonRelativeAllowNull(path));
        }

        // GetAppSection
        //
        // Get the Config for a specific path
        //
        static internal object GetApplicationSection(string sectionName) {
            Debug.Assert(UseHttpConfigurationSystem, "UseHttpConfigurationSystem");

            CachedPathData pathData;

            pathData = CachedPathData.GetApplicationPathData();

            return pathData.ConfigRecord.GetSection(sectionName);
        }


        //
        // Return the unique configuration record for a config path.
        // Used by CachedPathData to retreive config records.
        //
        static internal IInternalConfigRecord GetUniqueConfigRecord(string configPath) {
            if (!UseHttpConfigurationSystem)
                return null;

            IInternalConfigRecord configRecord = s_configRoot.GetUniqueConfigRecord(configPath);
            return configRecord;
        }

        static internal void AddFileDependency(String file) {
            if (String.IsNullOrEmpty(file))
                return;
#if !FEATURE_PAL // No file change notification in Coriolis
            if (UseHttpConfigurationSystem) {
                if (s_fileChangeEventHandler == null) {
                    s_fileChangeEventHandler = new FileChangeEventHandler(s_httpConfigSystem.OnConfigFileChanged);
                }

                HttpRuntime.FileChangesMonitor.StartMonitoringFile(file, s_fileChangeEventHandler);
            }
#endif // !FEATURE_PAL
        }

        internal void OnConfigurationChanged(Object sender, InternalConfigEventArgs e) {
            HttpRuntime.OnConfigChange(message: null);
        }

        internal void OnConfigFileChanged(Object sender, FileChangeEvent e) {
            string message = FileChangesMonitor.GenerateErrorMessage(e.Action, e.FileName);
            HttpRuntime.OnConfigChange(message);
        }

        static internal String MsCorLibDirectory {
            [FileIOPermissionAttribute(SecurityAction.Assert, AllFiles=FileIOPermissionAccess.PathDiscovery)]
            get {
                if (s_MsCorLibDirectory == null) {
                    s_MsCorLibDirectory = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
                }

                return s_MsCorLibDirectory;
            }
        }

        static internal string MachineConfigurationDirectory {
            get {
                if (s_MachineConfigurationDirectory == null) {
#if !FEATURE_PAL
                    s_MachineConfigurationDirectory = Path.Combine(MsCorLibDirectory, MachineConfigSubdirectory);
#else // !FEATURE_PAL
                    System.UInt32 length = 0;

                    // Get the required size
                    if (!UnsafeNativeMethods.GetMachineConfigurationDirectory(null, ref length)) {
                        throw new System.ComponentModel.Win32Exception();
                    }

                    // Now, create the string and call again
                    System.Text.StringBuilder sb = new System.Text.StringBuilder((int)length);

                    if (!UnsafeNativeMethods.GetMachineConfigurationDirectory(sb, ref length)) {
                        throw new System.ComponentModel.Win32Exception();
                    }

                    s_MachineConfigurationDirectory = sb.ToString();
#endif // !FEATURE_PAL
                }

                return s_MachineConfigurationDirectory;
            }
        }

        static internal string MachineConfigurationFilePath {
            get {
                if (s_MachineConfigurationFilePath == null) {
                    s_MachineConfigurationFilePath = Path.Combine(MachineConfigurationDirectory, MachineConfigFilename);
                }

                return s_MachineConfigurationFilePath;
            }
        }

        static internal string RootWebConfigurationFilePath {
            get {
                if (s_RootWebConfigurationFilePath == null) {
                    s_RootWebConfigurationFilePath = Path.Combine(MachineConfigurationDirectory, RootWebConfigFilename);
                }

                return s_RootWebConfigurationFilePath;
            }
            // for IIS 7, support setting this file path to support the hostable
            // web core and admin scenarios
            set {
                s_RootWebConfigurationFilePath = value;
                if (null == s_RootWebConfigurationFilePath) {
                    s_RootWebConfigurationFilePath = Path.Combine(MachineConfigurationDirectory, RootWebConfigFilename);
                }
            }
        }
    }
}