소스 검색

2005-09-14 Sebastien Pouliot <[email protected]>

* BrowserCapabilities.cs: Fixed changes (in 2.0) with versions. Fixed
compare with "True" (culture and case sensitivity).
* HttpApplicationState.cs: Added LinkDemand for Minimal. Use the
internal HttpStaticObjectsCollection ctor to avoid the UnmanagedCode
demand.
* HttpContext.cs: Added LinkDemand for Minimal. Added 2.0 properties
and methods to test CAS on them.
* HttpRequest.cs: Added LinkDemand for Minimal. Ensure we return
proper values when worker_request is null.
* HttpResponse.cs: Added LinkDemand for Minimal. Ensure we return
proper values when context or WorkerRequest is null. Added 2.0
properties and methods to test CAS on them.
* HttpRuntime.cs: Added LinkDemand for Minimal. Added PathDiscovery
demands for properties returning directories. Added demand for High
level on AppDomainAppId and AppDomainId properties, Low level on
IsOnUNCShare, Medium level on ProcessRequest and a demand for
UnmanagedCode on UnloadAppDomain method. Constructor also has a
UnmanagedCode demand for 1.x.
* HttpStaticObjectsCollection.cs: Added LinkDemand for Minimal. Added
a UnmanagedCode demand to public ctor. Added internal ctor without the
demand. Changed Serialize and Deserialize methods to public for 2.0.


svn path=/trunk/mcs/; revision=50038

Sebastien Pouliot 20 년 전
부모
커밋
866aaa596f

+ 16 - 6
mcs/class/System.Web/System.Web/BrowserCapabilities.cs

@@ -28,8 +28,9 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 //
-using System;
+
 using System.Collections;
 using System.Collections;
+using System.Globalization;
 using System.Web.Configuration;
 using System.Web.Configuration;
 using System.Web.UI;
 using System.Web.UI;
 
 
@@ -151,7 +152,12 @@ namespace System.Web {
 				return browser;
 				return browser;
 			}
 			}
 		}
 		}
