2 // System.Web.HttpRuntime
5 // Patrik Torstensson (ptorsten@hotmail.com)
6 // Gaurav Vaish (gvaish@iitk.ac.in)
9 using System.Collections;
11 using System.Security;
12 using System.Security.Permissions;
13 using System.Threading;
15 using System.Web.Util;
16 using System.Web.Caching;
18 namespace System.Web {
20 public sealed class HttpRuntime {
22 // Security permission helper objects
23 private static IStackWalk appPathDiscoveryStackWalk;
24 private static IStackWalk ctrlPrincipalStackWalk;
25 private static IStackWalk sensitiveInfoStackWalk;
26 private static IStackWalk unmgdCodeStackWalk;
27 private static IStackWalk unrestrictedStackWalk;
28 private static IStackWalk reflectionStackWalk;
30 private static HttpRuntime _runtime;
31 private static string appDomainAppId;
32 private static string appDomainId;
33 private static string appDomainAppPath;
34 private static string appDomainAppVirtualPath;
37 private int _activeRequests;
38 private HttpWorkerRequest.EndOfSendNotification _endOfSendCallback;
39 private AsyncCallback _handlerCallback;
40 private WaitCallback _appDomainCallback;
42 private bool _firstRequestStarted;
43 private bool _firstRequestExecuted;
44 private DateTime _firstRequestStartTime;
46 private Exception _initError;
50 appPathDiscoveryStackWalk = null;
51 ctrlPrincipalStackWalk = null;
52 sensitiveInfoStackWalk = null;
53 unmgdCodeStackWalk = null;
54 unrestrictedStackWalk = null;
56 _runtime = new HttpRuntime ();
64 static internal object CreateInternalObject(Type type) {
65 return Activator.CreateInstance(type, true);
72 _cache = new Cache ();
74 // TODO: timeout manager
75 // TODO: Load all app domain data
76 // TODO: Trace manager
77 _endOfSendCallback = new HttpWorkerRequest.EndOfSendNotification(OnEndOfSend);
78 _handlerCallback = new AsyncCallback(OnHandlerReady);
79 _appDomainCallback = new WaitCallback(OnAppDomainUnload);
81 catch (Exception error) {
86 private void OnFirstRequestStart() {
87 if (null == _initError) {
88 // TODO: First request initialize (config, trace, request queue)
91 // If we got an error during init, throw to client now..
92 if (null != _initError)
96 private void OnFirstRequestEnd() {
99 private void OnHandlerReady(IAsyncResult ar) {
100 HttpContext context = (HttpContext) ar.AsyncState;
102 IHttpAsyncHandler handler = context.AsyncHandler;
105 handler.EndProcessRequest(ar);
107 catch (Exception error) {
108 context.AddError(error);
112 context.AsyncHandler = null;
115 FinishRequest(context, context.Error);
118 private void OnEndOfSend(HttpWorkerRequest request, object data) {
119 HttpContext context = (HttpContext) data;
121 context.Request.Dispose();
122 context.Response.Dispose();
125 internal void FinishRequest(HttpContext context, Exception error) {
128 context.Response.FlushAtEndOfRequest();
129 } catch (Exception obj) {
134 HttpWorkerRequest request = context.WorkerRequest;
136 WebTrace.WriteLine (error.ToString ());
138 context.Response.Clear ();
139 context.Response.ClearHeaders ();
140 if (!(error is HttpException)) {
141 error = new HttpException (String.Empty, error);
142 context.Response.StatusCode = 500;
144 context.Response.StatusCode = ((HttpException) error).GetHttpCode ();
146 context.Response.Write (((HttpException) error).GetHtmlErrorMessage ());
147 context.Response.FinalFlush ();
150 if (!_firstRequestExecuted) {
152 if (!_firstRequestExecuted) {
154 _firstRequestExecuted = true;
159 Interlocked.Decrement(ref _activeRequests);
162 request.EndOfRequest();
164 // TODO: Schedule more work in request queue
167 private void OnAppDomainUnload(object state) {
172 internal void Dispose() {
173 // TODO: Drain Request queue
174 // TODO: Stop request queue
175 // TODO: Move timeout value to config
176 WaitForRequests(5000);
179 HttpApplicationFactory.EndApplication();
183 internal void WaitForRequests(int ms) {
184 DateTime timeout = DateTime.Now.AddMilliseconds(ms);
187 // TODO: We should check the request queue here also
188 if (_activeRequests == 0)
192 } while (timeout > DateTime.Now);
195 internal void InternalExecuteRequest(HttpWorkerRequest request)
198 throw new ArgumentNullException ("request");
200 IHttpHandler handler;
201 IHttpAsyncHandler async_handler;
203 HttpContext context = new HttpContext(request);
205 request.SetEndOfSendNotification(_endOfSendCallback, context);
207 Interlocked.Increment(ref _activeRequests);
210 if (!_firstRequestStarted) {
212 if (!_firstRequestStarted) {
213 _firstRequestStartTime = DateTime.Now;
215 OnFirstRequestStart();
216 _firstRequestStarted = true;
221 handler = HttpApplicationFactory.GetInstance(context);
223 throw new HttpException(FormatResourceString("unable_to_create_app"));
225 if (handler is IHttpAsyncHandler) {
226 async_handler = (IHttpAsyncHandler) handler;
228 context.AsyncHandler = async_handler;
229 async_handler.BeginProcessRequest(context, _handlerCallback, context);
231 handler.ProcessRequest(context);
232 FinishRequest(context, null);
235 catch (Exception error) {
236 FinishRequest(context, error);
240 public static void ProcessRequest (HttpWorkerRequest Request)
242 // TODO: Request queue
243 _runtime.InternalExecuteRequest(Request);
246 public static Cache Cache {
248 return _runtime._cache;
252 public static string AppDomainAppId {
254 if (appDomainAppId == null)
255 appDomainAppId = (string) AppDomain.CurrentDomain.GetData (".appId");
257 return appDomainAppId;
261 public static string AppDomainAppPath {
263 if (appDomainAppPath == null)
264 appDomainAppPath = (string) AppDomain.CurrentDomain.GetData (".appPath");
266 return appDomainAppPath;
270 public static string AppDomainAppVirtualPath {
272 if (appDomainAppVirtualPath == null)
273 appDomainAppVirtualPath = (string) AppDomain.CurrentDomain.GetData (".appVPath");
275 return appDomainAppVirtualPath;
279 public static string AppDomainId {
281 if (appDomainId == null)
282 appDomainId = (string) AppDomain.CurrentDomain.GetData (".domainId");
289 public static string AspInstallDirectory {
291 throw new NotImplementedException ();
296 public static string BinDirectory {
298 throw new NotImplementedException ();
303 public static string ClrInstallDirectory {
305 throw new NotImplementedException ();
310 public static string CodegenDir {
312 throw new NotImplementedException ();
317 public static bool IsOnUNCShare {
319 throw new NotImplementedException ();
324 public static string MachineConfigurationDirectory {
326 throw new NotImplementedException ();
330 public static void Close ()
335 internal static string FormatResourceString (string key)
337 return GetResourceString (key);
340 internal static string FormatResourceString (string key, string arg0)
342 /*string format = GetResourceString (key);
347 return String.Format (format, arg0);
349 return String.Format ("{0}: {1}", key, arg0);
352 [MonoTODO ("FormatResourceString (string, string, string)")]
353 internal static string FormatResourceString (string key, string arg0, string type) {
354 return String.Format ("{0}: {1} {2}", key, arg0, type);
357 [MonoTODO ("FormatResourceString (string, string, string, string)")]
358 internal static string FormatResourceString (string key, string arg0,
359 string arg1, string arg2)
361 return String.Format ("{0}: {1} {2} {3}", key, arg0, arg1, arg2);
364 [MonoTODO ("FormatResourceString (string, string[]")]
365 internal static string FormatResourceString (string key, string[] args)
367 //StringBuilder sb = new StringBuilder ();
368 /*sb.AppendFormat ("{0}: ", key);
369 foreach (string s in args)
370 sb.AppendFormat ("{0} ", s);
374 return sb.ToString ();*/
375 string s = key + ": ";
377 foreach (string k in args)
382 private static string GetResourceString (string key) {
383 return _runtime.GetResourceStringFromResourceManager (key);
386 [MonoTODO ("GetResourceStringFromResourceManager (string)")]
387 private string GetResourceStringFromResourceManager (string key) {
388 return "String returned by HttpRuntime.GetResourceStringFromResourceManager";
391 #region Security Internal Methods (not impl)
392 [MonoTODO ("Get Application path from the appdomain object")]
393 internal static IStackWalk AppPathDiscovery {
395 if (appPathDiscoveryStackWalk == null) {
396 appPathDiscoveryStackWalk = new FileIOPermission (
397 FileIOPermissionAccess.PathDiscovery, "<apppath>");
399 return appPathDiscoveryStackWalk;
403 internal static IStackWalk ControlPrincipal {
405 if (ctrlPrincipalStackWalk == null) {
406 ctrlPrincipalStackWalk = new SecurityPermission (
407 SecurityPermissionFlag.ControlPrincipal);
409 return ctrlPrincipalStackWalk;
413 internal static IStackWalk Reflection {
415 if (reflectionStackWalk == null) {
416 reflectionStackWalk = new ReflectionPermission (
417 ReflectionPermissionFlag.TypeInformation |
418 ReflectionPermissionFlag.MemberAccess);
420 return reflectionStackWalk;
424 internal static IStackWalk SensitiveInformation {
426 if (sensitiveInfoStackWalk == null) {
427 sensitiveInfoStackWalk = new EnvironmentPermission (
428 PermissionState.Unrestricted);
430 return sensitiveInfoStackWalk;
434 internal static IStackWalk UnmanagedCode {
436 if (unmgdCodeStackWalk == null) {
437 unmgdCodeStackWalk = new SecurityPermission (
438 SecurityPermissionFlag.UnmanagedCode);
440 return unmgdCodeStackWalk;
444 internal static IStackWalk Unrestricted {
446 if (unrestrictedStackWalk == null) {
447 unrestrictedStackWalk = new PermissionSet (
448 PermissionState.Unrestricted);
450 return unrestrictedStackWalk;
454 internal static IStackWalk FileReadAccess (string file)
456 return new FileIOPermission (FileIOPermissionAccess.Read, file);
459 internal static IStackWalk PathDiscoveryAccess (string path)
461 return new FileIOPermission (FileIOPermissionAccess.PathDiscovery, path);