* RealProxy.cs: added variables to support proxy bypass when the called CBO is
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Proxies / RemotingProxy.cs
1 //
2 // System.Runtime.Remoting.Proxies.RemotingProxy.cs
3 //
4 // Authors:
5 //   Dietmar Maurer (dietmar@ximian.com)
6 //   Lluis Sanchez Gual (lsg@ctv.es)
7 //
8 // (C) 2001 Ximian, Inc.  http://www.ximian.com
9 //
10
11 using System;
12 using System.Reflection;
13 using System.Runtime.Remoting.Messaging;
14 using System.Runtime.Remoting.Activation;
15 using System.Runtime.Remoting.Channels;
16 using System.Runtime.Remoting.Contexts;
17 using System.Runtime.CompilerServices;
18 using System.Threading;
19
20
21 namespace System.Runtime.Remoting.Proxies
22 {
23
24         public class RemotingProxy : RealProxy 
25         {
26                 static MethodInfo _cache_GetTypeMethod = typeof(System.Object).GetMethod("GetType");\r
27                 static MethodInfo _cache_GetHashCodeMethod = typeof(System.Object).GetMethod("GetHashCode");\r
28 \r
29                 IMessageSink _sink;
30                 bool _hasEnvoySink;
31                 ConstructionCall _ctorCall;
32
33                 internal RemotingProxy (Type type, ClientIdentity identity) : base (type, identity)
34                 {
35                         _sink = identity.ChannelSink;
36                         _hasEnvoySink = false;
37                 }
38
39                 internal RemotingProxy (Type type, string activationUrl, object[] activationAttributes) : base (type)
40                 {
41                         _hasEnvoySink = false;
42                         _ctorCall = ActivationServices.CreateConstructionCall (type, activationUrl, activationAttributes);
43                 }
44
45                 public override IMessage Invoke (IMessage request)
46                 {
47                         MonoMethodMessage mMsg = (MonoMethodMessage) request;
48
49                         if (mMsg.MethodBase.IsConstructor)
50                                 return ActivateRemoteObject (mMsg);
51
52                         if (mMsg.MethodBase == _cache_GetHashCodeMethod)
53                                 return new MethodResponse(ObjectIdentity.GetHashCode(), null, null, request as IMethodCallMessage);\r
54
55                         if (mMsg.MethodBase == _cache_GetTypeMethod)
56                                 return new MethodResponse(GetProxiedType(), null, null, request as IMethodCallMessage);\r
57
58                         mMsg.Uri = _objectIdentity.ObjectUri;
59                         ((IInternalMessage)mMsg).TargetIdentity = _objectIdentity;
60
61                         _objectIdentity.NotifyClientDynamicSinks (true, request, true, false);
62
63                         IMessage response;
64
65                         // Needs to go through the client context sink?
66                         if (Thread.CurrentContext.HasExitSinks && !_hasEnvoySink)
67                                 response = Thread.CurrentContext.GetClientContextSinkChain ().SyncProcessMessage (request);
68                         else
69                                 response = _sink.SyncProcessMessage (request);
70
71                         _objectIdentity.NotifyClientDynamicSinks (false, request, true, false);
72
73                         return response;
74                 }
75
76                 internal void AttachIdentity (Identity identity)
77                 {
78                         _objectIdentity = identity;
79
80                         if (identity is ClientActivatedIdentity)        // It is a CBO
81                         {
82                                 ClientActivatedIdentity cai = (ClientActivatedIdentity)identity;
83                                 _targetContext = cai.Context;
84                                 AttachServer (cai.GetServerObject ());
85                         }
86
87                         if (identity is ClientIdentity)
88                                 ((ClientIdentity)identity).ClientProxy = (MarshalByRefObject) GetTransparentProxy();
89
90                         if (_objectIdentity.EnvoySink != null) 
91                         {
92                                 _sink = _objectIdentity.EnvoySink;
93                                 _hasEnvoySink = true;
94                         }
95                         else 
96                                 _sink = _objectIdentity.ChannelSink;
97
98                         _ctorCall = null;       // Object already constructed
99                 }
100
101                 IMessage ActivateRemoteObject (IMethodMessage request)
102                 {
103                         if (_ctorCall == null)  // It must be a WKO
104                                 return new ReturnMessage (this, new object[0], 0, null, (IMethodCallMessage) request);  // Ignore constructor call for WKOs
105
106                         _ctorCall.CopyFrom (request);
107                         return ActivationServices.Activate (this, _ctorCall);
108                 }
109         }
110 }