-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathHttpRuntime.cs
3595 lines (2939 loc) · 147 KB
/
HttpRuntime.cs
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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//------------------------------------------------------------------------------
// <copyright file="HttpRuntime.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
* The ASP.NET runtime services
*
* Copyright (c) 1998 Microsoft Corporation
*/
namespace System.Web {
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Net;
using System.Reflection;
using System.Resources;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Security.Policy;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Caching;
using System.Web.Compilation;
using System.Web.Configuration;
using System.Web.Hosting;
using System.Web.Management;
using System.Web.Security;
using System.Web.UI;
using System.Web.Util;
using System.Xml;
using Microsoft.Win32;
/// <devdoc>
/// <para>Provides a set of ASP.NET runtime services.</para>
/// </devdoc>
public sealed class HttpRuntime {
internal const string codegenDirName = "Temporary ASP.NET Files";
internal const string profileFileName = "profileoptimization.prof";
private static HttpRuntime _theRuntime; // single instance of the class
internal static byte[] s_autogenKeys = new byte[1024];
//
// Names of special ASP.NET directories
//
internal const string BinDirectoryName = "bin";
internal const string CodeDirectoryName = "App_Code";
internal const string WebRefDirectoryName = "App_WebReferences";
internal const string ResourcesDirectoryName = "App_GlobalResources";
internal const string LocalResourcesDirectoryName = "App_LocalResources";
internal const string DataDirectoryName = "App_Data";
internal const string ThemesDirectoryName = "App_Themes";
internal const string GlobalThemesDirectoryName = "Themes";
internal const string BrowsersDirectoryName = "App_Browsers";
private static string DirectorySeparatorString = new string(Path.DirectorySeparatorChar, 1);
private static string DoubleDirectorySeparatorString = new string(Path.DirectorySeparatorChar, 2);
private static char[] s_InvalidPhysicalPathChars = { '/', '?', '*', '<', '>', '|', '"' };
#if OLD
// For s_forbiddenDirs and s_forbiddenDirsConstant, see
// ndll.h, and RestrictIISFolders in regiis.cxx
internal static string[] s_forbiddenDirs = {
BinDirectoryName,
CodeDirectoryName,
DataDirectoryName,
ResourcesDirectoryName,
WebRefDirectoryName,
};
internal static Int32[] s_forbiddenDirsConstant = {
UnsafeNativeMethods.RESTRICT_BIN,
UnsafeNativeMethods.RESTRICT_CODE,
UnsafeNativeMethods.RESTRICT_DATA,
UnsafeNativeMethods.RESTRICT_RESOURCES,
UnsafeNativeMethods.RESTRICT_WEBREFERENCES,
};
#endif
static HttpRuntime() {
AddAppDomainTraceMessage("*HttpRuntime::cctor");
StaticInit();
_theRuntime = new HttpRuntime();
_theRuntime.Init();
AddAppDomainTraceMessage("HttpRuntime::cctor*");
}
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
public HttpRuntime() {
}
//
// static initialization to get hooked up to the unmanaged code
// get installation directory, etc.
//
private static bool s_initialized = false;
private static String s_installDirectory;
private static bool s_isEngineLoaded = false;
// Force the static initialization of this class.
internal static void ForceStaticInit() { }
private static void StaticInit() {
if (s_initialized) {
// already initialized
return;
}
bool isEngineLoaded = false;
bool wasEngineLoadedHere = false;
String installDir = null;
// load webengine.dll if it is not loaded already
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
installDir = RuntimeEnvironment.GetRuntimeDirectory();
if (UnsafeNativeMethods.GetModuleHandle(ModName.ENGINE_FULL_NAME) != IntPtr.Zero) {
isEngineLoaded = true;
}
// Load webengine.dll if not loaded already
if (!isEngineLoaded) {
String fullPath = installDir + Path.DirectorySeparatorChar + ModName.ENGINE_FULL_NAME;
if (UnsafeNativeMethods.LoadLibrary(fullPath) != IntPtr.Zero) {
isEngineLoaded = true;
wasEngineLoadedHere = true;
}
}
if (isEngineLoaded) {
UnsafeNativeMethods.InitializeLibrary(false);
if (wasEngineLoadedHere) {
UnsafeNativeMethods.PerfCounterInitialize();
}
}
#else // !FEATURE_PAL
string p = typeof(object).Module.FullyQualifiedName;
installDir = Path.GetDirectoryName(p);
#endif // !FEATURE_PAL
s_installDirectory = installDir;
s_isEngineLoaded = isEngineLoaded;
s_initialized = true;
PopulateIISVersionInformation();
AddAppDomainTraceMessage("Initialize");
}
//
// Runtime services
//
private NamedPermissionSet _namedPermissionSet;
private PolicyLevel _policyLevel;
private string _hostSecurityPolicyResolverType = null;
private FileChangesMonitor _fcm;
private Cache _cachePublic;
private bool _isOnUNCShare;
private Profiler _profiler;
private RequestTimeoutManager _timeoutManager;
private RequestQueue _requestQueue;
private bool _apartmentThreading;
private bool _processRequestInApplicationTrust;
private bool _disableProcessRequestInApplicationTrust;
private bool _isLegacyCas;
//
// Counters
//
private bool _beforeFirstRequest = true;
private DateTime _firstRequestStartTime;
private bool _firstRequestCompleted;
private bool _userForcedShutdown;
private bool _configInited;
private bool _fusionInited;
private int _activeRequestCount;
private volatile bool _disposingHttpRuntime;
private DateTime _lastShutdownAttemptTime;
private bool _shutdownInProgress;
private String _shutDownStack;
private String _shutDownMessage;
private ApplicationShutdownReason _shutdownReason = ApplicationShutdownReason.None;
private string _trustLevel;
private string _wpUserId;
private bool _shutdownWebEventRaised;
//
// Header Newlines
//
private bool _enableHeaderChecking;
//
// Callbacks
//
private AsyncCallback _requestNotificationCompletionCallback;
private AsyncCallback _handlerCompletionCallback;
private HttpWorkerRequest.EndOfSendNotification _asyncEndOfSendCallback;
private WaitCallback _appDomainUnloadallback;
//
// Initialization error (to be reported on subsequent requests)
//
private Exception _initializationError;
private bool _hostingInitFailed; // make such errors non-sticky
private Timer _appDomainShutdownTimer = null;
//
// App domain related
//
private String _tempDir;
private String _codegenDir;
private String _appDomainAppId;
private String _appDomainAppPath;
private VirtualPath _appDomainAppVPath;
private String _appDomainId;
//
// Debugging support
//
private bool _debuggingEnabled = false;
//
// App_Offline.htm support
//
private const string AppOfflineFileName = "App_Offline.htm";
private const long MaxAppOfflineFileLength = 1024 * 1024;
private byte[] _appOfflineMessage;
//
// Client script support
//
private const string AspNetClientFilesSubDirectory = "asp.netclientfiles";
private const string AspNetClientFilesParentVirtualPath = "/aspnet_client/system_web/";
private string _clientScriptVirtualPath;
private string _clientScriptPhysicalPath;
//
// IIS version and whether we're using the integrated pipeline
//
private static Version _iisVersion;
private static bool _useIntegratedPipeline;
//
// Prefetch
//
private static bool _enablePrefetchOptimization;
/////////////////////////////////////////////////////////////////////////
// 3 steps of initialization:
// Init() is called from HttpRuntime cctor
// HostingInit() is called by the Hosting Environment
// FirstRequestInit() is called on first HTTP request
//
/*
* Context-less initialization (on app domain creation)
*/
private void Init() {
try {
#if !FEATURE_PAL
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
throw new PlatformNotSupportedException(SR.GetString(SR.RequiresNT));
#else // !FEATURE_PAL
// ROTORTODO
// Do nothing: FEATURE_PAL environment will always support ASP.NET hosting
#endif // !FEATURE_PAL
_profiler = new Profiler();
_timeoutManager = new RequestTimeoutManager();
_wpUserId = GetCurrentUserName();
_requestNotificationCompletionCallback = new AsyncCallback(this.OnRequestNotificationCompletion);
_handlerCompletionCallback = new AsyncCallback(this.OnHandlerCompletion);
_asyncEndOfSendCallback = new HttpWorkerRequest.EndOfSendNotification(this.EndOfSendCallback);
_appDomainUnloadallback = new WaitCallback(this.ReleaseResourcesAndUnloadAppDomain);
// appdomain values
if (GetAppDomainString(".appDomain") != null) {
Debug.Assert(HostingEnvironment.IsHosted);
_appDomainAppId = GetAppDomainString(".appId");
_appDomainAppPath = GetAppDomainString(".appPath");
_appDomainAppVPath = VirtualPath.CreateNonRelativeTrailingSlash(GetAppDomainString(".appVPath"));
_appDomainId = GetAppDomainString(".domainId");
_isOnUNCShare = StringUtil.StringStartsWith(_appDomainAppPath, "\\\\");
// init perf counters for this appdomain
PerfCounters.Open(_appDomainAppId);
}
else {
Debug.Assert(!HostingEnvironment.IsHosted);
}
// _appDomainAppPath should be set before file change notifications are initialized
// DevDiv 248126: Check httpRuntime fcnMode first before we use the registry key
_fcm = new FileChangesMonitor(HostingEnvironment.FcnMode);
}
catch (Exception e) {
// remember static initalization error
InitializationException = e;
}
}
private void SetUpDataDirectory() {
// Set the DataDirectory (see VSWhidbey 226834) with permission (DevDiv 29614)
string dataDirectory = Path.Combine(_appDomainAppPath, DataDirectoryName);
AppDomain.CurrentDomain.SetData("DataDirectory", dataDirectory,
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dataDirectory));
}
private void DisposeAppDomainShutdownTimer() {
Timer timer = _appDomainShutdownTimer;
if (timer != null && Interlocked.CompareExchange(ref _appDomainShutdownTimer, null, timer) == timer) {
timer.Dispose();
}
}
private void AppDomainShutdownTimerCallback(Object state) {
try {
DisposeAppDomainShutdownTimer();
ShutdownAppDomain(ApplicationShutdownReason.InitializationError, "Initialization Error");
}
catch { } // ignore exceptions
}
/*
* Restart the AppDomain in 10 seconds
*/
private void StartAppDomainShutdownTimer() {
if (_appDomainShutdownTimer == null && !_shutdownInProgress) {
lock (this) {
if (_appDomainShutdownTimer == null && !_shutdownInProgress) {
_appDomainShutdownTimer = new Timer(
new TimerCallback(this.AppDomainShutdownTimerCallback),
null,
10 * 1000,
0);
}
}
}
}
/*
* Initialization from HostingEnvironment of HTTP independent features
*/
private void HostingInit(HostingEnvironmentFlags hostingFlags, PolicyLevel policyLevel, Exception appDomainCreationException) {
using (new ApplicationImpersonationContext()) {
try {
// To ignore FCN during initialization
_firstRequestStartTime = DateTime.UtcNow;
SetUpDataDirectory();
// Throw an exception about lack of access to app directory early on
EnsureAccessToApplicationDirectory();
// Monitor renames to directories we are watching, and notifications on the bin directory
//
// Note that this must be the first monitoring that we do of the application directory.
// There is a bug in Windows 2000 Server where notifications on UNC shares do not
// happen correctly if:
// 1. the directory is monitored for regular notifications
// 2. the directory is then monitored for directory renames
// 3. the directory is monitored again for regular notifications
StartMonitoringDirectoryRenamesAndBinDirectory();
// Initialize ObjectCacheHost before config is read, since config relies on the cache
if (InitializationException == null) {
HostingEnvironment.InitializeObjectCacheHost();
}
//
// Get the configuration needed to minimally initialize
// the components required for a complete configuration system,
// especially SetTrustLevel.
//
// We want to do this before calling SetUpCodegenDirectory(),
// to remove the risk of the config system loading
// codegen assemblies in full trust (VSWhidbey 460506)
//
CacheSection cacheSection;
TrustSection trustSection;
SecurityPolicySection securityPolicySection;
CompilationSection compilationSection;
HostingEnvironmentSection hostingEnvironmentSection;
Exception configInitException;
GetInitConfigSections(
out cacheSection,
out trustSection,
out securityPolicySection,
out compilationSection,
out hostingEnvironmentSection,
out configInitException);
// Once the configuration system is initialized, we can read
// the cache configuration settings.
//
// Note that we must do this after we start monitoring directory renames,
// as reading config will cause file monitoring on the application directory
// to occur.
// Set up the codegen directory for the app. This needs to be done before we process
// the policy file, because it needs to replace the $CodeGen$ token.
SetUpCodegenDirectory(compilationSection);
if(compilationSection != null) {
_enablePrefetchOptimization = compilationSection.EnablePrefetchOptimization;
if(_enablePrefetchOptimization) {
UnsafeNativeMethods.StartPrefetchActivity((uint)StringUtil.GetStringHashCode(_appDomainAppId));
}
}
// NOTE: after calling SetUpCodegenDirectory(), and until we call SetTrustLevel(), we are at
// risk of codegen assemblies being loaded in full trust. No code that might cause
// assembly loading should be added here! This is only valid if the legacyCasModel is set
// to true in <trust> section.
// Throw the original configuration exception from ApplicationManager if configuration is broken.
if (appDomainCreationException != null) {
throw appDomainCreationException;
}
if (trustSection == null || String.IsNullOrEmpty(trustSection.Level)) {
throw new ConfigurationErrorsException(SR.GetString(SR.Config_section_not_present, "trust"));
}
if (trustSection.LegacyCasModel) {
try {
_disableProcessRequestInApplicationTrust = false;
_isLegacyCas = true;
// Set code access policy on the app domain
SetTrustLevel(trustSection, securityPolicySection);
}
catch {
// throw the original config exception if it exists
if (configInitException != null)
throw configInitException;
throw;
}
}
else if ((hostingFlags & HostingEnvironmentFlags.ClientBuildManager) != 0) {
_trustLevel = "Full";
}
else {
_disableProcessRequestInApplicationTrust = true;
// Set code access policy properties of the runtime object
SetTrustParameters(trustSection, securityPolicySection, policyLevel);
}
// Configure fusion to use directories set in the app config
InitFusion(hostingEnvironmentSection);
// set the sliding expiration for URL metadata
CachedPathData.InitializeUrlMetadataSlidingExpiration(hostingEnvironmentSection);
// Complete initialization of configuration.
// Note that this needs to be called after SetTrustLevel,
// as it indicates that we have the permission set needed
// to correctly run configuration section handlers.
// As little config should be read before CompleteInit() as possible.
// No section that runs before CompleteInit() should demand permissions,
// as the permissions set has not yet determined until SetTrustLevel()
// is called.
HttpConfigurationSystem.CompleteInit();
//
// If an exception occurred loading configuration,
// we are now ready to handle exception processing
// with the correct trust level set.
//
if (configInitException != null) {
throw configInitException;
}
SetThreadPoolLimits();
SetAutogenKeys();
// Initialize the build manager
BuildManager.InitializeBuildManager();
if(compilationSection != null && compilationSection.ProfileGuidedOptimizations == ProfileGuidedOptimizationsFlags.All) {
ProfileOptimization.SetProfileRoot(_codegenDir);
ProfileOptimization.StartProfile(profileFileName);
}
// Determine apartment threading setting
InitApartmentThreading();
// Init debugging
InitDebuggingSupport();
_processRequestInApplicationTrust = trustSection.ProcessRequestInApplicationTrust;
// Init AppDomain Resource Perf Counters
AppDomainResourcePerfCounters.Init();
RelaxMapPathIfRequired();
}
catch (Exception e) {
_hostingInitFailed = true;
InitializationException = e;
Debug.Trace("AppDomainFactory", "HostingInit failed. " + e.ToString());
if ((hostingFlags & HostingEnvironmentFlags.ThrowHostingInitErrors) != 0)
throw;
}
}
}
internal static Exception InitializationException {
get {
return _theRuntime._initializationError;
}
// The exception is "cached" for 10 seconds, then the AppDomain is restarted.
set {
_theRuntime._initializationError = value;
// In v2.0, we shutdown immediately if hostingInitFailed...so we don't need the timer
if (!HostingInitFailed) {
_theRuntime.StartAppDomainShutdownTimer();
}
}
}
internal static bool HostingInitFailed {
get {
return _theRuntime._hostingInitFailed;
}
}
internal static void InitializeHostingFeatures(HostingEnvironmentFlags hostingFlags, PolicyLevel policyLevel, Exception appDomainCreationException) {
_theRuntime.HostingInit(hostingFlags, policyLevel, appDomainCreationException);
}
internal static bool EnableHeaderChecking {
get {
return _theRuntime._enableHeaderChecking;
}
}
internal static bool ProcessRequestInApplicationTrust {
get {
return _theRuntime._processRequestInApplicationTrust;
}
}
internal static bool DisableProcessRequestInApplicationTrust {
get {
return _theRuntime._disableProcessRequestInApplicationTrust;
}
}
internal static bool IsLegacyCas {
get {
return _theRuntime._isLegacyCas;
}
}
internal static byte[] AppOfflineMessage {
get {
return _theRuntime._appOfflineMessage;
}
}
/*
* Initialization on first request (context available)
*/
private void FirstRequestInit(HttpContext context) {
Exception error = null;
if (InitializationException == null && _appDomainId != null) {
#if DBG
HttpContext.SetDebugAssertOnAccessToCurrent(true);
#endif
try {
using (new ApplicationImpersonationContext()) {
// Is this necessary? See InitHttpConfiguration
CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture;
CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture;
try {
// Ensure config system is initialized
InitHttpConfiguration(); // be sure config system is set
// Check if applicaton is enabled
CheckApplicationEnabled();
// Check access to temp compilation directory (under hosting identity)
CheckAccessToTempDirectory();
// Initialize health monitoring
InitializeHealthMonitoring();
// Init request queue (after reading config)
InitRequestQueue();
// configure the profiler according to config
InitTrace(context);
// Start heatbeat for Web Event Health Monitoring
HealthMonitoringManager.StartHealthMonitoringHeartbeat();
// Remove read and browse access of the bin directory
RestrictIISFolders(context);
// Preload all assemblies from bin (only if required). ASURT 114486
PreloadAssembliesFromBin();
// Decide whether or not to encode headers. VsWhidbey 257154
InitHeaderEncoding();
// Force the current encoder + validator to load so that there's a deterministic
// place (here) for an exception to occur if there's a load error
HttpEncoder.InitializeOnFirstRequest();
RequestValidator.InitializeOnFirstRequest();
if (context.WorkerRequest is ISAPIWorkerRequestOutOfProc) {
// Make sure that the <processModel> section has no errors
ProcessModelSection processModel = RuntimeConfig.GetMachineConfig().ProcessModel;
}
}
finally {
Thread.CurrentThread.CurrentUICulture = savedUICulture;
SetCurrentThreadCultureWithAssert(savedCulture);
}
}
}
catch (ConfigurationException e) {
error = e;
}
catch (Exception e) {
// remember second-phase initialization error
error = new HttpException(SR.GetString(SR.XSP_init_error, e.Message), e);
}
finally {
#if DBG
HttpContext.SetDebugAssertOnAccessToCurrent(false);
#endif
}
}
if (InitializationException != null) {
// throw cached exception. We need to wrap it in a new exception, otherwise
// we lose the original stack.
throw new HttpException(InitializationException.Message, InitializationException);
}
else if (error != null) {
InitializationException = error;
// throw new exception
throw error;
}
AddAppDomainTraceMessage("FirstRequestInit");
}
[SecurityPermission(SecurityAction.Assert, ControlThread = true)]
internal static void SetCurrentThreadCultureWithAssert(CultureInfo cultureInfo) {
Thread.CurrentThread.CurrentCulture = cultureInfo;
}
private void EnsureFirstRequestInit(HttpContext context) {
if (_beforeFirstRequest) {
lock (this) {
if (_beforeFirstRequest) {
_firstRequestStartTime = DateTime.UtcNow;
FirstRequestInit(context);
_beforeFirstRequest = false;
context.FirstRequest = true;
}
}
}
}
private void EnsureAccessToApplicationDirectory() {
if (!FileUtil.DirectoryAccessible(_appDomainAppPath)) {
//
if (_appDomainAppPath.IndexOf('?') >= 0) {
// Possible Unicode when not supported
throw new HttpException(SR.GetString(SR.Access_denied_to_unicode_app_dir, _appDomainAppPath));
}
else {
throw new HttpException(SR.GetString(SR.Access_denied_to_app_dir, _appDomainAppPath));
}
}
}
private void StartMonitoringDirectoryRenamesAndBinDirectory() {
_fcm.StartMonitoringDirectoryRenamesAndBinDirectory(AppDomainAppPathInternal, new FileChangeEventHandler(this.OnCriticalDirectoryChange));
}
//
// Monitor a local resources subdirectory and unload appdomain when it changes
//
internal static void StartListeningToLocalResourcesDirectory(VirtualPath virtualDir) {
#if !FEATURE_PAL // FEATURE_PAL does not enable file change notification
_theRuntime._fcm.StartListeningToLocalResourcesDirectory(virtualDir);
#endif // !FEATURE_PAL
}
//
// Get the configuration needed to minimally initialize
// the components required for a complete configuration system,
//
// Note that if the application configuration file has an error,
// AppLKGConfig will still retreive any valid configuration from
// that file, or from location directives that apply to the
// application path. This implies that an administrator can
// lock down an application's trust level in root web.config,
// and it will still take effect if the application's web.config
// has errors.
//
private void GetInitConfigSections(
out CacheSection cacheSection,
out TrustSection trustSection,
out SecurityPolicySection securityPolicySection,
out CompilationSection compilationSection,
out HostingEnvironmentSection hostingEnvironmentSection,
out Exception initException) {
cacheSection = null;
trustSection = null;
securityPolicySection = null;
compilationSection = null;
hostingEnvironmentSection = null;
initException = null;
// AppLKGConfig is guaranteed to not throw an exception.
RuntimeConfig appLKGConfig = RuntimeConfig.GetAppLKGConfig();
// AppConfig may throw an exception.
RuntimeConfig appConfig = null;
try {
appConfig = RuntimeConfig.GetAppConfig();
}
catch (Exception e) {
initException = e;
}
// Cache section
if (appConfig != null) {
try {
cacheSection = appConfig.Cache;
}
catch (Exception e) {
if (initException == null) {
initException = e;
}
}
}
if (cacheSection == null) {
cacheSection = appLKGConfig.Cache;
}
// Trust section
if (appConfig != null) {
try {
trustSection = appConfig.Trust;
}
catch (Exception e) {
if (initException == null) {
initException = e;
}
}
}
if (trustSection == null) {
trustSection = appLKGConfig.Trust;
}
// SecurityPolicy section
if (appConfig != null) {
try {
securityPolicySection = appConfig.SecurityPolicy;
}
catch (Exception e) {
if (initException == null) {
initException = e;
}
}
}
if (securityPolicySection == null) {
securityPolicySection = appLKGConfig.SecurityPolicy;
}
// Compilation section
if (appConfig != null) {
try {
compilationSection = appConfig.Compilation;
}
catch (Exception e) {
if (initException == null) {
initException = e;
}
}
}
if (compilationSection == null) {
compilationSection = appLKGConfig.Compilation;
}
// HostingEnvironment section
if (appConfig != null) {
try {
hostingEnvironmentSection = appConfig.HostingEnvironment;
}
catch (Exception e) {
if (initException == null) {
initException = e;
}
}
}
if (hostingEnvironmentSection == null) {
hostingEnvironmentSection = appLKGConfig.HostingEnvironment;
}
}
// Set up the codegen directory for the app
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "This call site is trusted.")]
private void SetUpCodegenDirectory(CompilationSection compilationSection) {
AppDomain appDomain = Thread.GetDomain();
string codegenBase;
// devdiv 1038337. Passing the corresponding IsDevelopmentEnvironment flag to ConstructSimpleAppName
string simpleAppName = System.Web.Hosting.AppManagerAppDomainFactory.ConstructSimpleAppName(
AppDomainAppVirtualPath, HostingEnvironment.IsDevelopmentEnvironment);
string tempDirectory = null;
// These variables are used for error handling
string tempDirAttribName = null;
string configFileName = null;
int configLineNumber = 0;
if (compilationSection != null && !String.IsNullOrEmpty(compilationSection.TempDirectory)) {
tempDirectory = compilationSection.TempDirectory;
compilationSection.GetTempDirectoryErrorInfo(out tempDirAttribName,
out configFileName, out configLineNumber);
}
if (tempDirectory != null) {
tempDirectory = tempDirectory.Trim();
if (!Path.IsPathRooted(tempDirectory)) {
// Make sure the path is not relative (VSWhidbey 260075)
tempDirectory = null;
}
else {
try {
// Canonicalize it to avoid problems with spaces (VSWhidbey 229873)
tempDirectory = new DirectoryInfo(tempDirectory).FullName;
}
catch {
tempDirectory = null;
}
}
if (tempDirectory == null) {
throw new ConfigurationErrorsException(
SR.GetString(SR.Invalid_temp_directory, tempDirAttribName),
configFileName, configLineNumber);
}
#if FEATURE_PAL
} else {
System.UInt32 length = 0;
StringBuilder sb = null;
bool bRet;
// Get the required length
bRet = UnsafeNativeMethods.GetUserTempDirectory(
UnsafeNativeMethods.DeploymentDirectoryType.ddtInstallationDependentDirectory,
null, ref length);
if (true == bRet) {
// now, allocate the string
sb = new StringBuilder ((int)length);
// call again to get the value
bRet = UnsafeNativeMethods.GetUserTempDirectory(
UnsafeNativeMethods.DeploymentDirectoryType.ddtInstallationDependentDirectory,
sb, ref length);
}
if (false == bRet) {
throw new ConfigurationException(
HttpRuntime.FormatResourceString(SR.Invalid_temp_directory, tempDirAttribName));
}
tempDirectory = Path.Combine(sb.ToString(), codegenDirName);
}
// Always try to create the ASP.Net temp directory for FEATURE_PAL
#endif // FEATURE_PAL
// Create the config-specified directory if needed
try {
Directory.CreateDirectory(tempDirectory);
}
catch (Exception e) {
throw new ConfigurationErrorsException(
SR.GetString(SR.Invalid_temp_directory, tempDirAttribName),
e,
configFileName, configLineNumber);
}
#if !FEATURE_PAL
}
else {
tempDirectory = Path.Combine(s_installDirectory, codegenDirName);
}
#endif // !FEATURE_PAL
// If we don't have write access to the codegen dir, use the TEMP dir instead.
// This will allow non-admin users to work in hosting scenarios (e.g. Venus, aspnet_compiler)
if (!System.Web.UI.Util.HasWriteAccessToDirectory(tempDirectory)) {
// Don't do this if we are not in a CBM scenario and we're in a service (!UserInteractive),
// as TEMP could point to unwanted places.
#if !FEATURE_PAL // always fail here
if ((!BuildManagerHost.InClientBuildManager) && (!Environment.UserInteractive))
#endif // !FEATURE_PAL
{
throw new HttpException(SR.GetString(SR.No_codegen_access,
System.Web.UI.Util.GetCurrentAccountName(), tempDirectory));
}
tempDirectory = Path.GetTempPath();
Debug.Assert(System.Web.UI.Util.HasWriteAccessToDirectory(tempDirectory));
tempDirectory = Path.Combine(tempDirectory, codegenDirName);
}
_tempDir = tempDirectory;
codegenBase = Path.Combine(tempDirectory, simpleAppName);
#pragma warning disable 0618 // To avoid deprecation warning
appDomain.SetDynamicBase(codegenBase);
#pragma warning restore 0618
_codegenDir = Thread.GetDomain().DynamicDirectory;
// Create the codegen directory if needed
Directory.CreateDirectory(_codegenDir);
}
private void InitFusion(HostingEnvironmentSection hostingEnvironmentSection) {
AppDomain appDomain = Thread.GetDomain();