-
+#if NET_2_0
+		[MonoTODO]
+		public ArrayList Browsers {
+			get { throw new NotImplementedException (); }
+		}
+#endif
 		public bool CDF {
 		public bool CDF {
 			get {
 			get {
 				if (!Get (HaveCDF)) {
 				if (!Get (HaveCDF)) {
@@ -372,7 +378,7 @@ namespace System.Web {
 #if NET_1_1
 #if NET_1_1
 		public Version [] GetClrVersions ()
 		public Version [] GetClrVersions ()
 		{
 		{
-			if (clrVersions == null)
+			if ((clrVersions == null) && (clrVersion == null))
 				InternalGetClrVersions ();
 				InternalGetClrVersions ();
 
 
 			return clrVersions;
 			return clrVersions;
@@ -385,7 +391,7 @@ namespace System.Web {
 			string s = useragent;
 			string s = useragent;
 			ArrayList list = null;
 			ArrayList list = null;
 			int idx;
 			int idx;
-			while ((idx = s.IndexOf (".NET CLR ")) != -1) {
+			while ((s != null) && (idx = s.IndexOf (".NET CLR ")) != -1) {
 				int end = s.IndexOfAny (anychars, idx + 9);
 				int end = s.IndexOfAny (anychars, idx + 9);
 				if (end == -1)
 				if (end == -1)
 					break;
 					break;
@@ -407,7 +413,11 @@ namespace System.Web {
 			
 			
 			if (list == null || list.Count == 0) {
 			if (list == null || list.Count == 0) {
 				clrVersion = new Version ();
 				clrVersion = new Version ();
-				clrVersions = new Version [] { clrVersion };
+#if NET_2_0
+				clrVersions = null;
+#else
+				clrVersions = new Version [1] { clrVersion };
+#endif
 			} else {
 			} else {
 				list.Sort ();
 				list.Sort ();
 				clrVersions = (Version []) list.ToArray (typeof (Version));
 				clrVersions = (Version []) list.ToArray (typeof (Version));
@@ -420,7 +430,7 @@ namespace System.Web {
 			if (v == null)
 			if (v == null)
 				return dflt;
 				return dflt;
 
 
-			return (v == "True");
+			return (String.Compare (v, "True", true, CultureInfo.InvariantCulture) == 0);
 		}
 		}
 
 
 		int ReadInt32 (string key, int dflt)
 		int ReadInt32 (string key, int dflt)

+ 24 - 0
mcs/class/System.Web/System.Web/ChangeLog

@@ -1,3 +1,27 @@
+2005-09-14  Sebastien Pouliot  <[email protected]> 
+ 
+	* BrowserCapabilities.cs: Fixed changes (in 2.0) with versions. Fixed
+	compare with "True" (culture and case sensitivity).
+	* HttpApplicationState.cs: Added LinkDemand for Minimal. Use the 
+	internal HttpStaticObjectsCollection ctor to avoid the UnmanagedCode
+	demand.
+	* HttpContext.cs: Added LinkDemand for Minimal. Added 2.0 properties
+	and methods to test CAS on them.
+	* HttpRequest.cs: Added LinkDemand for Minimal. Ensure we return 
+	proper values when worker_request is null.
+	* HttpResponse.cs: Added LinkDemand for Minimal. Ensure we return 
+	proper values when context or WorkerRequest is null. Added 2.0 
+	properties and methods to test CAS on them.
+	* HttpRuntime.cs: Added LinkDemand for Minimal. Added PathDiscovery 
+	demands for properties returning directories. Added demand for High 
+	level on AppDomainAppId and AppDomainId properties, Low level on 
+	IsOnUNCShare, Medium level on ProcessRequest and a demand for 
+	UnmanagedCode on UnloadAppDomain method. Constructor also has a 
+	UnmanagedCode demand for 1.x.
+	* HttpStaticObjectsCollection.cs: Added LinkDemand for Minimal. Added
+	a UnmanagedCode demand to public ctor. Added internal ctor without the
+	demand. Changed Serialize and Deserialize methods to public for 2.0.
+
 2005-09-14  Sebastien Pouliot  <[email protected]>
 2005-09-14  Sebastien Pouliot  <[email protected]>
 
 
 	* HttpWorkerRequest.cs: Removed TODO for 2.0 APIs and return the 
 	* HttpWorkerRequest.cs: Removed TODO for 2.0 APIs and return the 

+ 12 - 8
mcs/class/System.Web/System.Web/HttpApplicationState.cs

@@ -25,14 +25,15 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 //
-using System;
+
 using System.Threading;
 using System.Threading;
-using System.Web;
 using System.Collections.Specialized;
 using System.Collections.Specialized;
+using System.Security.Permissions;
 
 
-namespace System.Web 
-{
+namespace System.Web {
 
 
+	// CAS - no InheritanceDemand here as the class is sealed
+	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
 	public sealed class HttpApplicationState : NameObjectCollectionBase 
 	public sealed class HttpApplicationState : NameObjectCollectionBase 
 	{
 	{
 		private HttpStaticObjectsCollection _AppObjects;
 		private HttpStaticObjectsCollection _AppObjects;
@@ -42,8 +43,9 @@ namespace System.Web
 
 
 		internal HttpApplicationState ()
 		internal HttpApplicationState ()
 		{
 		{
-			_AppObjects = new HttpStaticObjectsCollection ();
-			_SessionObjects = new HttpStaticObjectsCollection ();
+			// do not use the public (empty) ctor as it required UnmanagedCode permission
+			_AppObjects = new HttpStaticObjectsCollection (this);
+			_SessionObjects = new HttpStaticObjectsCollection (this);
 			_Lock = new ReaderWriterLock ();
 			_Lock = new ReaderWriterLock ();
 		}
 		}
 
 
@@ -56,7 +58,8 @@ namespace System.Web
 			} 
 			} 
 			else 
 			else 
 			{
 			{
-				_AppObjects = new HttpStaticObjectsCollection ();
+				// do not use the public (empty) ctor as it required UnmanagedCode permission
+				_AppObjects = new HttpStaticObjectsCollection (this);
 			}
 			}
 
 
 			if (null != SessionObj) 
 			if (null != SessionObj) 
@@ -65,7 +68,8 @@ namespace System.Web
 			} 
 			} 
 			else 
 			else 
 			{
 			{
-				_SessionObjects = new HttpStaticObjectsCollection ();
+				// do not use the public (empty) ctor as it required UnmanagedCode permission
+				_SessionObjects = new HttpStaticObjectsCollection (this);
 			}
 			}
 			_Lock = new ReaderWriterLock ();
 			_Lock = new ReaderWriterLock ();
 		}
 		}

+ 75 - 1
mcs/class/System.Web/System.Web/HttpContext.cs

@@ -31,6 +31,7 @@
 
 
 using System.Collections;
 using System.Collections;
 using System.Configuration;
 using System.Configuration;
+using System.Globalization;
 using System.Runtime.Remoting.Messaging;
 using System.Runtime.Remoting.Messaging;
 using System.Security.Permissions;
 using System.Security.Permissions;
 using System.Security.Principal;
 using System.Security.Principal;
@@ -40,9 +41,14 @@ using System.Web.Configuration;
 using System.Web.SessionState;
 using System.Web.SessionState;
 using System.Web.UI;
 using System.Web.UI;
 using System.Web.Util;
 using System.Web.Util;
+#if NET_2_0
+using System.Web.Profile;
+#endif
 
 
 namespace System.Web {
 namespace System.Web {
 	
 	
+	// CAS - no InheritanceDemand here as the class is sealed
+	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
 	public sealed class HttpContext : IServiceProvider {
 	public sealed class HttpContext : IServiceProvider {
 		internal HttpWorkerRequest WorkerRequest;
 		internal HttpWorkerRequest WorkerRequest;
 		HttpApplication app_instance;
 		HttpApplication app_instance;
@@ -178,7 +184,11 @@ namespace System.Web {
 #else
 #else
 		public bool IsDebuggingEnabled {
 		public bool IsDebuggingEnabled {
 			get {
 			get {
-				return CompilationConfiguration.GetInstance (this).Debug;
+				try {
+					return CompilationConfiguration.GetInstance (this).Debug;
+				} catch {
+					return false;
+				}
 			}
 			}
 		}
 		}
 #endif
 #endif
@@ -252,6 +262,25 @@ namespace System.Web {
 			}
 			}
 		}
 		}
 
 
+#if NET_2_0
+		[MonoTODO]
+		public IHttpHandler CurrentHandler {
+			get { throw new NotImplementedException (); }
+		}
+
+		[MonoTODO]
+		public IHttpHandler PreviousHandler {
+			get { throw new NotImplementedException (); }
+		}
+
+	#if false
+		[MonoTODO]
+		public ProfileBase Profile {
+			get { throw new NotImplementedException (); }
+		}
+	#endif
+#endif
+
 		public void AddError (Exception errorInfo)
 		public void AddError (Exception errorInfo)
 		{
 		{
 			if (errors == null){
 			if (errors == null){
@@ -273,6 +302,9 @@ namespace System.Web {
 			errors = null;
 			errors = null;
 		}
 		}
 
 
+#if NET_2_0
+		[Obsolete ("see WebConfigurationManager")]
+#endif
 		public static object GetAppConfig (string name)
 		public static object GetAppConfig (string name)
 		{
 		{
 			object o = ConfigurationSettings.GetConfig (name);
 			object o = ConfigurationSettings.GetConfig (name);
@@ -280,11 +312,45 @@ namespace System.Web {
 			return o;
 			return o;
 		}
 		}
 
 
+#if NET_2_0
+		[Obsolete ("see GetSection")]
+#endif
 		public object GetConfig (string name)
 		public object GetConfig (string name)
 		{
 		{
 			return WebConfigurationSettings.GetConfig (name, this);
 			return WebConfigurationSettings.GetConfig (name, this);
 		}
 		}
 
 
+#if NET_2_0
+		[MonoTODO]
+		public static object GetGlobalResourceObject (string classKey, string resourceKey)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static object GetGlobalResourceObject (string classKey, string resourceKey, CultureInfo culture)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static object GetLocalResourceObject (string virtualPath, string resourceKey)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static object GetLocalResourceObject (string virtualPath, string resourceKey, CultureInfo culture)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public object GetSection (string name)
+		{
+			throw new NotImplementedException ();
+		}
+#endif
 		object IServiceProvider.GetService (Type service)
 		object IServiceProvider.GetService (Type service)
 		{
 		{
 			if (service == typeof (HttpWorkerRequest))
 			if (service == typeof (HttpWorkerRequest))
@@ -355,6 +421,14 @@ namespace System.Web {
 				Request.QueryStringRaw = queryString;
 				Request.QueryStringRaw = queryString;
 		}
 		}
 
 
+#if NET_2_0
+		[MonoTODO]
+		public void RewritePath (string path, bool rebaseClientPath)
+		{
+			throw new NotImplementedException ();
+		}
+#endif
+
 #region internals
 #region internals
 		
 		
 		internal void SetSession (HttpSessionState state)
 		internal void SetSession (HttpSessionState state)

+ 76 - 25
mcs/class/System.Web/System.Web/HttpRequest.cs

@@ -34,6 +34,8 @@ using System.Collections;
 using System.Collections.Specialized;
 using System.Collections.Specialized;
 using System.IO;
 using System.IO;
 using System.Runtime.InteropServices;
 using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Permissions;
 using System.Web.Configuration;
 using System.Web.Configuration;
 using System.Web.UI;
 using System.Web.UI;
 using System.Web.Util;
 using System.Web.Util;
@@ -41,6 +43,8 @@ using System.Globalization;
 
 
 namespace System.Web {
 namespace System.Web {
 	
 	
+	// CAS - no InheritanceDemand here as the class is sealed
+	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
 	public sealed class HttpRequest {
 	public sealed class HttpRequest {
 		HttpWorkerRequest worker_request;
 		HttpWorkerRequest worker_request;
 		HttpContext context;
 		HttpContext context;
@@ -219,7 +223,7 @@ namespace System.Web {
 			get {
 			get {
 				if (content_length == -1){
 				if (content_length == -1){
 					if (worker_request == null)
 					if (worker_request == null)
-						throw new HttpException ("No HttpWorkerRequest");
+						return 0;
 
 
 					string cl = worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderContentLength);
 					string cl = worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderContentLength);
 
 
@@ -241,12 +245,11 @@ namespace System.Web {
 		public string ContentType {
 		public string ContentType {
 			get {
 			get {
 				if (content_type == null){
 				if (content_type == null){
-					if (worker_request == null)
-						throw new HttpException ("No HttpWorkerRequest");
+					if (worker_request != null)
+						content_type = worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderContentType);
 
 
-					content_type = worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderContentType);
 					if (content_type == null)
 					if (content_type == null)
-						content_type = "";
+						content_type = String.Empty;
 				}
 				}
 				
 				
 				return content_type;
 				return content_type;
@@ -259,9 +262,13 @@ namespace System.Web {
 
 
 		public HttpCookieCollection Cookies {
 		public HttpCookieCollection Cookies {
 			get {
 			get {
-				if (cookies == null){
-					string cookie_hv = worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderCookie);
-					cookies = new HttpCookieCollection (cookie_hv);
+				if (cookies == null) {
+					if (worker_request == null) {
+						cookies = new HttpCookieCollection ();
+					} else {
+						string cookie_hv = worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderCookie);
+						cookies = new HttpCookieCollection (cookie_hv);
+					}
 				}
 				}
 
 
 				if (validate_cookies && !checked_cookies){
 				if (validate_cookies && !checked_cookies){
@@ -286,7 +293,7 @@ namespace System.Web {
 		public string FilePath {
 		public string FilePath {
 			get {
 			get {
 				if (worker_request == null)
 				if (worker_request == null)
-					return null;
+					return "/"; // required for 2.0
 
 
 				if (file_path == null)
 				if (file_path == null)
 					file_path = UrlUtils.Canonic (worker_request.GetFilePath ());
 					file_path = UrlUtils.Canonic (worker_request.GetFilePath ());
@@ -311,7 +318,7 @@ namespace System.Web {
 			get {
 			get {
 				if (files == null) {
 				if (files == null) {
 					files = new HttpFileCollection ();
 					files = new HttpFileCollection ();
-					if (IsContentType ("multipart/form-data", true)) {
+					if ((worker_request != null) && IsContentType ("multipart/form-data", true)) {
 						form = new WebROCollection ();
 						form = new WebROCollection ();
 						LoadMultiPart ();
 						LoadMultiPart ();
 						form.Protect ();
 						form.Protect ();
@@ -321,6 +328,7 @@ namespace System.Web {
 			}
 			}
 		}
 		}
 
 
+		[MonoTODO]
 		public Stream Filter {
 		public Stream Filter {
 			get {
 			get {
 				throw new NotImplementedException ();
 				throw new NotImplementedException ();
@@ -458,11 +466,12 @@ namespace System.Web {
 		public NameValueCollection Headers {
 		public NameValueCollection Headers {
 			get {
 			get {
 				if (headers == null){
 				if (headers == null){
-					if (worker_request == null)
-						throw new HttpException ("No HttpWorkerRequest");
-						
 					headers = new WebROCollection ();
 					headers = new WebROCollection ();
-					
+					if (worker_request == null) {
+						headers.Protect ();
+						return headers;
+					}
+
 					for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++){
 					for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++){
 						string hval = worker_request.GetKnownRequestHeader (i);
 						string hval = worker_request.GetKnownRequestHeader (i);
 
 
@@ -493,6 +502,8 @@ namespace System.Web {
 				if (http_method == null){
 				if (http_method == null){
 					if (worker_request != null)
 					if (worker_request != null)
 						http_method = worker_request.GetHttpVerbName ();
 						http_method = worker_request.GetHttpVerbName ();
+					else
+						http_method = "GET";
 				}
 				}
 				return http_method;
 				return http_method;
 			}
 			}
@@ -557,8 +568,10 @@ namespace System.Web {
 
 
 		void MakeInputStream ()
 		void MakeInputStream ()
 		{
 		{
-			if (worker_request == null)
-				throw new HttpException ("No HttpWorkerRequest");
+			if (worker_request == null) {
+				input_stream = new MemoryStream (new byte [0], 0, 0, false, true);
+				return;
+			}
 
 
 			//
 			//
 			// Use an unmanaged memory block as this might be a large
 			// Use an unmanaged memory block as this might be a large
@@ -655,11 +668,14 @@ namespace System.Web {
 
 
 		public bool IsSecureConnection {
 		public bool IsSecureConnection {
 			get {
 			get {
+				if (worker_request == null)
+					return false;
 				return worker_request.IsSecure ();
 				return worker_request.IsSecure ();
 			}
 			}
 		}
 		}
 
 
 		public string this [string key] {
 		public string this [string key] {
+			[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
 			get {
 			get {
 				// "The QueryString, Form, Cookies, or ServerVariables collection member
 				// "The QueryString, Form, Cookies, or ServerVariables collection member
 				// specified in the key parameter."
 				// specified in the key parameter."
@@ -679,6 +695,7 @@ namespace System.Web {
 		}
 		}
 
 
 		public NameValueCollection Params {
 		public NameValueCollection Params {
+			[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
 			get {
 			get {
 				if (all_params == null) {
 				if (all_params == null) {
 					all_params = new WebROCollection ();
 					all_params = new WebROCollection ();
@@ -713,7 +730,7 @@ namespace System.Web {
 			get {
 			get {
 				if (path_info == null) {
 				if (path_info == null) {
 					if (worker_request == null)
 					if (worker_request == null)
-						return null;
+						return String.Empty;
 					path_info = worker_request.GetPathInfo ();
 					path_info = worker_request.GetPathInfo ();
 				}
 				}
 
 
@@ -724,16 +741,27 @@ namespace System.Web {
 		public string PhysicalApplicationPath {
 		public string PhysicalApplicationPath {
 			get {
 			get {
 				if (worker_request == null)
 				if (worker_request == null)
-					throw new NullReferenceException ();
-				
-				return HttpRuntime.AppDomainAppPath;
+					throw new ArgumentNullException (); // like 2.0, 1.x throws TypeInitializationException
+
+				string path = HttpRuntime.AppDomainAppPath;
+				if (SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path).Demand ();
+				}
+				return path;
 			}
 			}
 		}
 		}
 
 
 		public string PhysicalPath {
 		public string PhysicalPath {
 			get {
 			get {
+				if (worker_request == null)
+					return String.Empty; // don't check security with an empty string!
+
 				if (physical_path == null)
 				if (physical_path == null)
 					physical_path = MapPath (CurrentExecutionFilePath);
 					physical_path = MapPath (CurrentExecutionFilePath);
+
+				if (SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, physical_path).Demand ();
+				}
 				return physical_path;
 				return physical_path;
 			}
 			}
 		}
 		}
@@ -811,6 +839,8 @@ namespace System.Web {
 					if (worker_request != null) {
 					if (worker_request != null) {
 						request_type = worker_request.GetHttpVerbName ();
 						request_type = worker_request.GetHttpVerbName ();
 						http_method = request_type;
 						http_method = request_type;
+					} else {
+						request_type = "GET";
 					}
 					}
 				}
 				}
 				return request_type;
 				return request_type;
@@ -822,6 +852,7 @@ namespace System.Web {
 		}
 		}
 
 
 		public NameValueCollection ServerVariables {
 		public NameValueCollection ServerVariables {
+			[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
 			get {
 			get {
 				if (server_variables == null)
 				if (server_variables == null)
 					server_variables = new ServerVariablesCollection (this);
 					server_variables = new ServerVariablesCollection (this);
@@ -848,27 +879,40 @@ namespace System.Web {
 
 
 		public Uri UrlReferrer {
 		public Uri UrlReferrer {
 			get {
 			get {
+				if (worker_request == null)
+					return null;
+
 				string hr = worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderReferer);
 				string hr = worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderReferer);
 				if (hr == null)
 				if (hr == null)
 					return null;
 					return null;
+
 				return new Uri (hr);
 				return new Uri (hr);
 			}
 			}
 		}
 		}
 
 
 		public string UserAgent {
 		public string UserAgent {
 			get {
 			get {
+				if (worker_request == null)
+					return null;
+
 				return worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderUserAgent);
 				return worker_request.GetKnownRequestHeader (HttpWorkerRequest.HeaderUserAgent);
 			}
 			}
 		}
 		}
 
 
 		public string UserHostAddress {
 		public string UserHostAddress {
 			get {
 			get {
+				if (worker_request == null)
+					return null;
+
 				return worker_request.GetRemoteAddress ();
 				return worker_request.GetRemoteAddress ();
 			}
 			}
 		}
 		}
 
 
 		public string UserHostName {
 		public string UserHostName {
 			get {
 			get {
+				if (worker_request == null)
+					return null;
+
 				return worker_request.GetRemoteName ();
 				return worker_request.GetRemoteName ();
 			}
 			}
 		}
 		}
@@ -887,8 +931,8 @@ namespace System.Web {
 
 
 		public byte [] BinaryRead (int count)
 		public byte [] BinaryRead (int count)
 		{
 		{
-			if (count <= 0)
-				throw new ArgumentException ("count is <= 0");
+			if (count < 0)
+				throw new ArgumentException ("count is < 0");
 
 
 			Stream s = InputStream;
 			Stream s = InputStream;
 			byte [] ret = new byte [count];
 			byte [] ret = new byte [count];
@@ -932,6 +976,9 @@ namespace System.Web {
 
 
 		public string MapPath (string virtualPath)
 		public string MapPath (string virtualPath)
 		{
 		{
+			if (worker_request == null)
+				return null;
+
 			return MapPath (virtualPath, BaseVirtualDir, true);
 			return MapPath (virtualPath, BaseVirtualDir, true);
 		}
 		}
 
 
@@ -974,9 +1021,13 @@ namespace System.Web {
 			Stream output = new FileStream (filename, FileMode.Create);
 			Stream output = new FileStream (filename, FileMode.Create);
 			if (includeHeaders) {
 			if (includeHeaders) {
 				StringBuilder sb = new StringBuilder ();
 				StringBuilder sb = new StringBuilder ();
-				string version = worker_request.GetHttpVersion ();
-				InitUriBuilder ();
-				string path = uri_builder.Path;
+				string version = String.Empty;
+				string path = "/";
+				if (worker_request != null) {
+					version = worker_request.GetHttpVersion ();
+					InitUriBuilder ();
+					path = uri_builder.Path;
+				}
 				string qs = null;
 				string qs = null;
 				if (query_string != null && query_string != "")
 				if (query_string != null && query_string != "")
 					qs = "?" + query_string;
 					qs = "?" + query_string;

+ 117 - 44
mcs/class/System.Web/System.Web/HttpResponse.cs

@@ -29,6 +29,7 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 //
+
 using System.Text;
 using System.Text;
 using System.Web.UI;
 using System.Web.UI;
 using System.Collections;
 using System.Collections;
@@ -38,9 +39,12 @@ using System.Web.Caching;
 using System.Threading;
 using System.Threading;
 using System.Web.Util;
 using System.Web.Util;
 using System.Globalization;
 using System.Globalization;
+using System.Security.Permissions;
 
 
 namespace System.Web {
 namespace System.Web {
 	
 	
+	// CAS - no InheritanceDemand here as the class is sealed
+	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
 	public sealed class HttpResponse {
 	public sealed class HttpResponse {
 		internal HttpWorkerRequest WorkerRequest;
 		internal HttpWorkerRequest WorkerRequest;
 		internal HttpResponseStream output_stream;
 		internal HttpResponseStream output_stream;
@@ -150,17 +154,19 @@ namespace System.Web {
 		//
 		//
 		public Encoding ContentEncoding {
 		public Encoding ContentEncoding {
 			get {
 			get {
-				if (encoding == null){
-					string client_content_type = context.Request.ContentType;
-					string parameter = HttpRequest.GetParameter (client_content_type, "; charset=");
-					if (parameter != null){
-						try {
-							// Do what the #1 web server does
-							encoding = Encoding.GetEncoding (parameter);
-						} catch {
-							encoding = WebEncoding.ResponseEncoding;
+				if (encoding == null) {
+					if (context != null) {
+						string client_content_type = context.Request.ContentType;
+						string parameter = HttpRequest.GetParameter (client_content_type, "; charset=");
+						if (parameter != null) {
+							try {
+								// Do what the #1 web server does
+								encoding = Encoding.GetEncoding (parameter);
+							} catch {
+							}
 						}
 						}
-					} else
+					}
+					if (encoding == null)
 						encoding = WebEncoding.ResponseEncoding;
 						encoding = WebEncoding.ResponseEncoding;
 				}
 				}
 				return encoding;
 				return encoding;
@@ -231,7 +237,8 @@ namespace System.Web {
 				Cache.SetExpires (value);
 				Cache.SetExpires (value);
 			}
 			}
 		}
 		}
-		
+
+		[MonoTODO]
 		public Stream Filter {
 		public Stream Filter {
 			get {
 			get {
 				throw new NotImplementedException ();
 				throw new NotImplementedException ();
@@ -241,13 +248,31 @@ namespace System.Web {
 				throw new NotImplementedException ();
 				throw new NotImplementedException ();
 			}
 			}
 		}
 		}
-		
+#if NET_2_0
+		[MonoTODO]
+		public Encoding HeaderEncoding {
+			get { throw new NotImplementedException (); }
+			set {
+				if (value == null)
+					throw new ArgumentNullException ("HeaderEncoding");
+				throw new NotImplementedException ();
+			}
+		}
+#endif
 		public bool IsClientConnected {
 		public bool IsClientConnected {
 			get {
 			get {
+				if (WorkerRequest == null)
+					return true; // yep that's true
+
 				return WorkerRequest.IsClientConnected ();
 				return WorkerRequest.IsClientConnected ();
 			}
 			}
 		}
 		}
-		
+#if NET_2_0
+		[MonoTODO]
+		public bool IsRequestBeingRedirected {
+			get { throw new NotImplementedException (); }
+		}
+#endif
 		public TextWriter Output {
 		public TextWriter Output {
 			get {
 			get {
 				if (writer == null)
 				if (writer == null)
@@ -340,22 +365,44 @@ namespace System.Web {
 				suppress_content = value;
 				suppress_content = value;
 			}
 			}
 		}
 		}
+#if NET_2_0
+		[MonoTODO]
+		public void AddCacheDependency (CacheDependency[] dependencies)
+		{
+			throw new NotImplementedException ();
+		}
 
 
+		[MonoTODO]
+		public void AddCacheItemDependencies (string[] cacheKeys)
+		{
+			throw new NotImplementedException ();
+		}
+#endif
+		[MonoTODO]
 		public void AddCacheItemDependencies (ArrayList cacheKeys)
 		public void AddCacheItemDependencies (ArrayList cacheKeys)
 		{
 		{
 			// TODO: talk to jackson about the cache
 			// TODO: talk to jackson about the cache
 		}
 		}
 
 
+		[MonoTODO]
 		public void AddCacheItemDependency (string cacheKey)
 		public void AddCacheItemDependency (string cacheKey)
 		{
 		{
 			// TODO: talk to jackson about the cache
 			// TODO: talk to jackson about the cache
 		}
 		}
 
 
+		[MonoTODO]
 		public void AddFileDependencies (ArrayList filenames)
 		public void AddFileDependencies (ArrayList filenames)
 		{
 		{
 			// TODO: talk to jackson about the cache
 			// TODO: talk to jackson about the cache
 		}
 		}
-
+#if NET_2_0
+		[MonoTODO]
+		public void AddFileDependencies (string[] filenames)
+		{
+			throw new NotImplementedException ();
+		}
+#endif
+		[MonoTODO]
 		public void AddFileDependency (string filename)
 		public void AddFileDependency (string filename)
 		{
 		{
 			// TODO: talk to jackson about the cache
 			// TODO: talk to jackson about the cache
@@ -406,6 +453,7 @@ namespace System.Web {
 			headers.Add (new UnknownResponseHeader (name, value));
 			headers.Add (new UnknownResponseHeader (name, value));
 		}
 		}
 
 
+		[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
 		public void AppendToLog (string param)
 		public void AppendToLog (string param)
 		{
 		{
 			Console.Write ("System.Web: ");
 			Console.Write ("System.Web: ");
@@ -510,7 +558,8 @@ namespace System.Web {
 		{
 		{
 			if (closed)
 			if (closed)
 				return;
 				return;
-			WorkerRequest.CloseConnection ();
+			if (WorkerRequest != null)
+				WorkerRequest.CloseConnection ();
 			closed = true;
 			closed = true;
 		}
 		}
 
 
@@ -532,7 +581,8 @@ namespace System.Web {
 		//   Cache-Control
 		//   Cache-Control
 		void WriteHeaders (bool final_flush)
 		void WriteHeaders (bool final_flush)
 		{
 		{
-			WorkerRequest.SendStatus (status_code, StatusDescription);
+			if (WorkerRequest != null)
+				WorkerRequest.SendStatus (status_code, StatusDescription);
 
 
 			if (cached_response != null)
 			if (cached_response != null)
 				cached_response.SetHeaders (headers);
 				cached_response.SetHeaders (headers);
@@ -631,12 +681,15 @@ namespace System.Web {
 			//
 			//
 			// Flush
 			// Flush
 			//
 			//
-			HttpApplication app_instance = context.ApplicationInstance;
-			if (app_instance != null)
-				app_instance.TriggerPreSendRequestHeaders ();
-				
-			foreach (BaseResponseHeader header in write_headers){
-				header.SendContent (WorkerRequest);
+			if (context != null) {
+				HttpApplication app_instance = context.ApplicationInstance;
+				if (app_instance != null)
+					app_instance.TriggerPreSendRequestHeaders ();
+			}
+			if (WorkerRequest != null) {
+				foreach (BaseResponseHeader header in write_headers){
+					header.SendContent (WorkerRequest);
+				}
 			}
 			}
 			headers_sent = true;
 			headers_sent = true;
 		}
 		}
@@ -650,15 +703,19 @@ namespace System.Web {
 				WriteHeaders (final_flush);
 				WriteHeaders (final_flush);
 			}
 			}
 
 
-			if (suppress_content || context.Request.HttpMethod == "HEAD") {
+			bool head = ((context != null) && (context.Request.HttpMethod == "HEAD"));
+			if (suppress_content || head) {
 				output_stream.Clear ();
 				output_stream.Clear ();
-				output_stream.Flush (WorkerRequest, final_flush);
+				if (WorkerRequest != null)
+					output_stream.Flush (WorkerRequest, final_flush);
 				return;
 				return;
 			}
 			}
 
 
-			HttpApplication app_instance = context.ApplicationInstance;
-			if (app_instance != null)
-				app_instance.TriggerPreSendRequestContent ();
+			if (context != null) {
+				HttpApplication app_instance = context.ApplicationInstance;
+				if (app_instance != null)
+					app_instance.TriggerPreSendRequestContent ();
+			}
 
 
 			if (IsCached) {
 			if (IsCached) {
 				byte [] data = output_stream.GetData ();
 				byte [] data = output_stream.GetData ();
@@ -666,7 +723,8 @@ namespace System.Web {
 				cached_response.SetData (data);
 				cached_response.SetData (data);
 			}
 			}
 
 
-			output_stream.Flush (WorkerRequest, final_flush);
+			if (WorkerRequest != null)
+				output_stream.Flush (WorkerRequest, final_flush);
 
 
 			// FIXME
 			// FIXME
 			if (final_flush && use_chunked != null)
 			if (final_flush && use_chunked != null)
@@ -800,6 +858,8 @@ namespace System.Web {
 			if (size == 0)
 			if (size == 0)
 				return;
 				return;
 
 
+			// Note: this .ctor will throw a SecurityException if the caller 
+			// doesn't have the UnmanagedCode permission
 			using (FileStream fs = new FileStream (fileHandle, FileAccess.Read))
 			using (FileStream fs = new FileStream (fileHandle, FileAccess.Read))
 				WriteFile (fs, offset, size);
 				WriteFile (fs, offset, size);
 
 
@@ -829,7 +889,13 @@ namespace System.Web {
 
 
 			Flush ();
 			Flush ();
 		}
 		}
-
+#if NET_2_0
+		[MonoTODO]
+		public void WriteSubstitution (HttpResponseSubstitutionCallback callback)
+		{
+			throw new NotImplementedException ();
+		}
+#endif
 		//
 		//
 		// Like WriteFile, but never buffers, so we manually Flush here
 		// Like WriteFile, but never buffers, so we manually Flush here
 		//
 		//
@@ -900,29 +966,36 @@ namespace System.Web {
 		//
 		//
 		public string CacheControl {
 		public string CacheControl {
 			set {
 			set {
-				if (String.Compare (value, "public", true, CultureInfo.InvariantCulture) == 0 || 
-				    String.Compare (value, "private", true, CultureInfo.InvariantCulture) == 0 ||
-				    String.Compare (value, "no-cache", true, CultureInfo.InvariantCulture) == 0)
-					cache_control = value;
+				if (String.Compare (value, "public", true, CultureInfo.InvariantCulture) == 0)
+					Cache.SetCacheability (HttpCacheability.Public);
+				else if (String.Compare (value, "private", true, CultureInfo.InvariantCulture) == 0)
+					Cache.SetCacheability (HttpCacheability.Private);
+				else if (String.Compare (value, "no-cache", true, CultureInfo.InvariantCulture) == 0)
+					Cache.SetCacheability (HttpCacheability.NoCache);
 				else
 				else
 					throw new ArgumentException ("CacheControl property only allows `public', " +
 					throw new ArgumentException ("CacheControl property only allows `public', " +
 								     "`private' or no-cache, for different uses, use " +
 								     "`private' or no-cache, for different uses, use " +
 								     "Response.AppendHeader");
 								     "Response.AppendHeader");
-
+				cache_control = value;
 			}
 			}
 
 
 			get {
 			get {
-				if (cache_policy != null){
-					switch (Cache.Cacheability){
-					case HttpCacheability.NoCache: return "private";
-					case HttpCacheability.Private: return "private";
-					case HttpCacheability.Server: return "private";
-					case HttpCacheability.Public: return "public";
-					case HttpCacheability.ServerAndPrivate: return "private";
+				if ((cache_control == null) && (cache_policy != null)) {
+					switch (Cache.Cacheability) {
+					case (HttpCacheability)0:
+					case HttpCacheability.NoCache:
+						return "no-cache";
+					case HttpCacheability.Private: 
+					case HttpCacheability.Server:
+					case HttpCacheability.ServerAndPrivate:
+						return "private";
+					case HttpCacheability.Public:
+						return "public";
+					default:
+						throw new Exception ("Unknown internal state: " + Cache.Cacheability);
 					}
 					}
-					throw new Exception ("Unknown internal state: " + Cache.Cacheability);
-				} else
-					return cache_control;
+				}
+				return cache_control;
 			}
 			}
 		}
 		}
 #endregion
 #endregion

+ 52 - 11
mcs/class/System.Web/System.Web/HttpRuntime.cs

@@ -34,6 +34,8 @@ using System.IO;
 using System.Text;
 using System.Text;
 using System.Globalization;
 using System.Globalization;
 using System.Collections;
 using System.Collections;
+using System.Security;
+using System.Security.Permissions;
 using System.Web.Caching;
 using System.Web.Caching;
 using System.Web.Configuration;
 using System.Web.Configuration;
 using System.Web.UI;
 using System.Web.UI;
@@ -41,6 +43,8 @@ using System.Threading;
 
 
 namespace System.Web {
 namespace System.Web {
 	
 	
+	// CAS - no InheritanceDemand here as the class is sealed
+	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
 	public sealed class HttpRuntime {
 	public sealed class HttpRuntime {
 #if TARGET_J2EE
 #if TARGET_J2EE
 		static QueueManager queue_manager { get { return _runtime._queue_manager; } }
 		static QueueManager queue_manager { get { return _runtime._queue_manager; } }
@@ -94,6 +98,9 @@ namespace System.Web {
 			do_RealProcessRequest = new WaitCallback (RealProcessRequest);
 			do_RealProcessRequest = new WaitCallback (RealProcessRequest);
 		}
 		}
 
 
+#if ONLY_1_1
+		[SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
+#endif
 		public HttpRuntime ()
 		public HttpRuntime ()
 		{
 		{
 		}
 		}
@@ -104,19 +111,27 @@ namespace System.Web {
 		// http://radio.weblogs.com/0105476/stories/2002/07/12/executingAspxPagesWithoutAWebServer.html
 		// http://radio.weblogs.com/0105476/stories/2002/07/12/executingAspxPagesWithoutAWebServer.html
 		//
 		//
 		public static string AppDomainAppId {
 		public static string AppDomainAppId {
+			[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
 			get {
 			get {
 				//
 				//
 				// This value should not change across invocations
 				// This value should not change across invocations
 				//
 				//
-			       
-				return (string) AppDomain.CurrentDomain.GetData (".appId");
+				string dirname = (string) AppDomain.CurrentDomain.GetData (".appId");
+				if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+				}
+				return dirname;
 			}
 			}
 		}
 		}
 
 
 		// Physical directory for the application
 		// Physical directory for the application
 		public static string AppDomainAppPath {
 		public static string AppDomainAppPath {
 			get {
 			get {
-				return (string) AppDomain.CurrentDomain.GetData (".appPath");
+				string dirname = (string) AppDomain.CurrentDomain.GetData (".appPath");
+				if (SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+				}
+				return dirname;
 			}
 			}
 		}
 		}
 
 
@@ -127,6 +142,7 @@ namespace System.Web {
 		}
 		}
 
 
 		public static string AppDomainId {
 		public static string AppDomainId {
+			[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
 			get {
 			get {
 				return (string) AppDomain.CurrentDomain.GetData (".domainId");
 				return (string) AppDomain.CurrentDomain.GetData (".domainId");
 			}
 			}
@@ -134,14 +150,22 @@ namespace System.Web {
 
 
 		public static string AspInstallDirectory {
 		public static string AspInstallDirectory {
 			get {
 			get {
-				return (string) AppDomain.CurrentDomain.GetData (".hostingInstallDir");
+				string dirname = (string) AppDomain.CurrentDomain.GetData (".hostingInstallDir");
+				if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+				}
+				return dirname;
 			}
 			}
 		}
 		}
 #endregion
 #endregion
 		
 		
 		public static string BinDirectory {
 		public static string BinDirectory {
 			get {
 			get {
-				return Path.Combine (AppDomainAppPath, "bin");
+				string dirname = Path.Combine (AppDomainAppPath, "bin");
+				if (SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+				}
+				return dirname;
 			}
 			}
 		}
 		}
 
 
@@ -153,17 +177,27 @@ namespace System.Web {
 
 
 		public static string ClrInstallDirectory {
 		public static string ClrInstallDirectory {
 			get {
 			get {
-				return Path.GetDirectoryName (typeof (Object).Assembly.CodeBase);
+				string dirname = Path.GetDirectoryName (typeof (Object).Assembly.Location);
+				if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+				}
+				return dirname;
 			}
 			}
 		}
 		}
 
 
 		public static string CodegenDir {
 		public static string CodegenDir {
 			get {
 			get {
-				return AppDomain.CurrentDomain.SetupInformation.DynamicBase;
+				string dirname = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
+				if (SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+				}
+				return dirname;
 			}
 			}
 		}
 		}
 
 
+		[MonoTODO]
 		public static bool IsOnUNCShare {
 		public static bool IsOnUNCShare {
+			[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
 			get {
 			get {
 				throw new NotImplementedException ();
 				throw new NotImplementedException ();
 			}
 			}
@@ -171,10 +205,15 @@ namespace System.Web {
 
 
 		public static string MachineConfigurationDirectory {
 		public static string MachineConfigurationDirectory {
 			get {
 			get {
-				return Path.GetDirectoryName (WebConfigurationSettings.MachineConfigPath);
+				string dirname = Path.GetDirectoryName (WebConfigurationSettings.MachineConfigPath);
+				if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
+					new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+				}
+				return dirname;
 			}
 			}
 		}
 		}
 
 
+		[SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
 		public static void Close ()
 		public static void Close ()
 		{
 		{
 			// Remove all items from cache.
 			// Remove all items from cache.
@@ -224,14 +263,15 @@ namespace System.Web {
 		//    ProcessRequest does not guarantee that `wr' will be processed synchronously,
 		//    ProcessRequest does not guarantee that `wr' will be processed synchronously,
 		//    the request can be queued and processed later.
 		//    the request can be queued and processed later.
 		//
 		//
+		[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
 		public static void ProcessRequest (HttpWorkerRequest wr)
 		public static void ProcessRequest (HttpWorkerRequest wr)
 		{
 		{
-			HttpWorkerRequest request;
-
+			if (wr == null)
+				throw new ArgumentNullException ("wr");
 			//
 			//
 			// Queue our request, fetch the next available one from the queue
 			// Queue our request, fetch the next available one from the queue
 			//
 			//
-			request = queue_manager.GetNextRequest (wr);
+			HttpWorkerRequest request = queue_manager.GetNextRequest (wr);
 			if (request == null)
 			if (request == null)
 				return;
 				return;
 
 
@@ -253,6 +293,7 @@ namespace System.Web {
 		// Called when we are shutting down or we need to reload an application
 		// Called when we are shutting down or we need to reload an application
 		// that has been modified (touch global.asax) 
 		// that has been modified (touch global.asax) 
 		//
 		//
+		[SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
 		public static void UnloadAppDomain ()
 		public static void UnloadAppDomain ()
 		{
 		{
 			//
 			//

+ 40 - 12
mcs/class/System.Web/System.Web/HttpStaticObjectsCollection.cs

@@ -19,12 +19,16 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 //
-using System;
+
 using System.Collections;
 using System.Collections;
 using System.IO;
 using System.IO;
+using System.Security.Permissions;
 using System.Web.UI;
 using System.Web.UI;
 
 
 namespace System.Web {
 namespace System.Web {
+
+	// CAS - no InheritanceDemand here as the class is sealed
+	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
 	public sealed class HttpStaticObjectsCollection : ICollection, IEnumerable {
 	public sealed class HttpStaticObjectsCollection : ICollection, IEnumerable {
 		private Hashtable _Objects;
 		private Hashtable _Objects;
 
 
@@ -55,9 +59,18 @@ namespace System.Web {
 		}
 		}
 
 
 		// Needs to hold object items that can be latebound and can be serialized
 		// Needs to hold object items that can be latebound and can be serialized
+#if ONLY_1_1
+		[SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
+#endif
 		public HttpStaticObjectsCollection ()
 		public HttpStaticObjectsCollection ()
 		{
 		{
-			_Objects = new Hashtable();
+			_Objects = new Hashtable ();
+		}
+
+		// this ctor has no security requirements and is used when creating HttpApplicationState
+		internal HttpStaticObjectsCollection (HttpApplicationState appstate)
+		{
+			_Objects = new Hashtable ();
 		}
 		}
 
 
 		public object GetObject (string name)
 		public object GetObject (string name)
@@ -102,6 +115,13 @@ namespace System.Web {
 			get { return false; }
 			get { return false; }
 		}
 		}
 
 
+#if NET_2_0
+		[MonoTODO]
+		public bool NeverAccessed {
+			get { throw new NotImplementedException (); }
+		}
+#endif
+
 		public object SyncRoot {
 		public object SyncRoot {
 			get { return this; }
 			get { return this; }
 		}
 		}
@@ -128,33 +148,41 @@ namespace System.Web {
 			_Objects [name] = obj;
 			_Objects [name] = obj;
 		}
 		}
 
 
-		internal void Serialize (BinaryWriter w)
+#if NET_2_0
+		public void Serialize (BinaryWriter writer)
+#else
+		internal void Serialize (BinaryWriter writer)
+#endif
 		{
 		{
 			lock (_Objects) {
 			lock (_Objects) {
-				w.Write (Count);
+				writer.Write (Count);
 				foreach (string key in _Objects.Keys) {
 				foreach (string key in _Objects.Keys) {
-					w.Write (key);
+					writer.Write (key);
 					object value = _Objects [key];
 					object value = _Objects [key];
 					if (value == null) {
 					if (value == null) {
-						w.Write (System.Web.Util.AltSerialization.NullIndex);
+						writer.Write (System.Web.Util.AltSerialization.NullIndex);
 						continue;
 						continue;
 					}
 					}
 
 
-					System.Web.Util.AltSerialization.SerializeByType (w, value);
+					System.Web.Util.AltSerialization.SerializeByType (writer, value);
 				}
 				}
 			}
 			}
 		}
 		}
 
 
-		internal static HttpStaticObjectsCollection Deserialize (BinaryReader r)
+#if NET_2_0
+		public static HttpStaticObjectsCollection Deserialize (BinaryReader reader)
+#else
+		internal static HttpStaticObjectsCollection Deserialize (BinaryReader reader)
+#endif
 		{
 		{
 			HttpStaticObjectsCollection result = new HttpStaticObjectsCollection ();
 			HttpStaticObjectsCollection result = new HttpStaticObjectsCollection ();
-			for (int i = r.ReadInt32 (); i > 0; i--) {
-				string key = r.ReadString ();
-				int index = r.ReadInt32 ();
+			for (int i = reader.ReadInt32 (); i > 0; i--) {
+				string key = reader.ReadString ();
+				int index = reader.ReadInt32 ();
 				if (index == System.Web.Util.AltSerialization.NullIndex)
 				if (index == System.Web.Util.AltSerialization.NullIndex)
 					result.Set (key, null);
 					result.Set (key, null);
 				else
 				else
-					result.Set (key, System.Web.Util.AltSerialization.DeserializeFromIndex (index, r));
+					result.Set (key, System.Web.Util.AltSerialization.DeserializeFromIndex (index, reader));
 			}
 			}
 
 
 			return result;
 			return result;