2 // InterceptorBindingElement.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2006 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections.ObjectModel;
31 using System.Net.Security;
32 using System.Security.Principal;
33 using System.Security.Cryptography.X509Certificates;
34 using System.ServiceModel;
35 using System.ServiceModel.Channels;
36 using System.ServiceModel.Description;
37 using System.ServiceModel.Security;
38 using System.ServiceModel.Security.Tokens;
39 using System.Security.Cryptography.Xml;
40 using System.Threading;
41 using NUnit.Framework;
43 using MonoTests.System.ServiceModel.Channels;
45 namespace MonoTests.System.ServiceModel.Channels
47 public delegate void InterceptorRequestContextHandler (MessageBuffer src);
49 class InterceptorBindingElement : BindingElement
51 InterceptorRequestContextHandler handler;
53 public InterceptorBindingElement (InterceptorRequestContextHandler handler)
55 this.handler = handler;
58 public InterceptorRequestContextHandler Handler {
59 get { return handler; }
62 public override bool CanBuildChannelListener<TChannel> (BindingContext context)
67 public override bool CanBuildChannelFactory<TChannel> (BindingContext context)
72 public override IChannelListener<TChannel> BuildChannelListener<TChannel> (BindingContext context)
74 return new InterceptorChannelListener<TChannel> (this, context);
77 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (BindingContext context)
79 return new InterceptorChannelFactory<TChannel> (this, context);
82 public override T GetProperty<T> (BindingContext ctx)
84 return ctx.GetInnerProperty<T> ();
87 public override BindingElement Clone ()
93 abstract class DefaultTimeoutCommunicationObject : CommunicationObject
95 IDefaultCommunicationTimeouts timeouts;
96 public DefaultTimeoutCommunicationObject (IDefaultCommunicationTimeouts timeouts)
98 this.timeouts = timeouts;
101 protected override TimeSpan DefaultOpenTimeout {
102 get { return timeouts.OpenTimeout; }
104 protected override TimeSpan DefaultCloseTimeout {
105 get { return timeouts.CloseTimeout; }
109 class InterceptorChannelFactory<TChannel> : ChannelFactoryBase<TChannel>
111 InterceptorBindingElement element;
112 IChannelFactory<TChannel> inner;
114 public InterceptorChannelFactory (InterceptorBindingElement element, BindingContext context)
117 this.element = element;
118 inner = context.BuildInnerChannelFactory<TChannel> ();
121 public InterceptorBindingElement Element {
122 get { return element; }
125 public override T GetProperty<T> ()
127 return inner.GetProperty<T> ();
130 protected override TChannel OnCreateChannel (EndpointAddress address, Uri uri)
132 if (typeof (TChannel) == typeof (IRequestChannel))
133 return (TChannel) (object) new InterceptorRequestChannel (
134 (InterceptorChannelFactory<IRequestChannel>) (object) this,
135 (IRequestChannel) (object) inner.CreateChannel (address, uri));
136 throw new NotImplementedException ();
140 protected override void OnOpen (TimeSpan timeout)
142 inner.Open (timeout);
145 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
147 return inner.BeginOpen (timeout, callback, state);
150 protected override void OnEndOpen (IAsyncResult result)
152 inner.EndOpen (result);
155 protected override void OnClose (TimeSpan timeout)
157 inner.Close (timeout);
160 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
162 return inner.BeginClose (timeout, callback, state);
165 protected override void OnEndClose (IAsyncResult result)
167 inner.EndClose (result);
170 protected override void OnAbort ()
176 class InterceptorChannelListener<TChannel> : ChannelListenerBase<TChannel> where TChannel : class, IChannel
178 InterceptorBindingElement element;
179 IChannelListener<TChannel> inner;
181 public InterceptorChannelListener (InterceptorBindingElement element, BindingContext context)
183 this.element = element;
184 inner = context.BuildInnerChannelListener<TChannel> ();
187 public InterceptorBindingElement Element {
188 get { return element; }
191 public override Uri Uri {
192 get { return inner.Uri; }
195 protected override TChannel OnAcceptChannel (TimeSpan timeout)
197 if (typeof (TChannel) == typeof (IReplyChannel))
198 return (TChannel) (object) new InterceptorReplyChannel (
199 (InterceptorChannelListener<IReplyChannel>) (object) this,
200 (IReplyChannel) (object) inner.AcceptChannel (timeout));
201 throw new NotImplementedException ();
204 protected override IAsyncResult OnBeginAcceptChannel (
205 TimeSpan timeout, AsyncCallback callback, object state)
207 return inner.BeginAcceptChannel (timeout, callback, state);
210 protected override TChannel OnEndAcceptChannel (IAsyncResult result)
212 if (typeof (TChannel) == typeof (IReplyChannel))
213 return (TChannel) (object) new InterceptorReplyChannel (
214 (InterceptorChannelListener<IReplyChannel>) (object) this,
215 (IReplyChannel) (object) inner.EndAcceptChannel (result));
216 throw new NotImplementedException ();
220 protected override bool OnWaitForChannel (TimeSpan timeout)
222 return inner.WaitForChannel (timeout);
225 protected override IAsyncResult OnBeginWaitForChannel (TimeSpan timeout, AsyncCallback callback, object state)
227 return inner.BeginWaitForChannel (timeout, callback, state);
230 protected override bool OnEndWaitForChannel (IAsyncResult result)
232 return inner.EndWaitForChannel (result);
236 protected override void OnAbort ()
241 protected override void OnOpen (TimeSpan timeout)
243 inner.Open (timeout);
246 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
248 return inner.BeginOpen (timeout, callback, state);
251 protected override void OnEndOpen (IAsyncResult result)
253 inner.EndOpen (result);
256 protected override void OnClose (TimeSpan timeout)
258 inner.Close (timeout);
261 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
263 return inner.BeginClose (timeout, callback, state);
266 protected override void OnEndClose (IAsyncResult result)
268 inner.EndClose (result);
272 class InterceptorRequestChannel : ChannelBase, IRequestChannel
274 InterceptorChannelFactory<IRequestChannel> source;
275 IRequestChannel inner;
277 public InterceptorRequestChannel (InterceptorChannelFactory<IRequestChannel> source, IRequestChannel inner)
280 this.source = source;
284 public EndpointAddress RemoteAddress {
285 get { return inner.RemoteAddress; }
289 get { return inner.Via; }
292 public Message Request (Message message)
294 return inner.Request (message);
296 public Message Request (Message message, TimeSpan timeout)
298 return inner.Request (message, timeout);
300 public IAsyncResult BeginRequest (Message message, AsyncCallback callback, object state)
302 return inner.BeginRequest (message, callback, state);
304 public IAsyncResult BeginRequest (Message message, TimeSpan timeout, AsyncCallback callback, object state)
306 return inner.BeginRequest (message, timeout, callback, state);
308 public Message EndRequest (IAsyncResult result)
310 return inner.EndRequest (result);
314 protected override void OnAbort ()
319 protected override void OnOpen (TimeSpan timeout)
321 inner.Open (timeout);
324 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
326 return inner.BeginOpen (timeout, callback, state);
329 protected override void OnEndOpen (IAsyncResult result)
331 inner.EndOpen (result);
334 protected override void OnClose (TimeSpan timeout)
336 inner.Close (timeout);
339 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
341 return inner.BeginClose (timeout, callback, state);
344 protected override void OnEndClose (IAsyncResult result)
346 inner.EndClose (result);
350 class InterceptorReplyChannel : ReplyChannelBase
352 InterceptorChannelListener<IReplyChannel> source;
355 public InterceptorReplyChannel (InterceptorChannelListener<IReplyChannel> source, IReplyChannel inner)
358 this.source = source;
362 public override EndpointAddress LocalAddress {
363 get { return inner.LocalAddress; }
366 RequestContext Inspect (RequestContext src)
368 CopyRequestContext ret = new CopyRequestContext (src);
369 source.Element.Handler (ret.Buffer);
373 public override RequestContext ReceiveRequest ()
375 return Inspect (inner.ReceiveRequest ());
378 public override RequestContext ReceiveRequest (TimeSpan timeout)
380 return Inspect (inner.ReceiveRequest (timeout));
383 public override IAsyncResult BeginReceiveRequest (AsyncCallback callback, object state)
385 return inner.BeginReceiveRequest (callback, state);
388 public override IAsyncResult BeginReceiveRequest (TimeSpan timeout, AsyncCallback callback, object state)
390 return inner.BeginReceiveRequest (timeout, callback, state);
393 public override RequestContext EndReceiveRequest (IAsyncResult result)
395 return Inspect (inner.EndReceiveRequest (result));
398 public override bool TryReceiveRequest (TimeSpan timeout, out RequestContext context)
400 if (inner.TryReceiveRequest (timeout, out context)) {
401 context = Inspect (context);
408 public override IAsyncResult BeginTryReceiveRequest (TimeSpan timeout, AsyncCallback callback, object state)
410 return inner.BeginTryReceiveRequest (timeout, callback, state);
413 public override bool EndTryReceiveRequest (IAsyncResult result, out RequestContext context)
415 if (inner.EndTryReceiveRequest (result, out context)) {
416 context = Inspect (context);
423 public override bool WaitForRequest (TimeSpan timeout)
425 return inner.WaitForRequest (timeout);
428 public override IAsyncResult BeginWaitForRequest (TimeSpan timeout, AsyncCallback callback, object state)
430 return inner.BeginWaitForRequest (timeout, callback, state);
433 public override bool EndWaitForRequest (IAsyncResult result)
435 return inner.EndWaitForRequest (result);
438 protected override void OnAbort ()
443 protected override void OnClose (TimeSpan timeout)
445 inner.Close (timeout);
448 protected override void OnOpen (TimeSpan timeout)
450 inner.Open (timeout);
454 class CopyRequestContext : RequestContext
457 MessageBuffer buffer;
460 public CopyRequestContext (RequestContext src)
463 buffer = src.RequestMessage.CreateBufferedCopy (0x10000);
464 copy_msg = buffer.CreateMessage ();
467 public MessageBuffer Buffer {
468 get { return buffer; }
471 public override void Abort ()
476 public override void Close ()
481 public override void Close (TimeSpan timeout)
486 public override IAsyncResult BeginReply (Message message, AsyncCallback callback, object state)
488 return src.BeginReply (message, callback, state);
491 public override IAsyncResult BeginReply (Message message, TimeSpan timeout, AsyncCallback callback, object state)
493 return src.BeginReply (message, timeout, callback, state);
496 public override void EndReply (IAsyncResult result)
498 src.EndReply (result);
501 public override void Reply (Message message)
506 public override void Reply (Message message, TimeSpan timeout)
508 src.Reply (message, timeout);
511 public override Message RequestMessage {
512 get { return copy_msg; }