2 // System.Web.HttpApplication.cs
5 // Miguel de Icaza (miguel@novell.com)
6 // Gonzalo Paniagua (gonzalo@ximian.com)
9 // Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
30 // The Application Processing Pipeline.
32 // The Http application pipeline implemented in this file is a
33 // beautiful thing. The application pipeline invokes a number of
34 // hooks at various stages of the processing of a request. These
35 // hooks can be either synchronous or can be asynchronous.
37 // The pipeline must ensure that every step is completed before
38 // moving to the next step. A trivial thing for synchronous
39 // hooks, but asynchronous hooks introduce an extra layer of
40 // complexity: when the hook is invoked, the thread must
41 // relinquish its control so that the thread can be reused in
42 // another operation while waiting.
44 // To implement this functionality we used C# iterators manually;
45 // we drive the pipeline by executing the various hooks from the
46 // `RunHooks' routine which is an enumerator that will yield the
47 // value `false' if execution must proceed or `true' if execution
50 // By yielding values we can suspend execution of RunHooks.
52 // Special attention must be given to `in_begin' and `must_yield'
53 // variables. These are used in the case that an async hook
54 // completes synchronously as its important to not yield in that
55 // case or we would hang.
57 // Many of Mono modules used to be declared async, but they would
58 // actually be completely synchronous, this might resurface in the
59 // future with other modules.
66 using System.Collections;
67 using System.ComponentModel;
68 using System.Configuration;
69 using System.Diagnostics;
70 using System.Globalization;
71 using System.Reflection;
72 using System.Security.Permissions;
73 using System.Security.Principal;
74 using System.Threading;
75 using System.Web.Caching;
76 using System.Web.Compilation;
77 using System.Web.Configuration;
78 using System.Web.Management;
79 using System.Web.SessionState;
81 using System.Web.Util;
90 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
91 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
94 public class HttpApplication : IHttpAsyncHandler, IHttpHandler, IComponent, IDisposable
96 static readonly object disposedEvent = new object ();
97 static readonly object errorEvent = new object ();
99 // we do this static rather than per HttpApplication because
100 // mono's perfcounters use the counter instance parameter for
101 // the process to access shared memory.
102 internal static PerformanceCounter requests_total_counter = new PerformanceCounter ("ASP.NET", "Requests Total");
104 internal static readonly string [] BinDirs = {"Bin", "bin"};
105 object this_lock = new object();
108 HttpSessionState session;
111 // The source, and the exposed API (cache).
112 volatile HttpModuleCollection modcoll;
114 string assemblyLocation;
117 // The factory for the handler currently running.
119 IHttpHandlerFactory factory;
122 // Whether the thread culture is to be auto-set.
123 // Used only in the 2.0 profile, always false for 1.x
129 // Whether the pipeline should be stopped
131 bool stop_processing;
134 // See https://bugzilla.novell.com/show_bug.cgi?id=381971
136 bool in_application_start;
141 IEnumerator pipeline;
143 // To flag when we are done processing a request from BeginProcessRequest.
144 ManualResetEvent done;
146 // The current IAsyncResult for the running async request handler in the pipeline
147 AsyncRequestState begin_iar;
149 // Tracks the current AsyncInvocation being dispatched
150 AsyncInvoker current_ai;
152 EventHandlerList events;
153 EventHandlerList nonApplicationEvents = new EventHandlerList ();
155 // Culture and IPrincipal
156 CultureInfo app_culture;
157 CultureInfo appui_culture;
158 CultureInfo prev_app_culture;
159 CultureInfo prev_appui_culture;
160 IPrincipal prev_user;
162 static string binDirectory;
165 const string initialization_exception_key = "System.Web.HttpApplication.initialization_exception";
166 static Exception initialization_exception {
167 get { return (Exception) AppDomain.CurrentDomain.GetData (initialization_exception_key); }
168 set { AppDomain.CurrentDomain.SetData (initialization_exception_key, value); }
171 static volatile Exception initialization_exception;
173 bool removeConfigurationFromCache;
174 bool fullInitComplete = false;
177 // These are used to detect the case where the EndXXX method is invoked
178 // from within the BeginXXXX delegate, so we detect whether we kick the
179 // pipeline from here, or from the the RunHook routine
184 public virtual event EventHandler Disposed {
185 add { nonApplicationEvents.AddHandler (disposedEvent, value); }
186 remove { nonApplicationEvents.RemoveHandler (disposedEvent, value); }
189 public virtual event EventHandler Error {
190 add { nonApplicationEvents.AddHandler (errorEvent, value); }
191 remove { nonApplicationEvents.RemoveHandler (errorEvent, value); }
194 public HttpApplication ()
196 done = new ManualResetEvent (false);
199 internal void InitOnce (bool full_init)
201 if (initialization_exception != null)
208 if (initialization_exception != null)
214 bool mustNullContext = context == null;
216 HttpModulesSection modules;
217 modules = (HttpModulesSection) WebConfigurationManager.GetWebApplicationSection ("system.web/httpModules");
218 HttpContext saved = HttpContext.Current;
219 HttpContext.Current = new HttpContext (new System.Web.Hosting.SimpleWorkerRequest (String.Empty, String.Empty, new StringWriter()));
221 context = HttpContext.Current;
222 HttpModuleCollection coll = modules.LoadModules (this);
223 Interlocked.CompareExchange (ref modcoll, coll, null);
224 HttpContext.Current = saved;
227 HttpApplicationFactory.AttachEvents (this);
229 fullInitComplete = true;
231 } catch (Exception e) {
232 initialization_exception = e;
240 internal bool InApplicationStart {
241 get { return in_application_start; }
242 set { in_application_start = value; }
245 internal string AssemblyLocation {
247 if (assemblyLocation == null)
248 assemblyLocation = GetType ().Assembly.Location;
249 return assemblyLocation;
253 internal static Exception InitializationException {
254 get { return initialization_exception; }
258 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
259 public HttpApplicationState Application {
261 return HttpApplicationFactory.ApplicationState;
266 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
267 public HttpContext Context {
273 protected EventHandlerList Events {
276 events = new EventHandlerList ();
283 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
284 public HttpModuleCollection Modules {
285 [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
288 modcoll = new HttpModuleCollection ();
295 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
296 public HttpRequest Request {
299 throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
301 if (false == HttpApplicationFactory.ContextAvailable)
302 throw HttpException.NewWithCode (Locale.GetText ("Request is not available in this context."), WebEventCodes.RuntimeErrorRequestAbort);
304 return context.Request;
309 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
310 public HttpResponse Response {
313 throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
315 if (false == HttpApplicationFactory.ContextAvailable)
316 throw HttpException.NewWithCode (Locale.GetText ("Response is not available in this context."), WebEventCodes.RuntimeErrorRequestAbort);
318 return context.Response;
323 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
324 public HttpServerUtility Server {
327 return context.Server;
330 // This is so we can get the Server and call a few methods
331 // which are not context sensitive, see HttpServerUtilityTest
333 return new HttpServerUtility ((HttpContext) null);
338 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
339 public HttpSessionState Session {
341 // Only used for Session_End
346 throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
348 HttpSessionState ret = context.Session;
350 throw HttpException.NewWithCode (Locale.GetText ("Session state is not available in the context."), WebEventCodes.RuntimeErrorRequestAbort);
357 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
359 get { return isite; }
361 set { isite = value; }
365 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
366 public IPrincipal User {
369 throw new HttpException (Locale.GetText ("No context is available."));
370 if (context.User == null)
371 throw new HttpException (Locale.GetText ("No currently authenticated user."));
377 static object PreSendRequestHeadersEvent = new object ();
378 public event EventHandler PreSendRequestHeaders
380 add { AddEventHandler (PreSendRequestHeadersEvent, value); }
381 remove { RemoveEventHandler (PreSendRequestHeadersEvent, value); }
384 internal void TriggerPreSendRequestHeaders ()
386 EventHandler handler = Events [PreSendRequestHeadersEvent] as EventHandler;
388 handler (this, EventArgs.Empty);
391 static object PreSendRequestContentEvent = new object ();
392 public event EventHandler PreSendRequestContent
394 add { AddEventHandler (PreSendRequestContentEvent, value); }
395 remove { RemoveEventHandler (PreSendRequestContentEvent, value); }
398 internal void TriggerPreSendRequestContent ()
400 EventHandler handler = Events [PreSendRequestContentEvent] as EventHandler;
402 handler (this, EventArgs.Empty);
405 static object AcquireRequestStateEvent = new object ();
406 public event EventHandler AcquireRequestState
408 add { AddEventHandler (AcquireRequestStateEvent, value); }
409 remove { RemoveEventHandler (AcquireRequestStateEvent, value); }
412 public void AddOnAcquireRequestStateAsync (BeginEventHandler bh, EndEventHandler eh)
414 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
415 AcquireRequestState += new EventHandler (invoker.Invoke);
418 static object AuthenticateRequestEvent = new object ();
419 public event EventHandler AuthenticateRequest
421 add { AddEventHandler (AuthenticateRequestEvent, value); }
422 remove { RemoveEventHandler (AuthenticateRequestEvent, value); }
425 public void AddOnAuthenticateRequestAsync (BeginEventHandler bh, EndEventHandler eh)
427 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
428 AuthenticateRequest += new EventHandler (invoker.Invoke);
431 static object AuthorizeRequestEvent = new object ();
432 public event EventHandler AuthorizeRequest
434 add { AddEventHandler (AuthorizeRequestEvent, value); }
435 remove { RemoveEventHandler (AuthorizeRequestEvent, value); }
438 public void AddOnAuthorizeRequestAsync (BeginEventHandler bh, EndEventHandler eh)
440 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
441 AuthorizeRequest += new EventHandler (invoker.Invoke);
444 static object BeginRequestEvent = new object ();
445 public event EventHandler BeginRequest
448 // See https://bugzilla.novell.com/show_bug.cgi?id=381971
449 if (InApplicationStart)
451 AddEventHandler (BeginRequestEvent, value);
454 if (InApplicationStart)
456 RemoveEventHandler (BeginRequestEvent, value);
460 public void AddOnBeginRequestAsync (BeginEventHandler bh, EndEventHandler eh)
462 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
463 BeginRequest += new EventHandler (invoker.Invoke);
466 static object EndRequestEvent = new object ();
467 public event EventHandler EndRequest
470 // See https://bugzilla.novell.com/show_bug.cgi?id=381971
471 if (InApplicationStart)
473 AddEventHandler (EndRequestEvent, value);
476 if (InApplicationStart)
478 RemoveEventHandler (EndRequestEvent, value);
482 public void AddOnEndRequestAsync (BeginEventHandler bh, EndEventHandler eh)
484 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
485 EndRequest += new EventHandler (invoker.Invoke);
488 static object PostRequestHandlerExecuteEvent = new object ();
489 public event EventHandler PostRequestHandlerExecute
491 add { AddEventHandler (PostRequestHandlerExecuteEvent, value); }
492 remove { RemoveEventHandler (PostRequestHandlerExecuteEvent, value); }
495 public void AddOnPostRequestHandlerExecuteAsync (BeginEventHandler bh, EndEventHandler eh)
497 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
498 PostRequestHandlerExecute += new EventHandler (invoker.Invoke);
501 static object PreRequestHandlerExecuteEvent = new object ();
502 public event EventHandler PreRequestHandlerExecute
504 add { AddEventHandler (PreRequestHandlerExecuteEvent, value); }
505 remove { RemoveEventHandler (PreRequestHandlerExecuteEvent, value); }
508 public void AddOnPreRequestHandlerExecuteAsync (BeginEventHandler bh, EndEventHandler eh)
510 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
511 PreRequestHandlerExecute += new EventHandler (invoker.Invoke);
514 static object ReleaseRequestStateEvent = new object ();
515 public event EventHandler ReleaseRequestState
517 add { AddEventHandler (ReleaseRequestStateEvent, value); }
518 remove { RemoveEventHandler (ReleaseRequestStateEvent, value); }
521 public void AddOnReleaseRequestStateAsync (BeginEventHandler bh, EndEventHandler eh)
523 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
524 ReleaseRequestState += new EventHandler (invoker.Invoke);
527 static object ResolveRequestCacheEvent = new object ();
528 public event EventHandler ResolveRequestCache
530 add { AddEventHandler (ResolveRequestCacheEvent, value); }
531 remove { RemoveEventHandler (ResolveRequestCacheEvent, value); }
534 public void AddOnResolveRequestCacheAsync (BeginEventHandler bh, EndEventHandler eh)
536 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
537 ResolveRequestCache += new EventHandler (invoker.Invoke);
540 static object UpdateRequestCacheEvent = new object ();
541 public event EventHandler UpdateRequestCache
543 add { AddEventHandler (UpdateRequestCacheEvent, value); }
544 remove { RemoveEventHandler (UpdateRequestCacheEvent, value); }
547 public void AddOnUpdateRequestCacheAsync (BeginEventHandler bh, EndEventHandler eh)
549 AsyncInvoker invoker = new AsyncInvoker (bh, eh);
550 UpdateRequestCache += new EventHandler (invoker.Invoke);
553 static object PostAuthenticateRequestEvent = new object ();
554 public event EventHandler PostAuthenticateRequest
556 add { AddEventHandler (PostAuthenticateRequestEvent, value); }
557 remove { RemoveEventHandler (PostAuthenticateRequestEvent, value); }
560 public void AddOnPostAuthenticateRequestAsync (BeginEventHandler bh, EndEventHandler eh)
562 AddOnPostAuthenticateRequestAsync (bh, eh, null);
565 public void AddOnPostAuthenticateRequestAsync (BeginEventHandler bh, EndEventHandler eh, object data)
567 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
568 PostAuthenticateRequest += new EventHandler (invoker.Invoke);
571 static object PostAuthorizeRequestEvent = new object ();
572 public event EventHandler PostAuthorizeRequest
574 add { AddEventHandler (PostAuthorizeRequestEvent, value); }
575 remove { RemoveEventHandler (PostAuthorizeRequestEvent, value); }
578 public void AddOnPostAuthorizeRequestAsync (BeginEventHandler bh, EndEventHandler eh)
580 AddOnPostAuthorizeRequestAsync (bh, eh, null);
583 public void AddOnPostAuthorizeRequestAsync (BeginEventHandler bh, EndEventHandler eh, object data)
585 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
586 PostAuthorizeRequest += new EventHandler (invoker.Invoke);
589 static object PostResolveRequestCacheEvent = new object ();
590 public event EventHandler PostResolveRequestCache
592 add { AddEventHandler (PostResolveRequestCacheEvent, value); }
593 remove { RemoveEventHandler (PostResolveRequestCacheEvent, value); }
596 public void AddOnPostResolveRequestCacheAsync (BeginEventHandler bh, EndEventHandler eh)
598 AddOnPostResolveRequestCacheAsync (bh, eh, null);
601 public void AddOnPostResolveRequestCacheAsync (BeginEventHandler bh, EndEventHandler eh, object data)
603 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
604 PostResolveRequestCache += new EventHandler (invoker.Invoke);
607 static object PostMapRequestHandlerEvent = new object ();
608 public event EventHandler PostMapRequestHandler
610 add { AddEventHandler (PostMapRequestHandlerEvent, value); }
611 remove { RemoveEventHandler (PostMapRequestHandlerEvent, value); }
614 public void AddOnPostMapRequestHandlerAsync (BeginEventHandler bh, EndEventHandler eh)
616 AddOnPostMapRequestHandlerAsync (bh, eh, null);
619 public void AddOnPostMapRequestHandlerAsync (BeginEventHandler bh, EndEventHandler eh, object data)
621 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
622 PostMapRequestHandler += new EventHandler (invoker.Invoke);
625 static object PostAcquireRequestStateEvent = new object ();
626 public event EventHandler PostAcquireRequestState
628 add { AddEventHandler (PostAcquireRequestStateEvent, value); }
629 remove { RemoveEventHandler (PostAcquireRequestStateEvent, value); }
632 public void AddOnPostAcquireRequestStateAsync (BeginEventHandler bh, EndEventHandler eh)
634 AddOnPostAcquireRequestStateAsync (bh, eh, null);
637 public void AddOnPostAcquireRequestStateAsync (BeginEventHandler bh, EndEventHandler eh, object data)
639 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
640 PostAcquireRequestState += new EventHandler (invoker.Invoke);
643 static object PostReleaseRequestStateEvent = new object ();
644 public event EventHandler PostReleaseRequestState
646 add { AddEventHandler (PostReleaseRequestStateEvent, value); }
647 remove { RemoveEventHandler (PostReleaseRequestStateEvent, value); }
650 public void AddOnPostReleaseRequestStateAsync (BeginEventHandler bh, EndEventHandler eh)
652 AddOnPostReleaseRequestStateAsync (bh, eh, null);
655 public void AddOnPostReleaseRequestStateAsync (BeginEventHandler bh, EndEventHandler eh, object data)
657 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
658 PostReleaseRequestState += new EventHandler (invoker.Invoke);
661 static object PostUpdateRequestCacheEvent = new object ();
662 public event EventHandler PostUpdateRequestCache
664 add { AddEventHandler (PostUpdateRequestCacheEvent, value); }
665 remove { RemoveEventHandler (PostUpdateRequestCacheEvent, value); }
668 public void AddOnPostUpdateRequestCacheAsync (BeginEventHandler bh, EndEventHandler eh)
670 AddOnPostUpdateRequestCacheAsync (bh, eh, null);
673 public void AddOnPostUpdateRequestCacheAsync (BeginEventHandler bh, EndEventHandler eh, object data)
675 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
676 PostUpdateRequestCache += new EventHandler (invoker.Invoke);
680 // The new overloads that take a data parameter
682 public void AddOnAcquireRequestStateAsync (BeginEventHandler bh, EndEventHandler eh, object data)
684 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
685 AcquireRequestState += new EventHandler (invoker.Invoke);
688 public void AddOnAuthenticateRequestAsync (BeginEventHandler bh, EndEventHandler eh, object data)
690 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
691 AuthenticateRequest += new EventHandler (invoker.Invoke);
694 public void AddOnAuthorizeRequestAsync (BeginEventHandler bh, EndEventHandler eh, object data)
696 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
697 AuthorizeRequest += new EventHandler (invoker.Invoke);
700 public void AddOnBeginRequestAsync (BeginEventHandler bh, EndEventHandler eh, object data)
702 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
703 BeginRequest += new EventHandler (invoker.Invoke);
706 public void AddOnEndRequestAsync (BeginEventHandler bh, EndEventHandler eh, object data)
708 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
709 EndRequest += new EventHandler (invoker.Invoke);
712 public void AddOnPostRequestHandlerExecuteAsync (BeginEventHandler bh, EndEventHandler eh, object data)
714 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
715 PostRequestHandlerExecute += new EventHandler (invoker.Invoke);
718 public void AddOnPreRequestHandlerExecuteAsync (BeginEventHandler bh, EndEventHandler eh, object data)
720 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
721 PreRequestHandlerExecute += new EventHandler (invoker.Invoke);
724 public void AddOnReleaseRequestStateAsync (BeginEventHandler bh, EndEventHandler eh, object data)
726 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
727 ReleaseRequestState += new EventHandler (invoker.Invoke);
730 public void AddOnResolveRequestCacheAsync (BeginEventHandler bh, EndEventHandler eh, object data)
732 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
733 ResolveRequestCache += new EventHandler (invoker.Invoke);
736 public void AddOnUpdateRequestCacheAsync (BeginEventHandler bh, EndEventHandler eh, object data)
738 AsyncInvoker invoker = new AsyncInvoker (bh, eh, data);
739 UpdateRequestCache += new EventHandler (invoker.Invoke);
743 // They are for use with the IIS7 integrated mode, but have been added for
745 static object LogRequestEvent = new object ();
746 public event EventHandler LogRequest
748 add { AddEventHandler (LogRequestEvent, value); }
749 remove { RemoveEventHandler (LogRequestEvent, value); }
752 public void AddOnLogRequestAsync (BeginEventHandler bh, EndEventHandler eh)
754 AddOnLogRequestAsync (bh, eh, null);
757 public void AddOnLogRequestAsync (BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
759 AsyncInvoker invoker = new AsyncInvoker (beginHandler, endHandler, state);
760 LogRequest += new EventHandler (invoker.Invoke);
763 static object MapRequestHandlerEvent = new object ();
764 public event EventHandler MapRequestHandler
766 add { AddEventHandler (MapRequestHandlerEvent, value); }
767 remove { RemoveEventHandler (MapRequestHandlerEvent, value); }
770 public void AddOnMapRequestHandlerAsync (BeginEventHandler bh, EndEventHandler eh)
772 AddOnMapRequestHandlerAsync (bh, eh, null);
775 public void AddOnMapRequestHandlerAsync (BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
777 AsyncInvoker invoker = new AsyncInvoker (beginHandler, endHandler, state);
778 MapRequestHandler += new EventHandler (invoker.Invoke);
781 static object PostLogRequestEvent = new object ();
782 public event EventHandler PostLogRequest
784 add { AddEventHandler (PostLogRequestEvent, value); }
785 remove { RemoveEventHandler (PostLogRequestEvent, value); }
788 public void AddOnPostLogRequestAsync (BeginEventHandler bh, EndEventHandler eh)
790 AddOnPostLogRequestAsync (bh, eh, null);
793 public void AddOnPostLogRequestAsync (BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
795 AsyncInvoker invoker = new AsyncInvoker (beginHandler, endHandler, state);
796 PostLogRequest += new EventHandler (invoker.Invoke);
799 internal event EventHandler DefaultAuthentication;
801 void AddEventHandler (object key, EventHandler handler)
803 if (fullInitComplete)
806 Events.AddHandler (key, handler);
809 void RemoveEventHandler (object key, EventHandler handler)
811 if (fullInitComplete)
814 Events.RemoveHandler (key, handler);
818 // Bypass all the event on the Http pipeline and go directly to EndRequest
820 public void CompleteRequest ()
822 stop_processing = true;
825 internal bool RequestCompleted {
826 set { stop_processing = value; }
829 internal void DisposeInternal ()
832 HttpModuleCollection coll = new HttpModuleCollection ();
833 Interlocked.Exchange (ref modcoll, coll);
835 for (int i = coll.Count - 1; i >= 0; i--) {
836 coll.Get (i).Dispose ();
841 EventHandler eh = nonApplicationEvents [disposedEvent] as EventHandler;
843 eh (this, EventArgs.Empty);
849 public virtual void Dispose ()
854 public virtual string GetOutputCacheProviderName (HttpContext context)
856 // LAMESPEC: doesn't throw ProviderException if context is null
857 return OutputCache.DefaultProviderName;
861 public virtual string GetVaryByCustomString (HttpContext context, string custom)
863 if (custom == null) // Sigh
864 throw new NullReferenceException ();
866 if (0 == String.Compare (custom, "browser", true, Helpers.InvariantCulture))
867 return context.Request.Browser.Type;
872 bool ShouldHandleException (Exception e)
874 if (e is ParseException)
881 // If we catch an error, queue this error
883 void ProcessError (Exception e)
885 bool first = context.Error == null;
886 context.AddError (e);
887 if (first && ShouldHandleException (e)) {
888 EventHandler eh = nonApplicationEvents [errorEvent] as EventHandler;
891 eh (this, EventArgs.Empty);
893 context.ClearError ();
894 } catch (ThreadAbortException taex){
895 context.ClearError ();
896 if (FlagEnd.Value == taex.ExceptionState || HttpRuntime.DomainUnloading)
897 // This happens on Redirect(), End() and
898 // when unloading the AppDomain
899 Thread.ResetAbort ();
901 // This happens on Thread.Abort()
902 context.AddError (taex);
903 } catch (Exception ee){
904 context.AddError (ee);
908 stop_processing = true;
910 // we want to remove configuration from the cache in case of
911 // invalid resource not exists to prevent DOS attack.
912 HttpException httpEx = e as HttpException;
913 if (httpEx != null && httpEx.GetHttpCode () == 404) {
914 removeConfigurationFromCache = true;
919 // Ticks the clock: next step on the pipeline.
921 internal void Tick ()
925 if (context.Error is UnifyRequestException) {
926 Exception ex = context.Error.InnerException;
927 context.ClearError ();
928 vmw.common.TypeUtils.Throw (ex);
932 if (pipeline.MoveNext ()){
933 if ((bool)pipeline.Current)
938 catch (Exception ex) {
939 if (ex is ThreadAbortException &&
940 ((ThreadAbortException) ex).ExceptionState == FlagEnd.Value)
942 if (context.WorkerRequest is IHttpUnifyWorkerRequest) {
943 context.ClearError ();
944 context.AddError (new UnifyRequestException (ex));
951 } catch (ThreadAbortException taex) {
952 object obj = taex.ExceptionState;
953 Thread.ResetAbort ();
954 if (obj is StepTimeout)
955 ProcessError (HttpException.NewWithCode ("The request timed out.", WebEventCodes.RequestTransactionAbort));
957 context.ClearError ();
958 if (FlagEnd.Value != obj && !HttpRuntime.DomainUnloading)
959 context.AddError (taex);
962 stop_processing = true;
964 } catch (Exception e) {
965 ThreadAbortException inner = e.InnerException as ThreadAbortException;
966 if (inner != null && FlagEnd.Value == inner.ExceptionState && !HttpRuntime.DomainUnloading) {
967 context.ClearError ();
968 Thread.ResetAbort ();
972 stop_processing = true;
986 // Invoked when our async callback called from RunHooks completes,
987 // we restart the pipeline here.
989 void async_callback_completed_cb (IAsyncResult ar)
991 if (current_ai.end != null){
994 } catch (Exception e) {
1002 void async_handler_complete_cb (IAsyncResult ar)
1004 IHttpAsyncHandler async_handler = ar != null ? ar.AsyncState as IHttpAsyncHandler : null;
1007 if (async_handler != null)
1008 async_handler.EndProcessRequest (ar);
1009 } catch (Exception e){
1017 // This enumerator yields whether processing must be stopped:
1018 // true: processing of the pipeline must be stopped
1019 // false: processing of the pipeline must not be stopped
1021 IEnumerable RunHooks (Delegate list)
1023 Delegate [] delegates = list.GetInvocationList ();
1025 foreach (EventHandler d in delegates){
1026 if (d.Target != null && (d.Target is AsyncInvoker)){
1027 current_ai = (AsyncInvoker) d.Target;
1032 context.BeginTimeoutPossible ();
1033 current_ai.begin (this, EventArgs.Empty, async_callback_completed_cb, current_ai.data);
1036 context.EndTimeoutPossible ();
1040 // If things are still moving forward, yield this
1044 yield return stop_processing;
1045 else if (stop_processing)
1049 context.BeginTimeoutPossible ();
1050 d (this, EventArgs.Empty);
1052 context.EndTimeoutPossible ();
1054 if (stop_processing)
1060 static void FinalErrorWrite (HttpResponse response, string error)
1063 response.Write (error);
1064 response.Flush (true);
1072 if (context.Error == null){
1074 context.Response.Flush (true);
1075 } catch (Exception e){
1076 context.AddError (e);
1080 Exception error = context.Error;
1082 HttpResponse response = context.Response;
1084 if (!response.HeadersSent){
1085 response.ClearHeaders ();
1086 response.ClearContent ();
1088 if (error is HttpException){
1089 response.StatusCode = ((HttpException)error).GetHttpCode ();
1091 error = HttpException.NewWithCode (String.Empty, error, WebEventCodes.WebErrorOtherError);
1092 response.StatusCode = 500;
1094 HttpException httpEx = (HttpException) error;
1095 if (!RedirectCustomError (ref httpEx))
1096 FinalErrorWrite (response, httpEx.GetHtmlErrorMessage ());
1098 response.Flush (true);
1100 if (!(error is HttpException))
1101 error = HttpException.NewWithCode (String.Empty, error, WebEventCodes.WebErrorOtherError);
1102 FinalErrorWrite (response, ((HttpException) error).GetHtmlErrorMessage ());
1109 // Invoked at the end of the pipeline execution
1111 void PipelineDone ()
1114 EventHandler handler = Events [EndRequestEvent] as EventHandler;
1115 if (handler != null)
1116 handler (this, EventArgs.Empty);
1117 } catch (Exception e){
1123 } catch (ThreadAbortException taex) {
1124 ProcessError (taex);
1125 Thread.ResetAbort ();
1126 } catch (Exception e) {
1127 Console.WriteLine ("Internal error: OutputPage threw an exception " + e);
1129 context.WorkerRequest.EndOfRequest();
1130 if (factory != null && context.Handler != null){
1131 factory.ReleaseHandler (context.Handler);
1132 context.Handler = null;
1135 context.PopHandler ();
1137 // context = null; -> moved to PostDone
1143 if (begin_iar != null)
1144 begin_iar.Complete ();
1148 requests_total_counter.Increment ();
1158 public Tim (string name) {
1162 public string Name {
1163 get { return name; }
1164 set { name = value; }
1167 public void Start () {
1168 start = DateTime.UtcNow;
1171 public void Stop () {
1172 Console.WriteLine ("{0}: {1}ms", name, (DateTime.UtcNow - start).TotalMilliseconds);
1177 [Conditional ("PIPELINE_TIMER")]
1178 void StartTimer (string name)
1186 [Conditional ("PIPELINE_TIMER")]
1193 // Events fired as described in `Http Runtime Support, HttpModules,
1194 // Handling Public Events'
1196 IEnumerator Pipeline ()
1198 Delegate eventHandler;
1199 if (stop_processing)
1202 HttpRequest req = context.Request;
1206 context.MapRequestHandlerDone = false;
1207 StartTimer ("BeginRequest");
1208 eventHandler = Events [BeginRequestEvent];
1209 if (eventHandler != null) {
1210 foreach (bool stop in RunHooks (eventHandler))
1215 StartTimer ("AuthenticateRequest");
1216 eventHandler = Events [AuthenticateRequestEvent];
1217 if (eventHandler != null)
1218 foreach (bool stop in RunHooks (eventHandler))
1222 StartTimer ("DefaultAuthentication");
1223 if (DefaultAuthentication != null)
1224 foreach (bool stop in RunHooks (DefaultAuthentication))
1228 StartTimer ("PostAuthenticateRequest");
1229 eventHandler = Events [PostAuthenticateRequestEvent];
1230 if (eventHandler != null)
1231 foreach (bool stop in RunHooks (eventHandler))
1235 StartTimer ("AuthorizeRequest");
1236 eventHandler = Events [AuthorizeRequestEvent];
1237 if (eventHandler != null)
1238 foreach (bool stop in RunHooks (eventHandler))
1242 StartTimer ("PostAuthorizeRequest");
1243 eventHandler = Events [PostAuthorizeRequestEvent];
1244 if (eventHandler != null)
1245 foreach (bool stop in RunHooks (eventHandler))
1249 StartTimer ("ResolveRequestCache");
1250 eventHandler = Events [ResolveRequestCacheEvent];
1251 if (eventHandler != null)
1252 foreach (bool stop in RunHooks (eventHandler))
1256 StartTimer ("PostResolveRequestCache");
1257 eventHandler = Events [PostResolveRequestCacheEvent];
1258 if (eventHandler != null)
1259 foreach (bool stop in RunHooks (eventHandler))
1263 StartTimer ("MapRequestHandler");
1264 // As per http://msdn2.microsoft.com/en-us/library/bb470252(VS.90).aspx
1265 eventHandler = Events [MapRequestHandlerEvent];
1266 if (eventHandler != null)
1267 foreach (bool stop in RunHooks (eventHandler))
1270 context.MapRequestHandlerDone = true;
1272 StartTimer ("GetHandler");
1273 // Obtain the handler for the request.
1274 IHttpHandler handler = null;
1276 handler = GetHandler (context, context.Request.CurrentExecutionFilePath);
1277 context.Handler = handler;
1278 context.PushHandler (handler);
1279 } catch (FileNotFoundException fnf){
1281 Console.WriteLine ("$$$$$$$$$$:Sys.Web Pipeline");
1282 Console.WriteLine (fnf.ToString ());
1284 if (context.Request.IsLocal)
1285 ProcessError (HttpException.NewWithCode (404,
1286 String.Format ("File not found {0}", fnf.FileName),
1288 context.Request.FilePath,
1289 WebEventCodes.RuntimeErrorRequestAbort));
1291 ProcessError (HttpException.NewWithCode (404,
1292 "File not found: " + Path.GetFileName (fnf.FileName),
1293 context.Request.FilePath,
1294 WebEventCodes.RuntimeErrorRequestAbort));
1295 } catch (DirectoryNotFoundException dnf){
1296 if (!context.Request.IsLocal)
1297 dnf = null; // Do not "leak" real path information
1298 ProcessError (HttpException.NewWithCode (404, "Directory not found", dnf, WebEventCodes.RuntimeErrorRequestAbort));
1299 } catch (Exception e) {
1304 if (stop_processing)
1307 StartTimer ("PostMapRequestHandler");
1308 eventHandler = Events [PostMapRequestHandlerEvent];
1309 if (eventHandler != null)
1310 foreach (bool stop in RunHooks (eventHandler))
1314 StartTimer ("AcquireRequestState");
1315 eventHandler = Events [AcquireRequestStateEvent];
1316 if (eventHandler != null){
1317 foreach (bool stop in RunHooks (eventHandler))
1322 StartTimer ("PostAcquireRequestState");
1323 eventHandler = Events [PostAcquireRequestStateEvent];
1324 if (eventHandler != null){
1325 foreach (bool stop in RunHooks (eventHandler))
1331 // From this point on, we need to ensure that we call
1332 // ReleaseRequestState, so the code below jumps to
1333 // `release:' to guarantee it rather than yielding.
1335 StartTimer ("PreRequestHandlerExecute");
1336 eventHandler = Events [PreRequestHandlerExecuteEvent];
1337 if (eventHandler != null)
1338 foreach (bool stop in RunHooks (eventHandler))
1346 bool doProcessHandler = false;
1349 IHttpHandler ctxHandler = context.Handler;
1350 if (ctxHandler != null && handler != ctxHandler) {
1351 context.PopHandler ();
1352 handler = ctxHandler;
1353 context.PushHandler (handler);
1356 StartTimer ("ProcessRequest");
1358 context.BeginTimeoutPossible ();
1359 if (handler != null){
1360 IHttpAsyncHandler async_handler = handler as IHttpAsyncHandler;
1362 if (async_handler != null){
1365 async_handler.BeginProcessRequest (context, async_handler_complete_cb, handler);
1368 handler.ProcessRequest (context);
1370 IHttpExtendedHandler extHandler=handler as IHttpExtendedHandler;
1371 doProcessHandler = extHandler != null && !extHandler.IsCompleted;
1375 throw new InvalidOperationException ("No handler for the current request.");
1376 if (context.Error != null)
1377 throw new TargetInvocationException(context.Error);
1380 context.EndTimeoutPossible ();
1384 if (doProcessHandler) {
1386 goto processHandler;
1390 yield return stop_processing;
1391 else if (stop_processing)
1394 // These are executed after the application has returned
1396 StartTimer ("PostRequestHandlerExecute");
1397 eventHandler = Events [PostRequestHandlerExecuteEvent];
1398 if (eventHandler != null)
1399 foreach (bool stop in RunHooks (eventHandler))
1405 StartTimer ("ReleaseRequestState");
1406 eventHandler = Events [ReleaseRequestStateEvent];
1407 if (eventHandler != null){
1408 #pragma warning disable 219
1409 foreach (bool stop in RunHooks (eventHandler)) {
1411 // Ignore the stop signal while release the state
1415 #pragma warning restore 219
1419 if (stop_processing)
1422 StartTimer ("PostReleaseRequestState");
1423 eventHandler = Events [PostReleaseRequestStateEvent];
1424 if (eventHandler != null)
1425 foreach (bool stop in RunHooks (eventHandler))
1429 StartTimer ("Filter");
1430 if (context.Error == null)
1431 context.Response.DoFilter (true);
1434 StartTimer ("UpdateRequestCache");
1435 eventHandler = Events [UpdateRequestCacheEvent];
1436 if (eventHandler != null)
1437 foreach (bool stop in RunHooks (eventHandler))
1441 StartTimer ("PostUpdateRequestCache");
1442 eventHandler = Events [PostUpdateRequestCacheEvent];
1443 if (eventHandler != null)
1444 foreach (bool stop in RunHooks (eventHandler))
1448 StartTimer ("LogRequest");
1449 eventHandler = Events [LogRequestEvent];
1450 if (eventHandler != null)
1451 foreach (bool stop in RunHooks (eventHandler))
1455 StartTimer ("PostLogRequest");
1456 eventHandler = Events [PostLogRequestEvent];
1457 if (eventHandler != null)
1458 foreach (bool stop in RunHooks (eventHandler))
1462 StartTimer ("PipelineDone");
1468 internal CultureInfo GetThreadCulture (HttpRequest request, CultureInfo culture, bool isAuto)
1472 CultureInfo ret = null;
1473 string[] languages = request.UserLanguages;
1475 if (languages != null && languages.Length > 0)
1476 ret = CultureInfo.CreateSpecificCulture (languages[0]);
1489 GlobalizationSection cfg;
1490 cfg = (GlobalizationSection) WebConfigurationManager.GetSection ("system.web/globalization");
1491 app_culture = cfg.GetCulture ();
1492 autoCulture = cfg.IsAutoCulture;
1493 appui_culture = cfg.GetUICulture ();
1494 autoUICulture = cfg.IsAutoUICulture;
1496 context.StartTimeoutTimer ();
1498 Thread th = Thread.CurrentThread;
1499 if (app_culture != null) {
1500 prev_app_culture = th.CurrentCulture;
1501 CultureInfo new_app_culture = GetThreadCulture (Request, app_culture, autoCulture);
1502 if (!new_app_culture.Equals (Helpers.InvariantCulture))
1503 th.CurrentCulture = new_app_culture;
1506 if (appui_culture != null) {
1507 prev_appui_culture = th.CurrentUICulture;
1508 CultureInfo new_app_culture = GetThreadCulture (Request, appui_culture, autoUICulture);
1509 if (!new_app_culture.Equals (Helpers.InvariantCulture))
1510 th.CurrentUICulture = new_app_culture;
1514 prev_user = Thread.CurrentPrincipal;
1520 if (removeConfigurationFromCache) {
1521 WebConfigurationManager.RemoveConfigurationFromCache (context);
1522 removeConfigurationFromCache = false;
1525 Thread th = Thread.CurrentThread;
1527 if (Thread.CurrentPrincipal != prev_user)
1528 Thread.CurrentPrincipal = prev_user;
1530 if (prev_appui_culture != null && prev_appui_culture != th.CurrentUICulture)
1531 th.CurrentUICulture = prev_appui_culture;
1532 if (prev_app_culture != null && prev_app_culture != th.CurrentCulture)
1533 th.CurrentCulture = prev_app_culture;
1536 if (context == null)
1537 context = HttpContext.Current;
1538 context.StopTimeoutTimer ();
1540 context.Request.ReleaseResources ();
1541 context.Response.ReleaseResources ();
1544 HttpContext.Current = null;
1547 void Start (object x)
1549 var cultures = x as CultureInfo [];
1550 if (cultures != null && cultures.Length == 2) {
1551 Thread ct = Thread.CurrentThread;
1552 ct.CurrentCulture = cultures [0];
1553 ct.CurrentUICulture = cultures [1];
1557 if (initialization_exception != null) {
1558 Exception e = initialization_exception;
1559 HttpException exc = HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort);
1560 FinalErrorWrite (context.Response, exc.GetHtmlErrorMessage ());
1565 HttpContext.Current = Context;
1567 pipeline = Pipeline ();
1571 const string HANDLER_CACHE = "@@HttpHandlerCache@@";
1573 internal static Hashtable GetHandlerCache ()
1575 Cache cache = HttpRuntime.InternalCache;
1576 Hashtable ret = cache [HANDLER_CACHE] as Hashtable;
1579 ret = new Hashtable ();
1580 cache.Insert (HANDLER_CACHE, ret);
1586 internal static void ClearHandlerCache ()
1588 Hashtable cache = GetHandlerCache ();
1592 object LocateHandler (HttpRequest req, string verb, string url)
1594 Hashtable cache = GetHandlerCache ();
1595 string id = String.Concat (verb, url);
1596 object ret = cache [id];
1602 HttpHandlersSection httpHandlersSection = WebConfigurationManager.GetSection ("system.web/httpHandlers", req.Path, req.Context) as HttpHandlersSection;
1603 ret = httpHandlersSection.LocateHandler (verb, url, out allowCache);
1605 IHttpHandler handler = ret as IHttpHandler;
1606 if (allowCache && handler != null && handler.IsReusable)
1612 internal IHttpHandler GetHandler (HttpContext context, string url)
1614 return GetHandler (context, url, false);
1617 // Used by HttpServerUtility.Execute
1618 internal IHttpHandler GetHandler (HttpContext context, string url, bool ignoreContextHandler)
1620 if (!ignoreContextHandler && context.Handler != null)
1621 return context.Handler;
1623 HttpRequest request = context.Request;
1624 string verb = request.RequestType;
1626 IHttpHandler handler = null;
1627 object o = LocateHandler (request, verb, url);
1629 factory = o as IHttpHandlerFactory;
1630 if (factory == null) {
1631 handler = (IHttpHandler) o;
1633 handler = factory.GetHandler (context, verb, url, request.MapPath (url));
1639 void IHttpHandler.ProcessRequest (HttpContext context)
1642 this.context = context;
1650 // This is used by FireOnAppStart, when we init the application
1651 // as the context is required to be set at that point (the user
1652 // might call methods that require it on that hook).
1654 internal void SetContext (HttpContext context)
1656 this.context = context;
1659 internal void SetSession (HttpSessionState session)
1661 this.session = session;
1664 IAsyncResult IHttpAsyncHandler.BeginProcessRequest (HttpContext context, AsyncCallback cb, object extraData)
1666 this.context = context;
1669 begin_iar = new AsyncRequestState (done, cb, extraData);
1671 CultureInfo[] cultures = new CultureInfo [2];
1672 cultures [0] = Thread.CurrentThread.CurrentCulture;
1673 cultures [1] = Thread.CurrentThread.CurrentUICulture;
1678 if (Thread.CurrentThread.IsThreadPoolThread)
1682 ThreadPool.QueueUserWorkItem (x => {
1685 } catch (Exception e) {
1686 Console.Error.WriteLine (e);
1693 void IHttpAsyncHandler.EndProcessRequest (IAsyncResult result)
1699 if (!result.IsCompleted)
1700 result.AsyncWaitHandle.WaitOne ();
1704 public virtual void Init ()
1708 bool IHttpHandler.IsReusable {
1715 internal void ClearError ()
1717 context.ClearError ();
1720 bool RedirectErrorPage (string error_page)
1722 if (context.Request.QueryString ["aspxerrorpath"] != null)
1725 Response.Redirect (error_page + "?aspxerrorpath=" + Request.Path, false);
1729 bool RedirectCustomError (ref HttpException httpEx)
1732 if (!context.IsCustomErrorEnabledUnsafe)
1735 CustomErrorsSection config = (CustomErrorsSection)WebConfigurationManager.GetSection ("system.web/customErrors");
1736 if (config == null) {
1737 if (context.ErrorPage != null)
1738 return RedirectErrorPage (context.ErrorPage);
1743 CustomError err = config.Errors [context.Response.StatusCode.ToString()];
1744 string redirect = err == null ? null : err.Redirect;
1745 if (redirect == null) {
1746 redirect = context.ErrorPage;
1747 if (redirect == null)
1748 redirect = config.DefaultRedirect;
1751 if (redirect == null)
1754 if (config.RedirectMode == CustomErrorsRedirectMode.ResponseRewrite) {
1755 context.Server.Execute (redirect);
1759 return RedirectErrorPage (redirect);
1761 catch (Exception ex) {
1762 httpEx = HttpException.NewWithCode (500, String.Empty, ex, WebEventCodes.WebErrorOtherError);
1767 internal static string BinDirectory
1770 if (binDirectory == null) {
1771 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
1772 string baseDir = setup.ApplicationBase;
1775 foreach (string dir in BinDirs) {
1776 bindir = Path.Combine (baseDir, dir);
1777 if (!Directory.Exists (bindir))
1779 binDirectory = bindir;
1784 return binDirectory;
1788 internal static string[] BinDirectoryAssemblies
1791 ArrayList binDlls = null;
1794 string bindir = BinDirectory;
1795 if (bindir != null) {
1796 binDlls = new ArrayList ();
1797 dlls = Directory.GetFiles (bindir, "*.dll");
1798 binDlls.AddRange (dlls);
1801 if (binDlls == null)
1802 return new string[] {};
1804 return (string[]) binDlls.ToArray (typeof (string));
1808 internal static Type LoadType (string typeName)
1810 return LoadType (typeName, false);
1813 internal static Type LoadType (string typeName, bool throwOnMissing)
1815 Type type = Type.GetType (typeName);
1820 Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
1821 foreach (Assembly ass in assemblies) {
1822 type = ass.GetType (typeName, false);
1827 IList tla = System.Web.Compilation.BuildManager.TopLevelAssemblies;
1828 if (tla != null && tla.Count > 0) {
1829 foreach (Assembly asm in tla) {
1832 type = asm.GetType (typeName, false);
1838 Exception loadException = null;
1841 type = LoadTypeFromBin (typeName);
1842 } catch (Exception ex) {
1850 throw new TypeLoadException (String.Format ("Type '{0}' cannot be found", typeName), loadException);
1855 internal static Type LoadType <TBaseType> (string typeName, bool throwOnMissing)
1857 Type ret = LoadType (typeName, throwOnMissing);
1859 if (typeof (TBaseType).IsAssignableFrom (ret))
1863 throw new TypeLoadException (String.Format ("Type '{0}' found but it doesn't derive from base type '{1}'.", typeName, typeof (TBaseType)));
1868 internal static Type LoadTypeFromBin (string typeName)
1872 foreach (string s in BinDirectoryAssemblies) {
1873 Assembly binA = null;
1876 binA = Assembly.LoadFrom (s);
1877 } catch (FileLoadException) {
1880 } catch (BadImageFormatException) {
1885 type = binA.GetType (typeName, false);
1897 // Based on Fritz' Onion's AsyncRequestState class for asynchronous IHttpAsyncHandlers
1899 class AsyncRequestState : IAsyncResult {
1903 ManualResetEvent complete_event = null;
1905 internal AsyncRequestState (ManualResetEvent complete_event, AsyncCallback cb, object cb_data)
1908 this.cb_data = cb_data;
1909 this.complete_event = complete_event;
1912 internal void Complete ()
1917 // TODO: if this throws an error, we have no way of reporting it
1918 // Not really too bad, since the only failure might be
1919 // `HttpRuntime.request_processed'.
1926 complete_event.Set ();
1929 public object AsyncState {
1935 public bool CompletedSynchronously {
1941 public bool IsCompleted {
1947 public WaitHandle AsyncWaitHandle {
1949 return complete_event;
1954 #region Helper classes
1957 // A wrapper to keep track of begin/end pairs
1959 class AsyncInvoker {
1960 public BeginEventHandler begin;
1961 public EndEventHandler end;
1964 public AsyncInvoker (BeginEventHandler bh, EndEventHandler eh, object d)
1971 public AsyncInvoker (BeginEventHandler bh, EndEventHandler eh)
1977 public void Invoke (object sender, EventArgs e)
1979 throw new Exception ("This is just a dummy");