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){
1280 if (context.Request.IsLocal)
1281 ProcessError (HttpException.NewWithCode (404,
1282 String.Format ("File not found {0}", fnf.FileName),
1284 context.Request.FilePath,
1285 WebEventCodes.RuntimeErrorRequestAbort));
1287 ProcessError (HttpException.NewWithCode (404,
1288 "File not found: " + Path.GetFileName (fnf.FileName),
1289 context.Request.FilePath,
1290 WebEventCodes.RuntimeErrorRequestAbort));
1291 } catch (DirectoryNotFoundException dnf){
1292 if (!context.Request.IsLocal)
1293 dnf = null; // Do not "leak" real path information
1294 ProcessError (HttpException.NewWithCode (404, "Directory not found", dnf, WebEventCodes.RuntimeErrorRequestAbort));
1295 } catch (Exception e) {
1300 if (stop_processing)
1303 StartTimer ("PostMapRequestHandler");
1304 eventHandler = Events [PostMapRequestHandlerEvent];
1305 if (eventHandler != null)
1306 foreach (bool stop in RunHooks (eventHandler))
1310 StartTimer ("AcquireRequestState");
1311 eventHandler = Events [AcquireRequestStateEvent];
1312 if (eventHandler != null){
1313 foreach (bool stop in RunHooks (eventHandler))
1318 StartTimer ("PostAcquireRequestState");
1319 eventHandler = Events [PostAcquireRequestStateEvent];
1320 if (eventHandler != null){
1321 foreach (bool stop in RunHooks (eventHandler))
1327 // From this point on, we need to ensure that we call
1328 // ReleaseRequestState, so the code below jumps to
1329 // `release:' to guarantee it rather than yielding.
1331 StartTimer ("PreRequestHandlerExecute");
1332 eventHandler = Events [PreRequestHandlerExecuteEvent];
1333 if (eventHandler != null)
1334 foreach (bool stop in RunHooks (eventHandler))
1342 bool doProcessHandler = false;
1345 IHttpHandler ctxHandler = context.Handler;
1346 if (ctxHandler != null && handler != ctxHandler) {
1347 context.PopHandler ();
1348 handler = ctxHandler;
1349 context.PushHandler (handler);
1352 StartTimer ("ProcessRequest");
1354 context.BeginTimeoutPossible ();
1355 if (handler != null){
1356 IHttpAsyncHandler async_handler = handler as IHttpAsyncHandler;
1358 if (async_handler != null){
1361 async_handler.BeginProcessRequest (context, async_handler_complete_cb, handler);
1364 handler.ProcessRequest (context);
1366 IHttpExtendedHandler extHandler=handler as IHttpExtendedHandler;
1367 doProcessHandler = extHandler != null && !extHandler.IsCompleted;
1371 throw new InvalidOperationException ("No handler for the current request.");
1372 if (context.Error != null)
1373 throw new TargetInvocationException(context.Error);
1376 context.EndTimeoutPossible ();
1380 if (doProcessHandler) {
1382 goto processHandler;
1386 yield return stop_processing;
1387 else if (stop_processing)
1390 // These are executed after the application has returned
1392 StartTimer ("PostRequestHandlerExecute");
1393 eventHandler = Events [PostRequestHandlerExecuteEvent];
1394 if (eventHandler != null)
1395 foreach (bool stop in RunHooks (eventHandler))
1401 StartTimer ("ReleaseRequestState");
1402 eventHandler = Events [ReleaseRequestStateEvent];
1403 if (eventHandler != null){
1404 #pragma warning disable 219
1405 foreach (bool stop in RunHooks (eventHandler)) {
1407 // Ignore the stop signal while release the state
1411 #pragma warning restore 219
1415 if (stop_processing)
1418 StartTimer ("PostReleaseRequestState");
1419 eventHandler = Events [PostReleaseRequestStateEvent];
1420 if (eventHandler != null)
1421 foreach (bool stop in RunHooks (eventHandler))
1425 StartTimer ("Filter");
1426 if (context.Error == null)
1427 context.Response.DoFilter (true);
1430 StartTimer ("UpdateRequestCache");
1431 eventHandler = Events [UpdateRequestCacheEvent];
1432 if (eventHandler != null)
1433 foreach (bool stop in RunHooks (eventHandler))
1437 StartTimer ("PostUpdateRequestCache");
1438 eventHandler = Events [PostUpdateRequestCacheEvent];
1439 if (eventHandler != null)
1440 foreach (bool stop in RunHooks (eventHandler))
1444 StartTimer ("LogRequest");
1445 eventHandler = Events [LogRequestEvent];
1446 if (eventHandler != null)
1447 foreach (bool stop in RunHooks (eventHandler))
1451 StartTimer ("PostLogRequest");
1452 eventHandler = Events [PostLogRequestEvent];
1453 if (eventHandler != null)
1454 foreach (bool stop in RunHooks (eventHandler))
1458 StartTimer ("PipelineDone");
1464 internal CultureInfo GetThreadCulture (HttpRequest request, CultureInfo culture, bool isAuto)
1468 CultureInfo ret = null;
1469 string[] languages = request.UserLanguages;
1471 if (languages != null && languages.Length > 0)
1472 ret = CultureInfo.CreateSpecificCulture (languages[0]);
1485 GlobalizationSection cfg;
1486 cfg = (GlobalizationSection) WebConfigurationManager.GetSection ("system.web/globalization");
1487 app_culture = cfg.GetCulture ();
1488 autoCulture = cfg.IsAutoCulture;
1489 appui_culture = cfg.GetUICulture ();
1490 autoUICulture = cfg.IsAutoUICulture;
1492 context.StartTimeoutTimer ();
1494 Thread th = Thread.CurrentThread;
1495 if (app_culture != null) {
1496 prev_app_culture = th.CurrentCulture;
1497 CultureInfo new_app_culture = GetThreadCulture (Request, app_culture, autoCulture);
1498 if (!new_app_culture.Equals (Helpers.InvariantCulture))
1499 th.CurrentCulture = new_app_culture;
1502 if (appui_culture != null) {
1503 prev_appui_culture = th.CurrentUICulture;
1504 CultureInfo new_app_culture = GetThreadCulture (Request, appui_culture, autoUICulture);
1505 if (!new_app_culture.Equals (Helpers.InvariantCulture))
1506 th.CurrentUICulture = new_app_culture;
1509 prev_user = Thread.CurrentPrincipal;
1514 if (removeConfigurationFromCache) {
1515 WebConfigurationManager.RemoveConfigurationFromCache (context);
1516 removeConfigurationFromCache = false;
1519 Thread th = Thread.CurrentThread;
1520 if (Thread.CurrentPrincipal != prev_user)
1521 Thread.CurrentPrincipal = prev_user;
1522 if (prev_appui_culture != null && prev_appui_culture != th.CurrentUICulture)
1523 th.CurrentUICulture = prev_appui_culture;
1524 if (prev_app_culture != null && prev_app_culture != th.CurrentCulture)
1525 th.CurrentCulture = prev_app_culture;
1528 if (context == null)
1529 context = HttpContext.Current;
1530 context.StopTimeoutTimer ();
1532 context.Request.ReleaseResources ();
1533 context.Response.ReleaseResources ();
1536 HttpContext.Current = null;
1539 void Start (object x)
1541 var cultures = x as CultureInfo [];
1542 if (cultures != null && cultures.Length == 2) {
1543 Thread ct = Thread.CurrentThread;
1544 ct.CurrentCulture = cultures [0];
1545 ct.CurrentUICulture = cultures [1];
1549 if (initialization_exception != null) {
1550 Exception e = initialization_exception;
1551 HttpException exc = HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort);
1552 FinalErrorWrite (context.Response, exc.GetHtmlErrorMessage ());
1557 HttpContext.Current = Context;
1559 pipeline = Pipeline ();
1563 const string HANDLER_CACHE = "@@HttpHandlerCache@@";
1565 internal static Hashtable GetHandlerCache ()
1567 Cache cache = HttpRuntime.InternalCache;
1568 Hashtable ret = cache [HANDLER_CACHE] as Hashtable;
1571 ret = new Hashtable ();
1572 cache.Insert (HANDLER_CACHE, ret);
1578 internal static void ClearHandlerCache ()
1580 Hashtable cache = GetHandlerCache ();
1584 object LocateHandler (HttpRequest req, string verb, string url)
1586 Hashtable cache = GetHandlerCache ();
1587 string id = String.Concat (verb, url);
1588 object ret = cache [id];
1594 HttpHandlersSection httpHandlersSection = WebConfigurationManager.GetSection ("system.web/httpHandlers", req.Path, req.Context) as HttpHandlersSection;
1595 ret = httpHandlersSection.LocateHandler (verb, url, out allowCache);
1597 IHttpHandler handler = ret as IHttpHandler;
1598 if (allowCache && handler != null && handler.IsReusable)
1604 internal IHttpHandler GetHandler (HttpContext context, string url)
1606 return GetHandler (context, url, false);
1609 // Used by HttpServerUtility.Execute
1610 internal IHttpHandler GetHandler (HttpContext context, string url, bool ignoreContextHandler)
1612 if (!ignoreContextHandler && context.Handler != null)
1613 return context.Handler;
1615 HttpRequest request = context.Request;
1616 string verb = request.RequestType;
1618 IHttpHandler handler = null;
1619 object o = LocateHandler (request, verb, url);
1621 factory = o as IHttpHandlerFactory;
1622 if (factory == null) {
1623 handler = (IHttpHandler) o;
1625 handler = factory.GetHandler (context, verb, url, request.MapPath (url));
1631 void IHttpHandler.ProcessRequest (HttpContext context)
1634 this.context = context;
1642 // This is used by FireOnAppStart, when we init the application
1643 // as the context is required to be set at that point (the user
1644 // might call methods that require it on that hook).
1646 internal void SetContext (HttpContext context)
1648 this.context = context;
1651 internal void SetSession (HttpSessionState session)
1653 this.session = session;
1656 IAsyncResult IHttpAsyncHandler.BeginProcessRequest (HttpContext context, AsyncCallback cb, object extraData)
1658 this.context = context;
1661 begin_iar = new AsyncRequestState (done, cb, extraData);
1663 CultureInfo[] cultures = new CultureInfo [2];
1664 cultures [0] = Thread.CurrentThread.CurrentCulture;
1665 cultures [1] = Thread.CurrentThread.CurrentUICulture;
1667 if (Thread.CurrentThread.IsThreadPoolThread)
1670 ThreadPool.QueueUserWorkItem (x => {
1673 } catch (Exception e) {
1674 Console.Error.WriteLine (e);
1681 void IHttpAsyncHandler.EndProcessRequest (IAsyncResult result)
1687 if (!result.IsCompleted)
1688 result.AsyncWaitHandle.WaitOne ();
1692 public virtual void Init ()
1696 bool IHttpHandler.IsReusable {
1703 internal void ClearError ()
1705 context.ClearError ();
1708 bool RedirectErrorPage (string error_page)
1710 if (context.Request.QueryString ["aspxerrorpath"] != null)
1713 Response.Redirect (error_page + "?aspxerrorpath=" + Request.Path, false);
1717 bool RedirectCustomError (ref HttpException httpEx)
1720 if (!context.IsCustomErrorEnabledUnsafe)
1723 CustomErrorsSection config = (CustomErrorsSection)WebConfigurationManager.GetSection ("system.web/customErrors");
1724 if (config == null) {
1725 if (context.ErrorPage != null)
1726 return RedirectErrorPage (context.ErrorPage);
1731 CustomError err = config.Errors [context.Response.StatusCode.ToString()];
1732 string redirect = err == null ? null : err.Redirect;
1733 if (redirect == null) {
1734 redirect = context.ErrorPage;
1735 if (redirect == null)
1736 redirect = config.DefaultRedirect;
1739 if (redirect == null)
1742 if (config.RedirectMode == CustomErrorsRedirectMode.ResponseRewrite) {
1743 context.Server.Execute (redirect);
1747 return RedirectErrorPage (redirect);
1749 catch (Exception ex) {
1750 httpEx = HttpException.NewWithCode (500, String.Empty, ex, WebEventCodes.WebErrorOtherError);
1755 internal static string BinDirectory
1758 if (binDirectory == null) {
1759 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
1760 string baseDir = setup.ApplicationBase;
1763 foreach (string dir in BinDirs) {
1764 bindir = Path.Combine (baseDir, dir);
1765 if (!Directory.Exists (bindir))
1767 binDirectory = bindir;
1772 return binDirectory;
1776 internal static string[] BinDirectoryAssemblies
1779 ArrayList binDlls = null;
1782 string bindir = BinDirectory;
1783 if (bindir != null) {
1784 binDlls = new ArrayList ();
1785 dlls = Directory.GetFiles (bindir, "*.dll");
1786 binDlls.AddRange (dlls);
1789 if (binDlls == null)
1790 return new string[] {};
1792 return (string[]) binDlls.ToArray (typeof (string));
1796 internal static Type LoadType (string typeName)
1798 return LoadType (typeName, false);
1801 internal static Type LoadType (string typeName, bool throwOnMissing)
1803 Type type = Type.GetType (typeName);
1807 Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
1808 foreach (Assembly ass in assemblies) {
1809 type = ass.GetType (typeName, false);
1814 IList tla = System.Web.Compilation.BuildManager.TopLevelAssemblies;
1815 if (tla != null && tla.Count > 0) {
1816 foreach (Assembly asm in tla) {
1819 type = asm.GetType (typeName, false);
1825 Exception loadException = null;
1828 type = LoadTypeFromBin (typeName);
1829 } catch (Exception ex) {
1836 throw new TypeLoadException (String.Format ("Type '{0}' cannot be found", typeName), loadException);
1841 internal static Type LoadType <TBaseType> (string typeName, bool throwOnMissing)
1843 Type ret = LoadType (typeName, throwOnMissing);
1845 if (typeof (TBaseType).IsAssignableFrom (ret))
1849 throw new TypeLoadException (String.Format ("Type '{0}' found but it doesn't derive from base type '{1}'.", typeName, typeof (TBaseType)));
1854 internal static Type LoadTypeFromBin (string typeName)
1858 foreach (string s in BinDirectoryAssemblies) {
1859 Assembly binA = null;
1862 binA = Assembly.LoadFrom (s);
1863 } catch (FileLoadException) {
1866 } catch (BadImageFormatException) {
1871 type = binA.GetType (typeName, false);
1883 // Based on Fritz' Onion's AsyncRequestState class for asynchronous IHttpAsyncHandlers
1885 class AsyncRequestState : IAsyncResult {
1889 ManualResetEvent complete_event = null;
1891 internal AsyncRequestState (ManualResetEvent complete_event, AsyncCallback cb, object cb_data)
1894 this.cb_data = cb_data;
1895 this.complete_event = complete_event;
1898 internal void Complete ()
1903 // TODO: if this throws an error, we have no way of reporting it
1904 // Not really too bad, since the only failure might be
1905 // `HttpRuntime.request_processed'.
1912 complete_event.Set ();
1915 public object AsyncState {
1921 public bool CompletedSynchronously {
1927 public bool IsCompleted {
1933 public WaitHandle AsyncWaitHandle {
1935 return complete_event;
1940 #region Helper classes
1943 // A wrapper to keep track of begin/end pairs
1945 class AsyncInvoker {
1946 public BeginEventHandler begin;
1947 public EndEventHandler end;
1950 public AsyncInvoker (BeginEventHandler bh, EndEventHandler eh, object d)
1957 public AsyncInvoker (BeginEventHandler bh, EndEventHandler eh)
1963 public void Invoke (object sender, EventArgs e)
1965 throw new Exception ("This is just a dummy");