2009-06-12 Bill Holmes <billholmes54@gmail.com>
[mono.git] / mcs / class / System.Web / System.Web / HttpContext.cs
1 //
2 // System.Web.HttpContext.cs 
3 //
4 // Author:
5 //      Miguel de Icaza (miguel@novell.com)
6 //      Gonzalo Paniagua Javier (gonzalo@novell.com)
7 //
8
9 //
10 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Collections;
33 using System.Configuration;
34 using System.Globalization;
35 using System.Runtime.Remoting.Messaging;
36 using System.Security.Permissions;
37 using System.Security.Principal;
38 using System.Threading;
39 using System.Web.Caching;
40 using System.Web.Configuration;
41 using System.Web.SessionState;
42 using System.Web.UI;
43 using System.Web.Util;
44 #if NET_2_0
45 using System.Collections.Generic;
46 using System.IO;
47 using System.Reflection;
48 using System.Resources;
49 using System.Web.Compilation;
50 using System.Web.Profile;
51 using CustomErrorMode = System.Web.Configuration.CustomErrorsMode;
52 #endif
53
54 namespace System.Web {
55         // CAS - no InheritanceDemand here as the class is sealed
56         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
57         public sealed partial class HttpContext : IServiceProvider {
58                 internal HttpWorkerRequest WorkerRequest;
59                 HttpApplication app_instance;
60                 HttpRequest request;
61                 HttpResponse response;
62                 HttpSessionState session_state;
63                 HttpServerUtility server;
64                 TraceContext trace_context;
65                 IHttpHandler handler;
66                 string error_page;
67                 bool skip_authorization = false;
68                 IPrincipal user;
69                 object errors;
70                 Hashtable items;
71                 object config_timeout;
72                 int timeout_possible;
73                 DateTime time_stamp = DateTime.UtcNow;
74                 Timer timer;
75                 Thread thread;
76                 bool _isProcessingInclude;
77
78 #if NET_2_0
79                 [ThreadStatic]
80                 static ResourceProviderFactory provider_factory;
81                 [ThreadStatic]
82                 static Dictionary <string, IResourceProvider> resource_providers;
83                 
84 #if TARGET_JVM
85                 const string app_global_res_key = "HttpContext.app_global_res_key";
86                 internal static Assembly AppGlobalResourcesAssembly {
87                         get { return (Assembly) AppDomain.CurrentDomain.GetData (app_global_res_key); }
88                         set { AppDomain.CurrentDomain.SetData (app_global_res_key, value); }
89                 }
90 #else
91                 [ThreadStatic]
92                 static Dictionary <ResourceManagerCacheKey, ResourceManager> resourceManagerCache;
93                 internal static Assembly AppGlobalResourcesAssembly;
94 #endif
95                 ProfileBase profile = null;
96                 LinkedList<IHttpHandler> handlers;
97 #endif
98                 
99                 public HttpContext (HttpWorkerRequest wr)
100                 {
101                         WorkerRequest = wr;
102                         request = new HttpRequest (WorkerRequest, this);
103                         response = new HttpResponse (WorkerRequest, this);
104                 }
105
106                 public HttpContext (HttpRequest request, HttpResponse response)
107                 {
108                         this.request = request;
109                         this.response = response;
110                         
111                 }
112
113                 internal bool IsProcessingInclude {
114                         get { return _isProcessingInclude; }
115                         set { _isProcessingInclude = value; }
116                 }
117
118                 public Exception [] AllErrors {
119                         get {
120                                 if (errors == null)
121                                         return null;
122
123                                 if (errors is Exception){
124                                         Exception [] all = new Exception [1];
125                                         all [0] = (Exception) errors;
126                                         return all;
127                                 } 
128                                 return (Exception []) (((ArrayList) errors).ToArray (typeof (Exception)));
129                         }
130                 }
131
132                 public HttpApplicationState Application {
133                         get {
134                                 return HttpApplicationFactory.ApplicationState;
135                         }
136                 }
137
138                 public HttpApplication ApplicationInstance {
139                         get {
140                                 return app_instance;
141                         }
142
143                         set {
144                                 app_instance = value;
145                         }
146                               
147                 }
148
149                 public Cache Cache {
150                         get {
151                                 return HttpRuntime.Cache;
152                         }
153                 }
154
155                 internal Cache InternalCache {
156                         get {
157                                 return HttpRuntime.InternalCache;
158                         }
159                 }
160                 
161                 //
162                 // The "Current" property is set just after we have constructed it with 
163                 // the 'HttpContext (HttpWorkerRequest)' constructor.
164                 //
165 #if !TARGET_JVM // No remoting CallContext support in Grasshopper
166                 public static HttpContext Current {
167                         get {
168                                 return (HttpContext) CallContext.GetData ("c");
169                         }
170
171                         set {
172                                 CallContext.SetData ("c", value);
173                         }
174                 }
175 #endif
176
177                 public Exception Error {
178                         get {
179                                 if (errors == null || (errors is Exception))
180                                         return (Exception) errors;
181                                 return (Exception) (((ArrayList) errors) [0]);
182                         }
183                 }
184
185                 public IHttpHandler Handler {
186                         get {
187                                 return handler;
188                         }
189
190                         set {
191                                 handler = value;
192                         }
193                 }
194
195                 public bool IsCustomErrorEnabled {
196                         get {
197                                 try {
198                                         return IsCustomErrorEnabledUnsafe;
199                                 }
200                                 catch {
201                                         return false;
202                                 }
203                         }
204                 }
205
206                 internal bool IsCustomErrorEnabledUnsafe {
207                         get {
208 #if NET_2_0
209                                 CustomErrorsSection cfg = (CustomErrorsSection) WebConfigurationManager.GetSection ("system.web/customErrors");
210 #else
211                                 CustomErrorsConfig cfg = null;
212                                 try {
213                                         cfg = (CustomErrorsConfig) GetConfig ("system.web/customErrors");
214                                 } catch {
215                                 }
216
217                                 if (cfg == null)
218                                         return false;
219 #endif
220
221                                 if (cfg.Mode == CustomErrorMode.On)
222                                         return true;
223
224                                 return (cfg.Mode == CustomErrorMode.RemoteOnly) && !Request.IsLocal;
225                         }
226                 }
227 #if !TARGET_JVM
228                 public bool IsDebuggingEnabled {
229                         get { return HttpRuntime.IsDebuggingEnabled; }
230                 }
231 #endif
232                 public IDictionary Items {
233                         get {
234                                 if (items == null)
235                                         items = new Hashtable ();
236                                 return items;
237                         }
238                 }
239
240                 public HttpRequest Request {
241                         get {
242                                 return request;
243                         }
244                 }
245
246                 public HttpResponse Response {
247                         get {
248                                 return response;
249                         }
250                 }
251
252                 public HttpServerUtility Server {
253                         get {
254                                 if (server == null)
255                                         server = new HttpServerUtility (this);
256                                 return server;
257                         }
258                 }
259
260                 public HttpSessionState Session {
261                         get {
262                                 return session_state;
263                         }
264                 }
265
266                 public bool SkipAuthorization {
267                         get {
268                                 return skip_authorization;
269                         }
270
271                         [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
272                         set {
273                                 skip_authorization = value;
274                         }
275                 }
276
277                 public DateTime Timestamp {
278                         get {
279                                 return time_stamp.ToLocalTime ();
280                         }
281                 }
282                 
283                 public TraceContext Trace {
284                         get {
285                                 if (trace_context == null)
286                                         trace_context = new TraceContext (this);
287                                 return trace_context;
288                         }
289                 }
290
291                 public IPrincipal User {
292                         get {
293                                 return user;
294                         }
295
296                         [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
297                         set {
298                                 user = value;
299                         }
300                 }
301
302 #if NET_2_0
303                 internal bool MapRequestHandlerDone {
304                         get;
305                         set;
306                 }
307                 
308                 // The two properties below are defined only when the IIS7 integrated mode is used.
309                 // They are useless under Mono
310                 public RequestNotification CurrentNotification {
311                         get { throw new PlatformNotSupportedException ("This property is not supported on Mono.");  }
312                 }
313
314                 public bool IsPostNotification {
315                         get { throw new PlatformNotSupportedException ("This property is not supported on Mono."); }
316                 }
317                 
318                 internal void PushHandler (IHttpHandler handler)
319                 {
320                         if (handler == null)
321                                 return;
322                         if (handlers == null)
323                                 handlers = new LinkedList <IHttpHandler> ();
324                         handlers.AddLast (handler);
325                 }
326
327                 internal void PopHandler ()
328                 {
329                         if (handlers == null || handlers.Count == 0)
330                                 return;
331                         handlers.RemoveLast ();
332                 }
333                 
334                 IHttpHandler GetCurrentHandler ()
335                 {
336                         if (handlers == null || handlers.Count == 0)
337                                 return null;
338                         
339                         return handlers.Last.Value;
340                 }
341
342                 IHttpHandler GetPreviousHandler ()
343                 {
344                         if (handlers == null || handlers.Count <= 1)
345                                 return null;
346                         LinkedListNode <IHttpHandler> previous = handlers.Last.Previous;
347                         if (previous != null)
348                                 return previous.Value;
349                         return null;
350                 }
351                 
352                 public IHttpHandler CurrentHandler {
353                         get { return GetCurrentHandler (); }
354                 }
355
356                 public IHttpHandler PreviousHandler {
357                         get { return GetPreviousHandler (); }
358                 }
359
360                 internal bool ProfileInitialized {
361                         get { return profile != null; }
362                 }
363
364                 public ProfileBase Profile {
365                         get {
366                                 if (profile == null) {
367                                         if (Request.IsAuthenticated)
368                                                 profile = ProfileBase.Create (User.Identity.Name);
369                                         else
370                                                 profile = ProfileBase.Create (Request.AnonymousID, false);
371                                 }
372                                 return profile;
373                         }
374
375                         internal set {
376                                 profile = value;
377                         }
378                 }
379 #endif
380
381                 public void AddError (Exception errorInfo)
382                 {
383                         if (errors == null){
384                                 errors = errorInfo;
385                                 return;
386                         }
387                         ArrayList l;
388                         if (errors is Exception){
389                                 l = new ArrayList ();
390                                 l.Add (errors);
391                                 errors = l;
392                         } else 
393                                 l = (ArrayList) errors;
394                         l.Add (errorInfo);
395                 }
396
397                 internal void ClearError (Exception e)
398                 {
399                         if (errors == e)
400                                 errors = null;
401                 }
402
403                 internal bool HasError (Exception e)
404                 {
405                         if (errors == e)
406                                 return true;
407
408                         return (errors is ArrayList) ?
409                                 ((ArrayList) errors).Contains (e) : false;
410                 }
411
412                 public void ClearError ()
413                 {
414                         errors = null;
415                 }
416
417 #if NET_2_0
418                 [Obsolete ("use WebConfigurationManager.GetWebApplicationSection")]
419 #endif
420                 public static object GetAppConfig (string name)
421                 {
422                         object o = ConfigurationSettings.GetConfig (name);
423
424                         return o;
425                 }
426
427 #if NET_2_0
428                 [Obsolete ("see GetSection")]
429 #endif
430                 public object GetConfig (string name)
431                 {
432 #if NET_2_0
433                         return GetSection (name);
434 #else
435                         return WebConfigurationSettings.GetConfig (name, this);
436 #endif
437                 }
438
439 #if NET_2_0
440                 static object GetResourceObject (string classKey, string resourceKey, CultureInfo culture, Assembly assembly)
441                 {
442                         ResourceManager rm;
443                         try {
444                                 if (resourceManagerCache == null)
445                                         resourceManagerCache = new Dictionary <ResourceManagerCacheKey, ResourceManager> ();
446                                 
447                                 ResourceManagerCacheKey key = new ResourceManagerCacheKey (classKey, assembly);
448                                 if (!resourceManagerCache.TryGetValue (key, out rm)) {
449                                         rm = new ResourceManager (classKey, assembly);
450                                         rm.IgnoreCase = true;
451                                         resourceManagerCache.Add (key, rm);
452                                 }
453                                 
454                                 return rm.GetObject (resourceKey, culture);
455                         } catch (MissingManifestResourceException) {
456                                 throw;
457                         } catch (Exception ex) {
458                                 throw new HttpException ("Failed to retrieve the specified global resource object.", ex);
459                         }
460                 }
461                 
462                 public static object GetGlobalResourceObject (string classKey, string resourceKey)
463                 {
464                         return GetGlobalResourceObject (classKey, resourceKey, Thread.CurrentThread.CurrentUICulture);
465                 }
466
467                 static bool EnsureProviderFactory ()
468                 {
469                         if (resource_providers == null)
470                                 resource_providers = new Dictionary <string, IResourceProvider> ();
471                         
472                         if (provider_factory != null)
473                                 return true;
474
475                         GlobalizationSection gs = WebConfigurationManager.GetSection ("system.web/globalization") as GlobalizationSection;
476
477                         if (gs == null)
478                                 return false;
479
480                         String rsfTypeName = gs.ResourceProviderFactoryType;
481                         if (String.IsNullOrEmpty (rsfTypeName))
482                                 return false;
483                         
484                         Type rsfType = HttpApplication.LoadType (rsfTypeName, true);
485                         ResourceProviderFactory rpf = Activator.CreateInstance (rsfType) as ResourceProviderFactory;
486                         
487                         if (rpf == null)
488                                 return false;
489
490                         provider_factory = rpf;
491                         return true;
492                 }
493                 
494                 internal static IResourceProvider GetResourceProvider (string key, bool isLocal)
495                 {
496                         if (!EnsureProviderFactory ())
497                                 return null;
498
499                         IResourceProvider rp = null;
500                         if (!resource_providers.TryGetValue (key, out rp)) {
501                                 if (isLocal)
502                                         rp = provider_factory.CreateLocalResourceProvider (key);
503                                 else
504                                         rp = provider_factory.CreateGlobalResourceProvider (key);
505                                 if (rp == null)
506                                         return null;
507                                 resource_providers.Add (key, rp);
508                         }
509
510                         return rp;
511                 }
512
513                 static object GetGlobalObjectFromFactory (string classKey, string resourceKey, CultureInfo culture)
514                 {
515                         // FIXME: Retention of data
516                         IResourceProvider rp = GetResourceProvider (classKey, false);
517                         if (rp == null)
518                                 return null;
519                         
520                         return rp.GetObject (resourceKey, culture);
521                 }
522                 
523                 public static object GetGlobalResourceObject (string classKey, string resourceKey, CultureInfo culture)
524                 {
525                         object ret = GetGlobalObjectFromFactory (classKey, resourceKey, culture);
526                         if (ret != null)
527                                 return ret;
528                         
529                         if (AppGlobalResourcesAssembly == null)
530                                 return null;
531
532                         return GetResourceObject ("Resources." + classKey, resourceKey, culture, AppGlobalResourcesAssembly);
533                 }
534
535                 public static object GetLocalResourceObject (string virtualPath, string resourceKey)
536                 {
537                         return GetLocalResourceObject (virtualPath, resourceKey, Thread.CurrentThread.CurrentUICulture);
538                 }
539
540                 static object GetLocalObjectFromFactory (string virtualPath, string resourceKey, CultureInfo culture)
541                 {
542                         IResourceProvider rp = GetResourceProvider (virtualPath, true);
543                         if (rp == null)
544                                 return null;
545                         
546                         return rp.GetObject (resourceKey, culture);
547                 }
548                 
549                 public static object GetLocalResourceObject (string virtualPath, string resourceKey, CultureInfo culture)
550                 {
551                         if (!VirtualPathUtility.IsAbsolute (virtualPath))
552                                 throw new ArgumentException ("The specified virtualPath was not rooted.");
553
554                         object ret = GetLocalObjectFromFactory (virtualPath, resourceKey, culture);
555                         if (ret != null)
556                                 return ret;
557                         
558                         string path = VirtualPathUtility.GetDirectory (virtualPath);
559                         Assembly asm = AppResourcesCompiler.GetCachedLocalResourcesAssembly (path);
560                         if (asm == null) {
561                                 AppResourcesCompiler ac = new AppResourcesCompiler (path);
562                                 asm = ac.Compile ();
563                                 if (asm == null)
564                                         throw new MissingManifestResourceException ("A resource object was not found at the specified virtualPath.");
565                         }
566                         
567                         path = Path.GetFileName (virtualPath);
568                         return GetResourceObject (path, resourceKey, culture, asm);
569                 }
570
571                 public object GetSection (string name)
572                 {
573                         return WebConfigurationManager.GetSection (name);
574                 }
575
576                 sealed class ResourceManagerCacheKey
577                 {
578                         readonly string _name;
579                         readonly Assembly _asm;
580
581                         public ResourceManagerCacheKey (string name, Assembly asm)
582                         {
583                                 _name = name;
584                                 _asm = asm;
585                         }
586
587                         public override bool Equals (object obj)
588                         {
589                                 if (!(obj is ResourceManagerCacheKey))
590                                         return false;
591                                 ResourceManagerCacheKey key = (ResourceManagerCacheKey) obj;
592                                 return key._asm == _asm && _name.Equals (key._name, StringComparison.Ordinal);
593                         }
594
595                         public override int GetHashCode ()
596                         {
597                                 return _name.GetHashCode () + _asm.GetHashCode ();
598                         }
599                 }
600 #endif
601                 object IServiceProvider.GetService (Type service)
602                 {
603                         if (service == typeof (HttpWorkerRequest))
604                                 return WorkerRequest;
605
606                         //
607                         // We return everything out of properties in case
608                         // they are dynamically computed in some form in the future.
609                         //
610                         if (service == typeof (HttpApplication))
611                                 return ApplicationInstance;
612
613                         if (service == typeof (HttpRequest))
614                                 return Request;
615
616                         if (service == typeof (HttpResponse))
617                                 return Response;
618
619                         if (service == typeof (HttpSessionState))
620                                 return Session;
621
622                         if (service == typeof (HttpApplicationState))
623                                 return Application;
624
625                         if (service == typeof (IPrincipal))
626                                 return User;
627
628                         if (service == typeof (Cache))
629                                 return Cache;
630
631                         if (service == typeof (HttpContext))
632                                 return Current;
633
634                         if (service == typeof (IHttpHandler))
635                                 return Handler;
636
637                         if (service == typeof (HttpServerUtility))
638                                 return Server;
639                         
640                         if (service == typeof (TraceContext))
641                                 return Trace;
642                         
643                         return null;
644                 }
645
646 #if NET_2_0
647                 public void RemapHandler (IHttpHandler handler)
648                 {
649                         if (MapRequestHandlerDone)
650                                 throw new InvalidOperationException ("The RemapHandler method was called after the MapRequestHandler event occurred.");
651                         Handler = handler;
652                 }
653 #endif
654                 
655                 public void RewritePath (string path)
656                 {
657 #if NET_2_0
658                         RewritePath (path, true);
659 #else
660                         RewritePath (path, false);
661 #endif
662                 }
663
664                 public void RewritePath (string filePath, string pathInfo, string queryString)
665                 {
666                         RewritePath (filePath, pathInfo, queryString, false);
667                 }
668
669 #if NET_2_0
670                 public
671 #else
672                 internal
673 #endif
674                 void RewritePath (string path, bool rebaseClientPath)
675                 {
676                         int qmark = path.IndexOf ('?');
677                         if (qmark != -1)
678                                 RewritePath (path.Substring (0, qmark), "", path.Substring (qmark + 1), rebaseClientPath);
679                         else
680                                 RewritePath (path, null, null, rebaseClientPath);
681                 }
682
683 #if NET_2_0
684                 public
685 #else
686                 internal
687 #endif
688                 void RewritePath (string filePath, string pathInfo, string queryString, bool setClientFilePath)
689                 {
690                         if (filePath == null)
691                                 throw new ArgumentNullException ("filePath");
692                         if (!VirtualPathUtility.IsValidVirtualPath (filePath))
693                                 throw new HttpException ("'" + HttpUtility.HtmlEncode (filePath) + "' is not a valid virtual path.");
694
695                         bool pathRelative = VirtualPathUtility.IsAppRelative (filePath);
696                         bool pathAbsolute = pathRelative ? false : VirtualPathUtility.IsAbsolute (filePath);
697                         if (pathRelative || pathAbsolute) {
698                                 bool needSubstring = false;
699
700                                 if (pathRelative && filePath.Length > 1)
701                                         needSubstring = true;
702
703                                 string bvd = Request.BaseVirtualDir;
704                                 if (bvd.Length > 1)
705                                         bvd += "/";
706
707                                 string canonizedFilePath = VirtualPathUtility.Canonize (filePath);
708                                 filePath = VirtualPathUtility.Combine (bvd, needSubstring ? canonizedFilePath.Substring (2) : canonizedFilePath);
709                         } else 
710                                 filePath = VirtualPathUtility.Combine (VirtualPathUtility.GetDirectory (Request.FilePath), filePath);
711                         
712                         if (!StrUtils.StartsWith (filePath, HttpRuntime.AppDomainAppVirtualPath))
713                                 throw new HttpException (404, "The virtual path '" + HttpUtility.HtmlEncode (filePath) + "' maps to another application.", filePath);
714                         
715                         Request.SetCurrentExePath (filePath);
716                         if (setClientFilePath)
717                                 Request.SetFilePath (filePath);
718                         
719                         // A null pathInfo or queryString is ignored and previous values remain untouched
720                         if (pathInfo != null)
721                                 Request.SetPathInfo (pathInfo);
722
723                         if (queryString != null)
724                                 Request.QueryStringRaw = queryString;
725                 }
726
727 #region internals
728                 
729                 internal void SetSession (HttpSessionState state)
730                 {
731                         session_state = state;
732                 }
733
734                 // URL of a page used for error redirection.
735                 internal string ErrorPage {
736                         get {
737                                 return error_page;
738                         }
739
740                         set {
741                                 error_page = value;
742                         }
743                 }
744
745                 internal TimeSpan ConfigTimeout {
746                         get {
747                                 if (config_timeout == null) {
748 #if NET_2_0
749                                         HttpRuntimeSection section = (HttpRuntimeSection)WebConfigurationManager.GetSection ("system.web/httpRuntime");
750                                         config_timeout = section.ExecutionTimeout;
751 #else
752                                         HttpRuntimeConfig config = (HttpRuntimeConfig)
753                                                                 GetConfig ("system.web/httpRuntime");
754                                         config_timeout = new TimeSpan (0, 0, config.ExecutionTimeout);
755 #endif
756                                 }
757
758                                 return (TimeSpan) config_timeout;
759                         }
760
761                         set {
762                                 config_timeout = value;
763 #if !TARGET_J2EE
764                                 if (timer != null) {
765                                         TimeSpan remaining = value - (DateTime.UtcNow - time_stamp);
766                                         long remaining_ms = Math.Max ((long)remaining.TotalMilliseconds, 0);
767
768                                         // See http://msdn2.microsoft.com/en-us/library/7hs7492w.aspx
769                                         if (remaining_ms > 4294967294)
770                                                 remaining_ms = 4294967294;
771                                         
772                                         timer.Change (remaining_ms, (long)Timeout.Infinite);
773                                 }
774 #endif
775                         }
776                 }
777
778 #if !TARGET_J2EE
779                 void TimeoutReached(object state) {
780                         HttpRuntime.QueuePendingRequest (false);
781                         if (Interlocked.CompareExchange (ref timeout_possible, 0, 0) == 0) {
782                                 timer.Change(2000, 0);
783                                 return;                 
784                         }
785                         StopTimeoutTimer();
786                         
787                         thread.Abort (new StepTimeout ());
788                 }
789                 
790                 internal void StartTimeoutTimer() {
791                         thread = Thread.CurrentThread;
792                         timer = new Timer (TimeoutReached, null, (int)ConfigTimeout.TotalMilliseconds, Timeout.Infinite);
793                 }
794                 
795                 internal void StopTimeoutTimer() {
796                         if(timer != null) {
797                                 timer.Dispose ();
798                                 timer = null;
799                         }
800                 }
801
802                 internal bool TimeoutPossible {
803                         get { return (Interlocked.CompareExchange (ref timeout_possible, 1, 1) == 1); }
804                 }
805
806                 internal void BeginTimeoutPossible ()
807                 {
808                         timeout_possible = 1;
809                 }
810
811                 internal void EndTimeoutPossible ()
812                 {
813                         Interlocked.CompareExchange (ref timeout_possible, 0, 1);
814                 }
815 #endif
816 #endregion
817         }
818         
819         class StepTimeout
820         {
821         }
822 }