+ [MonoTODO ("Not Implemented")]
+ protected internal virtual string UniqueFilePathSuffix {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO ("Not Implemented")]
+ public int MaxPageStateFieldLength {
+ get {
+ throw new NotImplementedException ();
+ }
+ set {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public void AddOnPreRenderCompleteAsync (BeginEventHandler beginHandler, EndEventHandler endHandler)
+ {
+ AddOnPreRenderCompleteAsync (beginHandler, endHandler, null);
+ }
+
+ public void AddOnPreRenderCompleteAsync (BeginEventHandler beginHandler, EndEventHandler endHandler, Object state)
+ {
+ if (!IsAsync) {
+ throw new InvalidOperationException ("AddOnPreRenderCompleteAsync called and Page.IsAsync == false");
+ }
+
+ if (_lifeCycle >= PageLifeCycle.PreRender) {
+ throw new InvalidOperationException ("AddOnPreRenderCompleteAsync can only be called before PreRender.");
+ }
+
+ if (beginHandler == null) {
+ throw new ArgumentNullException ("beginHandler");
+ }
+
+ if (endHandler == null) {
+ throw new ArgumentNullException ("endHandler");
+ }
+
+ RegisterAsyncTask (new PageAsyncTask (beginHandler, endHandler, null, state, false));
+ }
+
+ private List<PageAsyncTask> ParallelTasks {
+ get
+ {
+ if (parallelTasks == null) {
+ parallelTasks = new List<PageAsyncTask>();
+ }
+ return parallelTasks;
+ }
+ }
+
+ private List<PageAsyncTask> SerialTasks {
+ get {
+ if (serialTasks == null) {
+ serialTasks = new List<PageAsyncTask> ();
+ }
+ return serialTasks;
+ }
+ }
+
+ public void RegisterAsyncTask (PageAsyncTask task)
+ {
+ if (task == null) {
+ throw new ArgumentNullException ("task");
+ }
+
+ if (task.ExecuteInParallel) {
+ ParallelTasks.Add (task);
+ }
+ else {
+ SerialTasks.Add (task);
+ }
+ }
+
+ public void ExecuteRegisteredAsyncTasks ()
+ {
+ if ((parallelTasks == null || parallelTasks.Count == 0) &&
+ (serialTasks == null || serialTasks.Count == 0)){
+ return;
+ }
+
+ if (parallelTasks != null) {
+ DateTime startExecution = DateTime.Now;
+ List<PageAsyncTask> localParallelTasks = parallelTasks;
+ parallelTasks = null; // Shouldn't execute tasks twice
+ List<IAsyncResult> asyncResults = new List<IAsyncResult>();
+ foreach (PageAsyncTask parallelTask in localParallelTasks) {
+ IAsyncResult result = parallelTask.BeginHandler (this, EventArgs.Empty, new AsyncCallback (EndAsyncTaskCallback), parallelTask.State);
+ if (result.CompletedSynchronously) {
+ parallelTask.EndHandler (result);
+ }
+ else {
+ asyncResults.Add (result);
+ }
+ }
+
+ if (asyncResults.Count > 0) {
+#if TARGET_JVM
+ TimeSpan timeout = AsyncTimeout;
+ long t1 = DateTime.Now.Ticks;
+ bool signalled = true;
+ for (int i = 0; i < asyncResults.Count; i++) {
+ if (asyncResults [i].IsCompleted)
+ continue;
+
+ if (signalled)
+ signalled = asyncResults [i].AsyncWaitHandle.WaitOne (timeout, false);
+
+ if (signalled) {
+ long t2 = DateTime.Now.Ticks;
+ timeout = AsyncTimeout - TimeSpan.FromTicks (t2 - t1);
+ if (timeout.Ticks <= 0)
+ signalled = false;
+ }
+ else {
+ localParallelTasks [i].TimeoutHandler (asyncResults [i]);
+ }
+ }
+#else
+ WaitHandle [] waitArray = new WaitHandle [asyncResults.Count];
+ int i = 0;
+ for (i = 0; i < asyncResults.Count; i++) {
+ waitArray [i] = asyncResults [i].AsyncWaitHandle;
+ }
+ bool allSignalled = WaitHandle.WaitAll (waitArray, AsyncTimeout, false);
+ if (!allSignalled) {
+ for (i = 0; i < asyncResults.Count; i++) {
+ if (!asyncResults [i].IsCompleted) {
+ localParallelTasks [i].TimeoutHandler (asyncResults [i]);
+ }
+ }
+ }
+#endif
+ }
+ DateTime endWait = DateTime.Now;
+ TimeSpan elapsed = endWait - startExecution;
+ if (elapsed <= AsyncTimeout) {
+ AsyncTimeout -= elapsed;
+ }
+ else {
+ AsyncTimeout = TimeSpan.FromTicks(0);
+ }
+ }
+
+ if (serialTasks != null) {
+ List<PageAsyncTask> localSerialTasks = serialTasks;
+ serialTasks = null; // Shouldn't execute tasks twice
+ foreach (PageAsyncTask serialTask in localSerialTasks) {
+ DateTime startExecution = DateTime.Now;
+
+ IAsyncResult result = serialTask.BeginHandler (this, EventArgs.Empty, new AsyncCallback (EndAsyncTaskCallback), serialTask);
+ if (result.CompletedSynchronously) {
+ serialTask.EndHandler (result);
+ }
+ else {
+ bool done = result.AsyncWaitHandle.WaitOne (AsyncTimeout, false);
+ if (!done && !result.IsCompleted) {
+ serialTask.TimeoutHandler (result);
+ }
+ }
+ DateTime endWait = DateTime.Now;
+ TimeSpan elapsed = endWait - startExecution;
+ if (elapsed <= AsyncTimeout) {
+ AsyncTimeout -= elapsed;
+ }
+ else {
+ AsyncTimeout = TimeSpan.FromTicks (0);
+ }
+ }
+ }
+ AsyncTimeout = TimeSpan.FromSeconds (DefaultAsyncTimeout);
+ }
+
+ void EndAsyncTaskCallback (IAsyncResult result)
+ {
+ PageAsyncTask task = (PageAsyncTask)result.AsyncState;
+ task.EndHandler (result);
+ }
+
+ public static HtmlTextWriter CreateHtmlTextWriterFromType (TextWriter tw, Type writerType)
+ {
+ Type htmlTextWriterType = typeof (HtmlTextWriter);
+
+ if (!htmlTextWriterType.IsAssignableFrom (writerType)) {
+ throw new HttpException (String.Format ("Type '{0}' cannot be assigned to HtmlTextWriter", writerType.FullName));
+ }
+
+ ConstructorInfo constructor = writerType.GetConstructor (new Type [] { typeof (TextWriter) });
+ if (constructor == null) {
+ throw new HttpException (String.Format ("Type '{0}' does not have a consturctor that takes a TextWriter as parameter", writerType.FullName));
+ }
+
+ return (HtmlTextWriter) Activator.CreateInstance(writerType, tw);
+ }
+
+ public ViewStateEncryptionMode ViewStateEncryptionMode {
+ get { return viewStateEncryptionMode; }
+ set { viewStateEncryptionMode = value; }
+ }
+
+ public void RegisterRequiresViewStateEncryption ()
+ {
+ controlRegisteredForViewStateEncryption = true;
+ }
+
+ private static byte [] AES_IV = null;
+ private static byte [] TripleDES_IV = null;
+ private static object locker = new object ();
+ private static bool isEncryptionInitialized = false;
+
+ private static void InitializeEncryption ()
+ {
+ if (isEncryptionInitialized) {
+ return;
+ }
+
+ lock (locker) {
+ if (isEncryptionInitialized) {
+ return;
+ }
+
+ string iv_string = "0BA48A9E-736D-40f8-954B-B2F62241F282";
+ AES_IV = new byte [16];
+ TripleDES_IV = new byte [8];
+
+ int i;
+ for (i = 0; i < AES_IV.Length; i++) {
+ AES_IV [i] = (byte) iv_string [i];
+ }
+
+ for (i = 0; i < TripleDES_IV.Length; i++) {
+ TripleDES_IV [i] = (byte) iv_string [i];
+ }
+
+ isEncryptionInitialized = true;
+ }
+ }
+
+ internal ICryptoTransform GetCryptoTransform (CryptoStreamMode cryptoStreamMode)
+ {
+ ICryptoTransform transform = null;
+ MachineKeySection config = (MachineKeySection) WebConfigurationManager.GetSection (machineKeyConfigPath);
+ byte [] vk = config.ValidationKeyBytes;
+
+ switch (config.Validation) {
+ case MachineKeyValidation.SHA1:
+ transform = SHA1.Create ();
+ break;
+
+ case MachineKeyValidation.MD5:
+ transform = MD5.Create ();
+ break;
+
+ case MachineKeyValidation.AES:
+ if (cryptoStreamMode == CryptoStreamMode.Read){
+ transform = Rijndael.Create().CreateDecryptor(vk, AES_IV);
+ } else {
+ transform = Rijndael.Create().CreateEncryptor(vk, AES_IV);
+ }
+ break;
+
+ case MachineKeyValidation.TripleDES:
+ if (cryptoStreamMode == CryptoStreamMode.Read){
+ transform = TripleDES.Create().CreateDecryptor(vk, TripleDES_IV);
+ } else {
+ transform = TripleDES.Create().CreateEncryptor(vk, TripleDES_IV);
+ }
+ break;
+ }
+
+ return transform;
+ }
+
+ internal bool NeedViewStateEncryption {
+ get {
+ return (ViewStateEncryptionMode == ViewStateEncryptionMode.Always ||
+ (ViewStateEncryptionMode == ViewStateEncryptionMode.Auto &&
+ controlRegisteredForViewStateEncryption));
+
+ }
+ }
+