2010-05-05 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web / HttpApplication.cs
index dc3b1fbc0d6051433b35bebfe24ac7a64a31e4c5..d9972ceddec874d60ed40d8dafba25186e78fad8 100644 (file)
@@ -73,7 +73,9 @@ using System.Security.Permissions;
 using System.Security.Principal;
 using System.Threading;
 using System.Web.Caching;
+using System.Web.Compilation;
 using System.Web.Configuration;
+using System.Web.Management;
 using System.Web.SessionState;
 using System.Web.UI;
 using System.Web.Util;
@@ -276,10 +278,10 @@ namespace System.Web
                public HttpRequest Request {
                        get {
                                if (context == null)
-                                       throw new HttpException (Locale.GetText ("No context is available."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                if (false == HttpApplicationFactory.ContextAvailable)
-                                       throw new HttpException (Locale.GetText ("Request is not available in this context."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("Request is not available in this context."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                return context.Request;
                        }
@@ -290,10 +292,10 @@ namespace System.Web
                public HttpResponse Response {
                        get {
                                if (context == null)
-                                       throw new HttpException (Locale.GetText ("No context is available."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                if (false == HttpApplicationFactory.ContextAvailable)
-                                       throw new HttpException (Locale.GetText ("Response is not available in this context."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("Response is not available in this context."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                return context.Response;
                        }
@@ -323,11 +325,11 @@ namespace System.Web
                                        return session;
 
                                if (context == null)
-                                       throw new HttpException (Locale.GetText ("No context is available."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                HttpSessionState ret = context.Session;
                                if (ret == null)
-                                       throw new HttpException (Locale.GetText ("Session state is not available in the context."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("Session state is not available in the context."), WebEventCodes.RuntimeErrorRequestAbort);
                                
                                return ret;
                        }
@@ -849,6 +851,14 @@ namespace System.Web
                        return null;
                }
 
+               bool ShouldHandleException (Exception e)
+               {
+                       if (e is ParseException)
+                               return false;
+
+                       return true;
+               }
+               
                //
                // If we catch an error, queue this error
                //
@@ -856,15 +866,18 @@ namespace System.Web
                {
                        bool first = context.Error == null;
                        context.AddError (e);
-                       if (first) {
+                       if (first && ShouldHandleException (e)) {
                                EventHandler eh = nonApplicationEvents [errorEvent] as EventHandler;
                                if (eh != null){
                                        try {
                                                eh (this, EventArgs.Empty);
+                                               if (stop_processing)
+                                                       context.ClearError ();
                                        } catch (ThreadAbortException taex){
                                                context.ClearError ();
-                                               if (FlagEnd.Value == taex.ExceptionState)
-                                                       // This happens on Redirect() or End()
+                                               if (FlagEnd.Value == taex.ExceptionState || HttpRuntime.DomainUnloading)
+                                                       // This happens on Redirect(), End() and
+                                                       // when unloading the AppDomain
                                                        Thread.ResetAbort ();
                                                else
                                                        // This happens on Thread.Abort()
@@ -920,19 +933,19 @@ namespace System.Web
                        } catch (ThreadAbortException taex) {
                                object obj = taex.ExceptionState;
                                Thread.ResetAbort ();
-                               stop_processing = true;
                                if (obj is StepTimeout)
-                                       ProcessError (new HttpException ("The request timed out."));
+                                       ProcessError (HttpException.NewWithCode ("The request timed out.", WebEventCodes.RequestTransactionAbort));
                                else {
                                        context.ClearError ();
-                                       if (FlagEnd.Value != obj)
+                                       if (FlagEnd.Value != obj && !HttpRuntime.DomainUnloading)
                                                context.AddError (taex);
                                }
-
+                               
+                               stop_processing = true;
                                PipelineDone ();
                        } catch (Exception e) {
-                               stop_processing = true;
                                ProcessError (e);
+                               stop_processing = true;
                                PipelineDone ();
                        }
                }
@@ -1051,7 +1064,7 @@ namespace System.Web
                                        if (error is HttpException){
                                                response.StatusCode = ((HttpException)error).GetHttpCode ();
                                        } else {
-                                               error = new HttpException ("", error);
+                                               error = HttpException.NewWithCode (String.Empty, error, WebEventCodes.WebErrorOtherError);
                                                response.StatusCode = 500;
                                        }
                                        HttpException httpEx = (HttpException) error;
@@ -1061,7 +1074,7 @@ namespace System.Web
                                                response.Flush (true);
                                } else {
                                        if (!(error is HttpException))
-                                               error = new HttpException ("", error);
+                                               error = HttpException.NewWithCode (String.Empty, error, WebEventCodes.WebErrorOtherError);
                                        FinalErrorWrite (response, ((HttpException) error).GetHtmlErrorMessage ());
                                }
                        }
@@ -1162,6 +1175,21 @@ namespace System.Web
                        if (stop_processing)
                                yield return true;
 
+#if NET_4_0
+                       if (HttpRequest.ValidateRequestNewMode) {
+                               char[] invalidChars = HttpRequest.RequestPathInvalidCharacters;
+                               HttpRequest req = context.Request;
+                               if (invalidChars != null && req != null) {
+                                       string path = req.PathNoValidation;
+                                       int idx = path != null ? path.IndexOfAny (invalidChars) : -1;
+                                       if (idx != -1)
+                                               throw HttpException.NewWithCode (
+                                                       String.Format ("A potentially dangerous Request.Path value was detected from the client ({0}).", path [idx]),
+                                                       WebEventCodes.RuntimeErrorValidationFailure
+                                               );
+                               }
+                       }
+#endif
                        context.MapRequestHandlerDone = false;
                        StartTimer ("BeginRequest");
                        eventHandler = Events [BeginRequestEvent];
@@ -1241,13 +1269,20 @@ namespace System.Web
                                Console.WriteLine (fnf.ToString ());
 #endif
                                if (context.Request.IsLocal)
-                                       ProcessError (new HttpException (404, String.Format ("File not found {0}", fnf.FileName), fnf, context.Request.FilePath));
+                                       ProcessError (HttpException.NewWithCode (404,
+                                                                                String.Format ("File not found {0}", fnf.FileName),
+                                                                                fnf,
+                                                                                context.Request.FilePath,
+                                                                                WebEventCodes.RuntimeErrorRequestAbort));
                                else
-                                       ProcessError (new HttpException (404, "File not found: " + Path.GetFileName (fnf.FileName), context.Request.FilePath));
+                                       ProcessError (HttpException.NewWithCode (404,
+                                                                                "File not found: " + Path.GetFileName (fnf.FileName),
+                                                                                context.Request.FilePath,
+                                                                                WebEventCodes.RuntimeErrorRequestAbort));
                        } catch (DirectoryNotFoundException dnf){
                                if (!context.Request.IsLocal)
                                        dnf = null; // Do not "leak" real path information
-                               ProcessError (new HttpException (404, "Directory not found", dnf));
+                               ProcessError (HttpException.NewWithCode (404, "Directory not found", dnf, WebEventCodes.RuntimeErrorRequestAbort));
                        } catch (Exception e) {
                                ProcessError (e);
                        }
@@ -1508,7 +1543,7 @@ namespace System.Web
                                InitOnce (true);
                        } catch (Exception e) {
                                initialization_exception = e;
-                               FinalErrorWrite (context.Response, new HttpException ("", e).GetHtmlErrorMessage ());
+                               FinalErrorWrite (context.Response, HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort).GetHtmlErrorMessage ());
                                PipelineDone ();
                                return;
                        }
@@ -1699,7 +1734,7 @@ namespace System.Web
                        return RedirectErrorPage (redirect);
                        }
                        catch (Exception ex) {
-                               httpEx = new HttpException (500, "", ex);
+                               httpEx = HttpException.NewWithCode (500, String.Empty, ex, WebEventCodes.WebErrorOtherError);
                                return false;
                        }
                }
@@ -1792,6 +1827,19 @@ namespace System.Web
                        return null;
                }
 
+               internal static Type LoadType <TBaseType> (string typeName, bool throwOnMissing)
+               {
+                       Type ret = LoadType (typeName, throwOnMissing);
+
+                       if (typeof (TBaseType).IsAssignableFrom (ret))
+                               return ret;
+
+                       if (throwOnMissing)
+                               throw new TypeLoadException (String.Format ("Type '{0}' found but it doesn't derive from base type '{1}'.", typeName, typeof (TBaseType)));
+
+                       return null;
+               }
+               
                internal static Type LoadTypeFromBin (string typeName)
                {
                        Type type = null;