PageRenderTime 36ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/Source.DLR/Core/RequestContext.cs

#
C# | 199 lines | 84 code | 28 blank | 87 comment | 9 complexity | d6fb7f2e06770a67d2e6641bdd0507c2 MD5 | raw file
Possible License(s): CPL-1.0, GPL-2.0, CC-BY-SA-3.0, MPL-2.0-no-copyleft-exception, Apache-2.0
  1. /*
  2. Copyright (c) 2005-2006 Tomas Matousek.
  3. The use and distribution terms for this software are contained in the file named License.txt,
  4. which can be found in the root of the Phalanger distribution. By using this software
  5. in any fashion, you are agreeing to be bound by the terms of this license.
  6. You must not remove this notice from this software.
  7. */
  8. using System;
  9. using System.IO;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Reflection;
  13. using System.Diagnostics;
  14. using System.Collections;
  15. using PHP.Core.Reflection;
  16. using PHP.Core.Emit;
  17. #if SILVERLIGHT
  18. using PHP.CoreCLR;
  19. #endif
  20. namespace PHP.Core
  21. {
  22. /// <summary>
  23. /// Represents a set of data associated with the current web request targeting PHP scripts.
  24. /// </summary>
  25. [Serializable]
  26. public sealed partial class RequestContext
  27. {
  28. #region Fields, Properties, Events
  29. /// <summary>
  30. /// Set when the context started finalization.
  31. /// </summary>
  32. private bool disposed = false;
  33. /// <summary>
  34. /// Current script context.
  35. /// </summary>
  36. public ScriptContext/*!*/ ScriptContext { get { return scriptContext; } }
  37. internal ScriptContext/*!*/ scriptContext;
  38. /// <summary>
  39. /// Source file targetted by the request.
  40. /// </summary>
  41. public PhpSourceFile/*!*/ RequestFile { get { return requestFile; } }
  42. private PhpSourceFile/*!*/ requestFile;
  43. /// <summary>
  44. /// Gets the original value of response encoding set in ASP.NET configuration.
  45. /// </summary>
  46. public Encoding DefaultResponseEncoding { get { return defaultResponseEncoding; } }
  47. private Encoding defaultResponseEncoding;
  48. /// <summary>
  49. /// An event fired on the very end of the request.
  50. /// </summary>
  51. public static event Notification RequestEnd;
  52. /// <summary>
  53. /// An event fired on the begining of the request after the script context is initialized.
  54. /// </summary>
  55. public static event Notification RequestBegin;
  56. #endregion
  57. #region Resources Management
  58. /// <summary>
  59. /// Lazily initialized list of <see cref="PhpResource"/>s created during this web request.
  60. /// </summary>
  61. /// <remarks>
  62. /// The resources are disposed of when the request is over.
  63. /// <seealso cref="RegisterResource"/><seealso cref="CleanUpResources"/>
  64. /// </remarks>
  65. private ArrayList resources; // GENERICS: <PhpResource>
  66. /// <summary>
  67. /// Registers a resource that should be disposed of when the request is over.
  68. /// </summary>
  69. /// <param name="res">The resource.</param>
  70. internal void RegisterResource(PhpResource res)
  71. {
  72. if (resources == null) resources = new ArrayList();
  73. resources.Add(res);
  74. }
  75. /// <summary>
  76. /// Disposes of <see cref="PhpResource"/>s created during this web request.
  77. /// </summary>
  78. private void CleanUpResources()
  79. {
  80. if (resources != null)
  81. {
  82. for (int i = 0; i < resources.Count; i++)
  83. {
  84. ((PhpResource)resources[i]).Dispose();
  85. }
  86. resources = null;
  87. }
  88. }
  89. #endregion
  90. #region Request Processing
  91. #if !SILVERLIGHT
  92. /// <summary>
  93. /// Performs PHP inclusion on a specified script. Equivalent to <see cref="PHP.Core.ScriptContext.IncludeScript"/>.
  94. /// </summary>
  95. /// <param name="relativeSourcePath">
  96. /// Path to the target script source file relative to the web application root.
  97. /// </param>
  98. /// <param name="type">
  99. /// Script type (i.e. type called <c>Default</c> representing the target script) or any type from
  100. /// the assembly where the target script is contained. In the latter case, the script type is searched in the
  101. /// assembly using value of <paramref name="relativeSourcePath"/>.
  102. /// </param>
  103. /// <returns>The value returned by the global code of the target script.</returns>
  104. /// <exception cref="InvalidOperationException">Request context has been disposed.</exception>
  105. /// <exception cref="ArgumentNullException"><paramref name="relativeSourcePath"/> or <paramref name="type"/> are <B>null</B> references.</exception>
  106. /// <exception cref="ArgumentException">Script type cannot be resolved.</exception>
  107. /// <exception cref="InvalidScriptAssemblyException">The target assembly is not a valid Phalanger compiled assembly.</exception>
  108. public object IncludeScript(string/*!*/ relativeSourcePath, Type/*!*/ type)
  109. {
  110. if (disposed)
  111. throw new InvalidOperationException(CoreResources.GetString("instance_disposed"));
  112. return scriptContext.IncludeScript(relativeSourcePath, type);
  113. }
  114. #endif
  115. /// <summary>
  116. /// Finalizes (disposes) the request context.
  117. /// </summary>
  118. /// <remarks>
  119. /// Finalization comprises of the following actions (executed in the order):
  120. /// <list type="number">
  121. /// <term>Output buffers are flushed. This action may include calls to user defined filters (see <c>ob_start</c> function).</term>
  122. /// <term>Shutdown callbacks are invoked (if added by <c>register_shutdown_function</c> function).</term>
  123. /// <term>Session is closed. User defined session handling function may be invoked (see <c>session_set_save_handler</c> function).</term>
  124. /// <term>PHP objects are destroyed.</term>
  125. /// <term>HTTP Headers are flushed (if it wasn't done earlier).</term>
  126. /// <term>PHP resources are disposed.</term>
  127. /// <term>Per-request temporary files are deleted.</term>
  128. /// <term><see cref="RequestEnd"/> event is fired.</term>
  129. /// <term>Current request and script contexts are nulled.</term>
  130. /// </list>
  131. /// Multiple invocations of the method are ignored.
  132. /// Since session data need to be written to the session store (<c>HttpContext.Session</c>) this method has to be
  133. /// called before the ASP.NET session is ended for the request.
  134. /// </remarks>
  135. public void Dispose()
  136. {
  137. if (!disposed)
  138. {
  139. try
  140. {
  141. scriptContext.GuardedCall(new Action(scriptContext.ProcessShutdownCallbacks), null, false);
  142. // Session is ended after destructing objects since PHP 5.0.5, use two-phase finalization:
  143. scriptContext.GuardedCall(new Action(scriptContext.FinalizePhpObjects), null, false);
  144. scriptContext.GuardedCall(new Action(scriptContext.FinalizeBufferedOutput), null, false);
  145. TryDisposeBeforeFinalization();
  146. // finalize objects created during session closing and output finalization:
  147. scriptContext.GuardedCall(new Action(scriptContext.FinalizePhpObjects), null, false);
  148. // Platforms-specific dispose
  149. TryDisposeAfterFinalization();
  150. }
  151. finally
  152. {
  153. CleanUpResources();
  154. // Platforms-specific finally dispose
  155. FinallyDispose();
  156. if (RequestEnd != null) RequestEnd();
  157. // cleans this instance:
  158. disposed = true;
  159. this.scriptContext = null;
  160. ScriptContext.CurrentContext = null;
  161. Debug.WriteLine("REQUEST", "-- disposed ----------------------");
  162. }
  163. }
  164. }
  165. #endregion
  166. }
  167. }