// Gonzalo Paniagua (gonzalo@ximian.com)
//
//
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
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;
#if TARGET_J2EE
using Mainsoft.Web;
#endif
-namespace System.Web {
-
+namespace System.Web
+{
// CAS
[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
static string binDirectory;
-#if NET_2_0
#if TARGET_J2EE
const string initialization_exception_key = "System.Web.HttpApplication.initialization_exception";
static Exception initialization_exception {
static Exception initialization_exception;
#endif
bool removeConfigurationFromCache;
-#endif
bool fullInitComplete = false;
//
if (modcoll != null)
return;
-#if NET_2_0
HttpModulesSection modules;
modules = (HttpModulesSection) WebConfigurationManager.GetWebApplicationSection ("system.web/httpModules");
-#else
- ModulesConfiguration modules;
-
- modules = (ModulesConfiguration) HttpContext.GetAppConfig ("system.web/httpModules");
-#endif
-
HttpContext saved = HttpContext.Current;
- HttpContext.Current = new HttpContext (new System.Web.Hosting.SimpleWorkerRequest ("", "", new StringWriter()));
+ HttpContext.Current = new HttpContext (new System.Web.Hosting.SimpleWorkerRequest (String.Empty, String.Empty, new StringWriter()));
modcoll = modules.LoadModules (this);
HttpContext.Current = saved;
}
}
-#if NET_2_0
internal static Exception InitializationException {
get { return initialization_exception; }
}
-#endif
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
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;
}
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;
}
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;
}
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-#if NET_2_0
public ISite Site {
-#else
- public virtual ISite Site {
-#endif
- get {
- return isite;
- }
+ get { return isite; }
- set {
- isite = value;
- }
+ set { isite = value; }
}
[Browsable (false)]
UpdateRequestCache += new EventHandler (invoker.Invoke);
}
-#if NET_2_0
static object PostAuthenticateRequestEvent = new object ();
public event EventHandler PostAuthenticateRequest
{
AsyncInvoker invoker = new AsyncInvoker (beginHandler, endHandler, state);
PostLogRequest += new EventHandler (invoker.Invoke);
}
-
-#endif
internal event EventHandler DefaultAuthentication;
{
}
+#if NET_4_0
+ public virtual string GetOutputCacheProviderName (HttpContext context)
+ {
+ // LAMESPEC: doesn't throw ProviderException if context is null
+ return OutputCache.DefaultProviderName;
+ }
+#endif
+
public virtual string GetVaryByCustomString (HttpContext context, string custom)
{
if (custom == null) // Sigh
throw new NullReferenceException ();
- if (0 == String.Compare (custom, "browser", true, CultureInfo.InvariantCulture))
+ if (0 == String.Compare (custom, "browser", true, Helpers.InvariantCulture))
return context.Request.Browser.Type;
return null;
}
+ bool ShouldHandleException (Exception e)
+ {
+ if (e is ParseException)
+ return false;
+
+ return true;
+ }
+
//
// If we catch an error, queue this error
//
{
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()
}
}
stop_processing = true;
-#if NET_2_0
+
// we want to remove configuration from the cache in case of
// invalid resource not exists to prevent DOS attack.
HttpException httpEx = e as HttpException;
if (httpEx != null && httpEx.GetHttpCode () == 404) {
removeConfigurationFromCache = true;
}
-#endif
}
//
} 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 ();
}
}
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;
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 ());
}
}
context.Handler = null;
factory = null;
}
-#if NET_2_0
context.PopHandler ();
-#endif
+
// context = null; -> moved to PostDone
pipeline = null;
current_ai = null;
if (stop_processing)
yield return true;
-#if NET_2_0
- context.MapRequestHandlerDone = false;
+#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];
if (eventHandler != null) {
yield return stop;
StopTimer ();
-#if NET_2_0
StartTimer ("PostAuthenticateRequest");
eventHandler = Events [PostAuthenticateRequestEvent];
if (eventHandler != null)
foreach (bool stop in RunHooks (eventHandler))
yield return stop;
StopTimer ();
-#endif
+
StartTimer ("AuthorizeRequest");
eventHandler = Events [AuthorizeRequestEvent];
if (eventHandler != null)
foreach (bool stop in RunHooks (eventHandler))
yield return stop;
StopTimer ();
-#if NET_2_0
+
StartTimer ("PostAuthorizeRequest");
eventHandler = Events [PostAuthorizeRequestEvent];
if (eventHandler != null)
foreach (bool stop in RunHooks (eventHandler))
yield return stop;
StopTimer ();
-#endif
StartTimer ("ResolveRequestCache");
eventHandler = Events [ResolveRequestCacheEvent];
yield return stop;
StopTimer ();
-#if NET_2_0
StartTimer ("PostResolveRequestCache");
eventHandler = Events [PostResolveRequestCacheEvent];
if (eventHandler != null)
yield return stop;
StopTimer ();
context.MapRequestHandlerDone = true;
-#endif
StartTimer ("GetHandler");
// Obtain the handler for the request.
try {
handler = GetHandler (context, context.Request.CurrentExecutionFilePath);
context.Handler = handler;
-#if NET_2_0
context.PushHandler (handler);
-#endif
} catch (FileNotFoundException fnf){
#if TARGET_JVM
Console.WriteLine ("$$$$$$$$$$:Sys.Web Pipeline");
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);
}
if (stop_processing)
yield return true;
-#if NET_2_0
StartTimer ("PostMapRequestHandler");
eventHandler = Events [PostMapRequestHandlerEvent];
if (eventHandler != null)
foreach (bool stop in RunHooks (eventHandler))
yield return stop;
StopTimer ();
-#endif
StartTimer ("AcquireRequestState");
eventHandler = Events [AcquireRequestStateEvent];
}
StopTimer ();
-#if NET_2_0
StartTimer ("PostAcquireRequestState");
eventHandler = Events [PostAcquireRequestStateEvent];
if (eventHandler != null){
yield return stop;
}
StopTimer ();
-#endif
//
// From this point on, we need to ensure that we call
bool doProcessHandler = false;
#endif
-#if NET_2_0
IHttpHandler ctxHandler = context.Handler;
if (ctxHandler != null && handler != ctxHandler) {
context.PopHandler ();
handler = ctxHandler;
context.PushHandler (handler);
}
-#endif
StartTimer ("ProcessRequest");
try {
if (stop_processing)
yield return true;
-#if NET_2_0
StartTimer ("PostReleaseRequestState");
eventHandler = Events [PostReleaseRequestStateEvent];
if (eventHandler != null)
foreach (bool stop in RunHooks (eventHandler))
yield return stop;
StopTimer ();
-#endif
StartTimer ("Filter");
if (context.Error == null)
yield return stop;
StopTimer ();
-#if NET_2_0
StartTimer ("PostUpdateRequestCache");
eventHandler = Events [PostUpdateRequestCacheEvent];
if (eventHandler != null)
foreach (bool stop in RunHooks (eventHandler))
yield return stop;
StopTimer ();
-#endif
+
StartTimer ("PipelineDone");
PipelineDone ();
StopTimer ();
internal CultureInfo GetThreadCulture (HttpRequest request, CultureInfo culture, bool isAuto)
{
-#if NET_2_0
if (!isAuto)
return culture;
CultureInfo ret = null;
ret = culture;
return ret;
-#else
- return culture;
-#endif
}
void PreStart ()
{
-#if NET_2_0
GlobalizationSection cfg;
cfg = (GlobalizationSection) WebConfigurationManager.GetSection ("system.web/globalization");
app_culture = cfg.GetCulture ();
autoCulture = cfg.IsAutoCulture;
appui_culture = cfg.GetUICulture ();
autoUICulture = cfg.IsAutoUICulture;
-#else
- GlobalizationConfiguration cfg;
- cfg = GlobalizationConfiguration.GetInstance (null);
- if (cfg != null) {
- app_culture = cfg.Culture;
- appui_culture = cfg.UICulture;
- }
-#endif
-
#if !TARGET_J2EE
context.StartTimeoutTimer ();
#endif
if (app_culture != null) {
prev_app_culture = th.CurrentCulture;
CultureInfo new_app_culture = GetThreadCulture (Request, app_culture, autoCulture);
- if (!new_app_culture.Equals (CultureInfo.InvariantCulture))
+ if (!new_app_culture.Equals (Helpers.InvariantCulture))
th.CurrentCulture = new_app_culture;
}
if (appui_culture != null) {
prev_appui_culture = th.CurrentUICulture;
CultureInfo new_app_culture = GetThreadCulture (Request, appui_culture, autoUICulture);
- if (!new_app_culture.Equals (CultureInfo.InvariantCulture))
+ if (!new_app_culture.Equals (Helpers.InvariantCulture))
th.CurrentUICulture = new_app_culture;
}
void PostDone ()
{
-#if NET_2_0
if (removeConfigurationFromCache) {
WebConfigurationManager.RemoveConfigurationFromCache (context);
removeConfigurationFromCache = false;
}
-#endif
+
Thread th = Thread.CurrentThread;
#if !TARGET_JVM
if (Thread.CurrentPrincipal != prev_user)
try {
InitOnce (true);
} catch (Exception e) {
-#if NET_2_0
initialization_exception = e;
-#endif
- FinalErrorWrite (context.Response, new HttpException ("", e).GetHtmlErrorMessage ());
+ FinalErrorWrite (context.Response, HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort).GetHtmlErrorMessage ());
PipelineDone ();
return;
}
cache.Clear ();
}
- object LocateHandler (string verb, string url)
+ object LocateHandler (HttpRequest req, string verb, string url)
{
Hashtable cache = GetHandlerCache ();
string id = String.Concat (verb, url);
if (ret != null)
return ret;
-
-#if NET_2_0
- HttpHandlersSection httpHandlersSection = (HttpHandlersSection) WebConfigurationManager.GetWebApplicationSection ("system.web/httpHandlers");
- ret = httpHandlersSection.LocateHandler (verb, url);
-#else
- HandlerFactoryConfiguration factory_config = (HandlerFactoryConfiguration) HttpContext.GetAppConfig ("system.web/httpHandlers");
- ret = factory_config.LocateHandler (verb, url);
-#endif
+
+ bool allowCache;
+ HttpHandlersSection httpHandlersSection = WebConfigurationManager.GetSection ("system.web/httpHandlers", req.Path, req.Context) as HttpHandlersSection;
+ ret = httpHandlersSection.LocateHandler (verb, url, out allowCache);
IHttpHandler handler = ret as IHttpHandler;
- if (handler != null && handler.IsReusable)
+ if (allowCache && handler != null && handler.IsReusable)
cache [id] = ret;
return ret;
string verb = request.RequestType;
IHttpHandler handler = null;
- object o = LocateHandler (verb, url);
+ object o = LocateHandler (request, verb, url);
factory = o as IHttpHandlerFactory;
-
if (factory == null) {
handler = (IHttpHandler) o;
} else {
if (!context.IsCustomErrorEnabledUnsafe)
return false;
-#if NET_2_0
- CustomErrorsSection config = (CustomErrorsSection)WebConfigurationManager.GetSection ("system.web/customErrors");
-#else
- CustomErrorsConfig config = null;
- try {
- config = (CustomErrorsConfig) context.GetConfig ("system.web/customErrors");
- } catch { }
-#endif
-
+ CustomErrorsSection config = (CustomErrorsSection)WebConfigurationManager.GetSection ("system.web/customErrors");
if (config == null) {
if (context.ErrorPage != null)
return RedirectErrorPage (context.ErrorPage);
return false;
}
-#if NET_2_0
CustomError err = config.Errors [context.Response.StatusCode.ToString()];
string redirect = err == null ? null : err.Redirect;
-#else
- string redirect = config [context.Response.StatusCode];
-#endif
if (redirect == null) {
redirect = context.ErrorPage;
if (redirect == null)
return RedirectErrorPage (redirect);
}
catch (Exception ex) {
- httpEx = new HttpException (500, "", ex);
+ httpEx = HttpException.NewWithCode (500, String.Empty, ex, WebEventCodes.WebErrorOtherError);
return false;
}
}
return type;
}
-#if NET_2_0
IList tla = System.Web.Compilation.BuildManager.TopLevelAssemblies;
if (tla != null && tla.Count > 0) {
foreach (Assembly asm in tla) {
return type;
}
}
-#endif
- type = LoadTypeFromBin (typeName);
+ Exception loadException = null;
+ try {
+ type = null;
+ type = LoadTypeFromBin (typeName);
+ } catch (Exception ex) {
+ loadException = ex;
+ }
+
if (type != null)
return type;
#endif
if (throwOnMissing)
- throw new TypeLoadException (String.Format ("Type '{0}' cannot be found", typeName));
+ throw new TypeLoadException (String.Format ("Type '{0}' cannot be found", typeName), loadException);
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;
foreach (string s in BinDirectoryAssemblies) {
- Assembly binA = Assembly.LoadFrom (s);
+ Assembly binA = null;
+
+ try {
+ binA = Assembly.LoadFrom (s);
+ } catch (FileLoadException) {
+ // ignore
+ continue;
+ } catch (BadImageFormatException) {
+ // ignore
+ continue;
+ }
+
type = binA.GetType (typeName, false);
if (type == null)
continue;