HttpRuntime.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. //
  2. // System.Web.HttpRuntime.cs
  3. //
  4. // Authors:
  5. // Miguel de Icaza ([email protected])
  6. // Marek Habersack <[email protected]>
  7. //
  8. //
  9. // Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining
  12. // a copy of this software and associated documentation files (the
  13. // "Software"), to deal in the Software without restriction, including
  14. // without limitation the rights to use, copy, modify, merge, publish,
  15. // distribute, sublicense, and/or sell copies of the Software, and to
  16. // permit persons to whom the Software is furnished to do so, subject to
  17. // the following conditions:
  18. //
  19. // The above copyright notice and this permission notice shall be
  20. // included in all copies or substantial portions of the Software.
  21. //
  22. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. //
  30. //
  31. // TODO: Call HttpRequest.CloseInputStream when we finish a request, as we are using the IntPtr stream.
  32. //
  33. using System.IO;
  34. using System.Text;
  35. using System.Globalization;
  36. using System.Collections;
  37. using System.Collections.Concurrent;
  38. using System.Reflection;
  39. using System.Security;
  40. using System.Security.Permissions;
  41. using System.Web.Caching;
  42. using System.Web.Configuration;
  43. using System.Web.Management;
  44. using System.Web.UI;
  45. using System.Web.Util;
  46. #if MONOWEB_DEP
  47. using Mono.Web.Util;
  48. #endif
  49. using System.Threading;
  50. #if TARGET_J2EE
  51. using Mainsoft.Web;
  52. #else
  53. using System.CodeDom.Compiler;
  54. using System.Web.Compilation;
  55. #endif
  56. namespace System.Web
  57. {
  58. // CAS - no InheritanceDemand here as the class is sealed
  59. [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  60. public sealed class HttpRuntime
  61. {
  62. static bool domainUnloading;
  63. static SplitOrderedList <string, string> registeredAssemblies;
  64. #if TARGET_J2EE
  65. static QueueManager queue_manager { get { return _runtime._queue_manager; } }
  66. static TraceManager trace_manager { get { return _runtime._trace_manager; } }
  67. static Cache cache { get { return _runtime._cache; } }
  68. static Cache internalCache { get { return _runtime._internalCache; } }
  69. static WaitCallback do_RealProcessRequest;
  70. QueueManager _queue_manager;
  71. TraceManager _trace_manager;
  72. Cache _cache;
  73. Cache _internalCache;
  74. public HttpRuntime ()
  75. {
  76. WebConfigurationManager.Init ();
  77. _queue_manager = new QueueManager ();
  78. _trace_manager = new TraceManager ();
  79. _cache = new Cache ();
  80. _internalCache = new Cache();
  81. _internalCache.DependencyCache = _cache;
  82. }
  83. static HttpRuntime _runtimeInstance {
  84. get {
  85. HttpRuntime runtime = (HttpRuntime) AppDomain.CurrentDomain.GetData ("HttpRuntime");
  86. if (runtime == null)
  87. lock (typeof (HttpRuntime)) {
  88. runtime = (HttpRuntime) AppDomain.CurrentDomain.GetData ("HttpRuntime");
  89. if (runtime == null) {
  90. runtime = new HttpRuntime ();
  91. AppDomain.CurrentDomain.SetData ("HttpRuntime", runtime);
  92. }
  93. }
  94. return runtime;
  95. }
  96. }
  97. static HttpRuntime _runtime
  98. {
  99. get
  100. {
  101. if (HttpContext.Current != null)
  102. return HttpContext.Current.HttpRuntimeInstance;
  103. else
  104. return _runtimeInstance;
  105. }
  106. }
  107. #else
  108. static QueueManager queue_manager;
  109. static TraceManager trace_manager;
  110. static Cache cache;
  111. static Cache internalCache;
  112. static WaitCallback do_RealProcessRequest;
  113. static HttpWorkerRequest.EndOfSendNotification end_of_send_cb;
  114. static Exception initialException;
  115. static bool firstRun;
  116. static bool assemblyMappingEnabled;
  117. static object assemblyMappingLock = new object ();
  118. static object appOfflineLock = new object ();
  119. static HttpRuntimeSection runtime_section;
  120. public HttpRuntime ()
  121. {
  122. }
  123. #endif
  124. static HttpRuntime ()
  125. {
  126. #if !TARGET_J2EE
  127. firstRun = true;
  128. try {
  129. WebConfigurationManager.Init ();
  130. #if MONOWEB_DEP
  131. SettingsMappingManager.Init ();
  132. #endif
  133. runtime_section = (HttpRuntimeSection) WebConfigurationManager.GetSection ("system.web/httpRuntime");
  134. } catch (Exception ex) {
  135. initialException = ex;
  136. }
  137. // The classes in whose constructors exceptions may be thrown, should be handled the same way QueueManager
  138. // and TraceManager are below. The constructors themselves MUST NOT throw any exceptions - we MUST be sure
  139. // the objects are created here. The exceptions will be dealt with below, in RealProcessRequest.
  140. queue_manager = new QueueManager ();
  141. if (queue_manager.HasException)
  142. initialException = queue_manager.InitialException;
  143. trace_manager = new TraceManager ();
  144. if (trace_manager.HasException)
  145. initialException = trace_manager.InitialException;
  146. registeredAssemblies = new SplitOrderedList <string, string> (StringComparer.Ordinal);
  147. cache = new Cache ();
  148. internalCache = new Cache ();
  149. internalCache.DependencyCache = internalCache;
  150. #endif
  151. do_RealProcessRequest = new WaitCallback (state => {
  152. try {
  153. RealProcessRequest (state);
  154. } catch {}
  155. });
  156. end_of_send_cb = new HttpWorkerRequest.EndOfSendNotification (EndOfSend);
  157. }
  158. internal static SplitOrderedList <string, string> RegisteredAssemblies {
  159. get { return registeredAssemblies; }
  160. }
  161. #region AppDomain handling
  162. internal static bool DomainUnloading {
  163. get { return domainUnloading; }
  164. }
  165. [MonoDocumentationNote ("Currently returns path to the application root")]
  166. public static string AspClientScriptPhysicalPath { get { return AppDomainAppPath; } }
  167. [MonoDocumentationNote ("Currently returns path to the application root")]
  168. public static string AspClientScriptVirtualPath { get { return AppDomainAppVirtualPath; } }
  169. //
  170. // http://radio.weblogs.com/0105476/stories/2002/07/12/executingAspxPagesWithoutAWebServer.html
  171. //
  172. public static string AppDomainAppId {
  173. [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
  174. get {
  175. //
  176. // This value should not change across invocations
  177. //
  178. string dirname = (string) AppDomain.CurrentDomain.GetData (".appId");
  179. if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
  180. new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
  181. }
  182. return dirname;
  183. }
  184. }
  185. // Physical directory for the application
  186. public static string AppDomainAppPath {
  187. get {
  188. string dirname = (string) AppDomain.CurrentDomain.GetData (".appPath");
  189. if (SecurityManager.SecurityEnabled) {
  190. new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
  191. }
  192. return dirname;
  193. }
  194. }
  195. public static string AppDomainAppVirtualPath {
  196. get {
  197. return (string) AppDomain.CurrentDomain.GetData (".appVPath");
  198. }
  199. }
  200. public static string AppDomainId {
  201. [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
  202. get {
  203. return (string) AppDomain.CurrentDomain.GetData (".domainId");
  204. }
  205. }
  206. public static string AspInstallDirectory {
  207. get {
  208. string dirname = (string) AppDomain.CurrentDomain.GetData (".hostingInstallDir");
  209. if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
  210. new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
  211. }
  212. return dirname;
  213. }
  214. }
  215. #endregion
  216. static string _actual_bin_directory;
  217. public static string BinDirectory {
  218. get {
  219. if (_actual_bin_directory == null) {
  220. string[] parts = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath.Split (';');
  221. string mypath = AppDomainAppPath;
  222. string tmp;
  223. foreach (string p in parts) {
  224. tmp = Path.Combine (mypath, p);
  225. if (Directory.Exists (tmp)) {
  226. _actual_bin_directory = tmp;
  227. break;
  228. }
  229. }
  230. if (_actual_bin_directory == null)
  231. _actual_bin_directory = Path.Combine (mypath, "bin");
  232. if (_actual_bin_directory [_actual_bin_directory.Length - 1] != Path.DirectorySeparatorChar)
  233. _actual_bin_directory += Path.DirectorySeparatorChar;
  234. }
  235. if (SecurityManager.SecurityEnabled)
  236. new FileIOPermission (FileIOPermissionAccess.PathDiscovery, _actual_bin_directory).Demand ();
  237. return _actual_bin_directory;
  238. }
  239. }
  240. public static Cache Cache {
  241. get {
  242. return cache;
  243. }
  244. }
  245. internal static Cache InternalCache {
  246. get {
  247. return internalCache;
  248. }
  249. }
  250. public static string ClrInstallDirectory {
  251. get {
  252. string dirname = Path.GetDirectoryName (typeof (Object).Assembly.Location);
  253. if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
  254. new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
  255. }
  256. return dirname;
  257. }
  258. }
  259. public static string CodegenDir {
  260. get {
  261. string dirname = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
  262. if (SecurityManager.SecurityEnabled) {
  263. new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
  264. }
  265. return dirname;
  266. }
  267. }
  268. public static bool IsOnUNCShare {
  269. [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
  270. get {
  271. return RuntimeHelpers.IsUncShare;
  272. }
  273. }
  274. public static string MachineConfigurationDirectory {
  275. get {
  276. string dirname = Path.GetDirectoryName (ICalls.GetMachineConfigPath ());
  277. if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
  278. new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
  279. }
  280. return dirname;
  281. }
  282. }
  283. internal static HttpRuntimeSection Section { get { return runtime_section; } }
  284. public static bool UsingIntegratedPipeline { get { return false; } }
  285. [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
  286. public static void Close ()
  287. {
  288. // Remove all items from cache.
  289. }
  290. internal static HttpWorkerRequest QueuePendingRequest (bool started_internally)
  291. {
  292. HttpWorkerRequest next = queue_manager.GetNextRequest (null);
  293. if (next == null)
  294. return null;
  295. if (!started_internally) {
  296. next.StartedInternally = true;
  297. ThreadPool.QueueUserWorkItem (do_RealProcessRequest, next);
  298. return null;
  299. }
  300. return next;
  301. }
  302. #if !TARGET_J2EE
  303. static readonly string[] app_offline_files = {"app_offline.htm", "App_Offline.htm", "APP_OFFLINE.HTM"};
  304. static string app_offline_file;
  305. static bool AppIsOffline (HttpContext context)
  306. {
  307. if (!HttpApplicationFactory.ApplicationDisabled || app_offline_file == null)
  308. return false;
  309. HttpResponse response = context.Response;
  310. response.Clear ();
  311. response.ContentType = "text/html";
  312. response.ExpiresAbsolute = DateTime.UtcNow;
  313. response.StatusCode = 503;
  314. response.TransmitFile (app_offline_file, true);
  315. context.Request.ReleaseResources ();
  316. context.Response.ReleaseResources ();
  317. HttpContext.Current = null;
  318. HttpApplication.requests_total_counter.Increment ();
  319. return true;
  320. }
  321. static void AppOfflineFileRenamed (object sender, RenamedEventArgs args)
  322. {
  323. AppOfflineFileChanged (sender, args);
  324. }
  325. static void AppOfflineFileChanged (object sender, FileSystemEventArgs args)
  326. {
  327. lock (appOfflineLock) {
  328. bool offline;
  329. switch (args.ChangeType) {
  330. case WatcherChangeTypes.Created:
  331. case WatcherChangeTypes.Changed:
  332. offline = true;
  333. break;
  334. case WatcherChangeTypes.Deleted:
  335. offline = false;
  336. break;
  337. case WatcherChangeTypes.Renamed:
  338. RenamedEventArgs rargs = args as RenamedEventArgs;
  339. if (rargs != null &&
  340. String.Compare (rargs.Name, "app_offline.htm", StringComparison.OrdinalIgnoreCase) == 0)
  341. offline = true;
  342. else
  343. offline = false;
  344. break;
  345. default:
  346. offline = false;
  347. break;
  348. }
  349. SetOfflineMode (offline, args.FullPath);
  350. }
  351. }
  352. static void SetOfflineMode (bool offline, string filePath)
  353. {
  354. if (!offline) {
  355. app_offline_file = null;
  356. if (HttpApplicationFactory.ApplicationDisabled)
  357. HttpRuntime.UnloadAppDomain ();
  358. } else {
  359. app_offline_file = filePath;
  360. HttpApplicationFactory.DisableWatchers ();
  361. HttpApplicationFactory.ApplicationDisabled = true;
  362. InternalCache.InvokePrivateCallbacks ();
  363. HttpApplicationFactory.Dispose ();
  364. }
  365. }
  366. static void SetupOfflineWatch ()
  367. {
  368. lock (appOfflineLock) {
  369. FileSystemEventHandler seh = new FileSystemEventHandler (AppOfflineFileChanged);
  370. RenamedEventHandler reh = new RenamedEventHandler (AppOfflineFileRenamed);
  371. string app_dir = AppDomainAppPath;
  372. ArrayList watchers = new ArrayList ();
  373. FileSystemWatcher watcher;
  374. string offlineFile = null, tmp;
  375. foreach (string f in app_offline_files) {
  376. watcher = new FileSystemWatcher ();
  377. watcher.Path = Path.GetDirectoryName (app_dir);
  378. watcher.Filter = Path.GetFileName (f);
  379. watcher.NotifyFilter |= NotifyFilters.Size;
  380. watcher.Deleted += seh;
  381. watcher.Changed += seh;
  382. watcher.Created += seh;
  383. watcher.Renamed += reh;
  384. watcher.EnableRaisingEvents = true;
  385. watchers.Add (watcher);
  386. tmp = Path.Combine (app_dir, f);
  387. if (File.Exists (tmp))
  388. offlineFile = tmp;
  389. }
  390. if (offlineFile != null)
  391. SetOfflineMode (true, offlineFile);
  392. }
  393. }
  394. #endif
  395. static void RealProcessRequest (object o)
  396. {
  397. if (domainUnloading) {
  398. Console.Error.WriteLine ("Domain is unloading, not processing the request.");
  399. return;
  400. }
  401. HttpWorkerRequest req = (HttpWorkerRequest) o;
  402. bool started_internally = req.StartedInternally;
  403. do {
  404. Process (req);
  405. req = QueuePendingRequest (started_internally);
  406. } while (started_internally && req != null);
  407. }
  408. static void Process (HttpWorkerRequest req)
  409. {
  410. #if TARGET_J2EE
  411. HttpContext context = HttpContext.Current;
  412. if (context == null)
  413. context = new HttpContext (req);
  414. else
  415. context.SetWorkerRequest (req);
  416. #else
  417. HttpContext context = new HttpContext (req);
  418. #endif
  419. HttpContext.Current = context;
  420. bool error = false;
  421. #if !TARGET_J2EE
  422. if (firstRun) {
  423. SetupOfflineWatch ();
  424. firstRun = false;
  425. if (initialException != null) {
  426. FinishWithException (req, HttpException.NewWithCode ("Initial exception", initialException, WebEventCodes.RuntimeErrorRequestAbort));
  427. error = true;
  428. }
  429. }
  430. if (AppIsOffline (context))
  431. return;
  432. #endif
  433. //
  434. // Get application instance (create or reuse an instance of the correct class)
  435. //
  436. HttpApplication app = null;
  437. if (!error) {
  438. try {
  439. app = HttpApplicationFactory.GetApplication (context);
  440. } catch (Exception e) {
  441. FinishWithException (req, HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort));
  442. error = true;
  443. }
  444. }
  445. if (error) {
  446. context.Request.ReleaseResources ();
  447. context.Response.ReleaseResources ();
  448. HttpContext.Current = null;
  449. } else {
  450. context.ApplicationInstance = app;
  451. req.SetEndOfSendNotification (end_of_send_cb, context);
  452. //
  453. // Ask application to service the request
  454. //
  455. #if TARGET_J2EE
  456. IHttpAsyncHandler ihah = app;
  457. if (context.Handler == null)
  458. ihah.BeginProcessRequest (context, new AsyncCallback (request_processed), context);
  459. else
  460. app.Tick ();
  461. //ihh.ProcessRequest (context);
  462. IHttpExtendedHandler extHandler = context.Handler as IHttpExtendedHandler;
  463. if (extHandler != null && !extHandler.IsCompleted)
  464. return;
  465. if (context.Error is UnifyRequestException)
  466. return;
  467. ihah.EndProcessRequest (null);
  468. #else
  469. IHttpHandler ihh = app;
  470. // IAsyncResult appiar = ihah.BeginProcessRequest (context, new AsyncCallback (request_processed), context);
  471. // ihah.EndProcessRequest (appiar);
  472. ihh.ProcessRequest (context);
  473. #endif
  474. HttpApplicationFactory.Recycle (app);
  475. }
  476. }
  477. static void EndOfSend (HttpWorkerRequest ignored1, object ignored2)
  478. {
  479. }
  480. //
  481. // ProcessRequest method is executed in the AppDomain of the application
  482. //
  483. // Observations:
  484. // ProcessRequest does not guarantee that `wr' will be processed synchronously,
  485. // the request can be queued and processed later.
  486. //
  487. [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
  488. public static void ProcessRequest (HttpWorkerRequest wr)
  489. {
  490. if (wr == null)
  491. throw new ArgumentNullException ("wr");
  492. //
  493. // Queue our request, fetch the next available one from the queue
  494. //
  495. HttpWorkerRequest request = queue_manager.GetNextRequest (wr);
  496. if (request == null)
  497. return;
  498. QueuePendingRequest (false);
  499. RealProcessRequest (request);
  500. }
  501. #if TARGET_J2EE
  502. //
  503. // Callback to be invoked by IHttpAsyncHandler.BeginProcessRequest
  504. //
  505. static void request_processed (IAsyncResult iar)
  506. {
  507. HttpContext context = (HttpContext) iar.AsyncState;
  508. context.Request.ReleaseResources ();
  509. context.Response.ReleaseResources ();
  510. }
  511. #endif
  512. #if TARGET_JVM
  513. [MonoNotSupported ("UnloadAppDomain is not supported")]
  514. public static void UnloadAppDomain ()
  515. {
  516. throw new NotImplementedException ("UnloadAppDomain is not supported");
  517. }
  518. #else
  519. //
  520. // Called when we are shutting down or we need to reload an application
  521. // that has been modified (touch global.asax)
  522. //
  523. [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
  524. public static void UnloadAppDomain ()
  525. {
  526. //
  527. // TODO: call ReleaseResources
  528. //
  529. domainUnloading = true;
  530. HttpApplicationFactory.DisableWatchers ();
  531. ThreadPool.QueueUserWorkItem (delegate {
  532. try {
  533. ShutdownAppDomain ();
  534. } catch (Exception e){
  535. Console.Error.WriteLine (e);
  536. }
  537. });
  538. }
  539. #endif
  540. //
  541. // Shuts down the AppDomain
  542. //
  543. static void ShutdownAppDomain ()
  544. {
  545. queue_manager.Dispose ();
  546. // This will call Session_End if needed.
  547. InternalCache.InvokePrivateCallbacks ();
  548. // Kill our application.
  549. HttpApplicationFactory.Dispose ();
  550. ThreadPool.QueueUserWorkItem (delegate {
  551. try {
  552. DoUnload ();
  553. } catch {
  554. }});
  555. }
  556. static void DoUnload ()
  557. {
  558. #if TARGET_J2EE
  559. // No unload support for appdomains under Grasshopper
  560. #else
  561. AppDomain.Unload (AppDomain.CurrentDomain);
  562. #endif
  563. }
  564. static string content503 = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" +
  565. "<html><head>\n<title>503 Server Unavailable</title>\n</head><body>\n" +
  566. "<h1>Server Unavailable</h1>\n" +
  567. "</body></html>\n";
  568. static void FinishWithException (HttpWorkerRequest wr, HttpException e)
  569. {
  570. int code = e.GetHttpCode ();
  571. wr.SendStatus (code, HttpWorkerRequest.GetStatusDescription (code));
  572. wr.SendUnknownResponseHeader ("Connection", "close");
  573. Encoding enc = Encoding.ASCII;
  574. wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
  575. string msg = e.GetHtmlErrorMessage ();
  576. byte [] contentBytes = enc.GetBytes (msg);
  577. wr.SendUnknownResponseHeader ("Content-Length", contentBytes.Length.ToString ());
  578. wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
  579. wr.FlushResponse (true);
  580. wr.CloseConnection ();
  581. HttpApplication.requests_total_counter.Increment ();
  582. }
  583. //
  584. // This is called from the QueueManager if a request
  585. // can not be processed (load, no resources, or
  586. // appdomain unload).
  587. //
  588. static internal void FinishUnavailable (HttpWorkerRequest wr)
  589. {
  590. wr.SendStatus (503, "Service unavailable");
  591. wr.SendUnknownResponseHeader ("Connection", "close");
  592. Encoding enc = Encoding.ASCII;
  593. wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
  594. byte [] contentBytes = enc.GetBytes (content503);
  595. wr.SendUnknownResponseHeader ("Content-Length", contentBytes.Length.ToString ());
  596. wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
  597. wr.FlushResponse (true);
  598. wr.CloseConnection ();
  599. HttpApplication.requests_total_counter.Increment ();
  600. }
  601. [AspNetHostingPermissionAttribute(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Unrestricted)]
  602. [MonoDocumentationNote ("Always returns null on Mono")]
  603. public static NamedPermissionSet GetNamedPermissionSet ()
  604. {
  605. return null;
  606. }
  607. #if !TARGET_J2EE
  608. static internal void WritePreservationFile (Assembly asm, string genericNameBase)
  609. {
  610. if (asm == null)
  611. throw new ArgumentNullException ("asm");
  612. if (String.IsNullOrEmpty (genericNameBase))
  613. throw new ArgumentNullException ("genericNameBase");
  614. string compiled = Path.Combine (AppDomain.CurrentDomain.SetupInformation.DynamicBase,
  615. genericNameBase + ".compiled");
  616. PreservationFile pf = new PreservationFile ();
  617. try {
  618. pf.VirtualPath = String.Concat ("/", genericNameBase, "/");
  619. AssemblyName an = asm.GetName ();
  620. pf.Assembly = an.Name;
  621. pf.ResultType = BuildResultTypeCode.TopLevelAssembly;
  622. pf.Save (compiled);
  623. } catch (Exception ex) {
  624. throw new HttpException (
  625. String.Format ("Failed to write preservation file {0}", genericNameBase + ".compiled"),
  626. ex);
  627. }
  628. }
  629. static Assembly ResolveAssemblyHandler(object sender, ResolveEventArgs e)
  630. {
  631. AssemblyName an = new AssemblyName (e.Name);
  632. string dynamic_base = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
  633. string compiled = Path.Combine (dynamic_base, an.Name + ".compiled");
  634. string asmPath;
  635. if (!File.Exists (compiled)) {
  636. string fn = an.FullName;
  637. if (!RegisteredAssemblies.Find ((uint)fn.GetHashCode (), fn, out asmPath))
  638. return null;
  639. } else {
  640. PreservationFile pf;
  641. try {
  642. pf = new PreservationFile (compiled);
  643. } catch (Exception ex) {
  644. throw new HttpException (
  645. String.Format ("Failed to read preservation file {0}", an.Name + ".compiled"),
  646. ex);
  647. }
  648. asmPath = Path.Combine (dynamic_base, pf.Assembly + ".dll");
  649. }
  650. if (String.IsNullOrEmpty (asmPath))
  651. return null;
  652. Assembly ret = null;
  653. try {
  654. ret = Assembly.LoadFrom (asmPath);
  655. } catch (Exception) {
  656. // ignore
  657. }
  658. return ret;
  659. }
  660. internal static void EnableAssemblyMapping (bool enable)
  661. {
  662. lock (assemblyMappingLock) {
  663. if (assemblyMappingEnabled == enable)
  664. return;
  665. if (enable)
  666. AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler (ResolveAssemblyHandler);
  667. else
  668. AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler (ResolveAssemblyHandler);
  669. assemblyMappingEnabled = enable;
  670. }
  671. }
  672. #endif // #if !TARGET_J2EE
  673. internal static TraceManager TraceManager {
  674. get {
  675. return trace_manager;
  676. }
  677. }
  678. }
  679. }