HttpRuntime.cs 21 KB

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