Merge pull request #1245 from StephenMcConnel/bug-22483
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel.Channels / InterceptorBindingElement.cs
1 //
2 // InterceptorBindingElement.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 Novell, Inc.  http://www.novell.com
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28 using System;
29 using System.Collections.ObjectModel;
30 using System.Net;
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;
42
43 using MonoTests.System.ServiceModel.Channels;
44
45 namespace MonoTests.System.ServiceModel.Channels
46 {
47         public delegate void InterceptorRequestContextHandler (MessageBuffer src);
48
49         class InterceptorBindingElement : BindingElement
50         {
51                 InterceptorRequestContextHandler handler;
52
53                 public InterceptorBindingElement (InterceptorRequestContextHandler handler)
54                 {
55                         this.handler = handler;
56                 }
57
58                 public InterceptorRequestContextHandler Handler {
59                         get { return handler; }
60                 }
61
62                 public override bool CanBuildChannelListener<TChannel> (BindingContext context)
63                 {
64                         return true;
65                 }
66
67                 public override bool CanBuildChannelFactory<TChannel> (BindingContext context)
68                 {
69                         return true;
70                 }
71
72                 public override IChannelListener<TChannel> BuildChannelListener<TChannel> (BindingContext context)
73                 {
74                         return new InterceptorChannelListener<TChannel> (this, context);
75                 }
76
77                 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (BindingContext context)
78                 {
79                         return new InterceptorChannelFactory<TChannel> (this, context);
80                 }
81
82                 public override T GetProperty<T> (BindingContext ctx)
83                 {
84                         return ctx.GetInnerProperty<T> ();
85                 }
86
87                 public override BindingElement Clone ()
88                 {
89                         return this;
90                 }
91         }
92
93         abstract class DefaultTimeoutCommunicationObject : CommunicationObject
94         {
95                 IDefaultCommunicationTimeouts timeouts;
96                 public DefaultTimeoutCommunicationObject (IDefaultCommunicationTimeouts timeouts)
97                 {
98                         this.timeouts = timeouts;
99                 }
100
101                 protected override TimeSpan DefaultOpenTimeout {
102                         get { return timeouts.OpenTimeout; }
103                 }
104                 protected override TimeSpan DefaultCloseTimeout {
105                         get { return timeouts.CloseTimeout; }
106                 }
107         }
108
109         class InterceptorChannelFactory<TChannel> : ChannelFactoryBase<TChannel>
110         {
111                 InterceptorBindingElement element;
112                 IChannelFactory<TChannel> inner;
113
114                 public InterceptorChannelFactory (InterceptorBindingElement element, BindingContext context)
115                         : base (null)
116                 {
117                         this.element = element;
118                         inner = context.BuildInnerChannelFactory<TChannel> ();
119                 }
120
121                 public InterceptorBindingElement Element {
122                         get { return element; }
123                 }
124
125                 public override T GetProperty<T> ()
126                 {
127                         return inner.GetProperty<T> ();
128                 }
129
130                 protected override TChannel OnCreateChannel (EndpointAddress address, Uri uri)
131                 {
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 ();
137                 }
138
139
140                 protected override void OnOpen (TimeSpan timeout)
141                 {
142                         inner.Open (timeout);
143                 }
144
145                 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
146                 {
147                         return inner.BeginOpen (timeout, callback, state);
148                 }
149
150                 protected override void OnEndOpen (IAsyncResult result)
151                 {
152                         inner.EndOpen (result);
153                 }
154
155                 protected override void OnClose (TimeSpan timeout)
156                 {
157                         inner.Close (timeout);
158                 }
159
160                 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
161                 {
162                         return inner.BeginClose (timeout, callback, state);
163                 }
164
165                 protected override void OnEndClose (IAsyncResult result)
166                 {
167                         inner.EndClose (result);
168                 }
169
170                 protected override void OnAbort ()
171                 {
172                         inner.Abort ();
173                 }
174         }
175
176         class InterceptorChannelListener<TChannel> : ChannelListenerBase<TChannel> where TChannel : class, IChannel
177         {
178                 InterceptorBindingElement element;
179                 IChannelListener<TChannel> inner;
180
181                 public InterceptorChannelListener (InterceptorBindingElement element, BindingContext context)
182                 {
183                         this.element = element;
184                         inner = context.BuildInnerChannelListener<TChannel> ();
185                 }
186
187                 public InterceptorBindingElement Element {
188                         get { return element; }
189                 }
190
191                 public override Uri Uri {
192                         get { return inner.Uri; }
193                 }
194
195                 protected override TChannel OnAcceptChannel (TimeSpan timeout)
196                 {
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 ();
202                 }
203
204                 protected override IAsyncResult OnBeginAcceptChannel (
205                         TimeSpan timeout, AsyncCallback callback, object state)
206                 {
207                         return inner.BeginAcceptChannel (timeout, callback, state);
208                 }
209
210                 protected override TChannel OnEndAcceptChannel (IAsyncResult result)
211                 {
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 ();
217                 }
218
219
220                 protected override bool OnWaitForChannel (TimeSpan timeout)
221                 {
222                         return inner.WaitForChannel (timeout);
223                 }
224
225                 protected override IAsyncResult OnBeginWaitForChannel (TimeSpan timeout, AsyncCallback callback, object state)
226                 {
227                         return inner.BeginWaitForChannel (timeout, callback, state);
228                 }
229
230                 protected override bool OnEndWaitForChannel (IAsyncResult result)
231                 {
232                         return inner.EndWaitForChannel (result);
233                 }
234
235
236                 protected override void OnAbort ()
237                 {
238                         inner.Abort ();
239                 }
240
241                 protected override void OnOpen (TimeSpan timeout)
242                 {
243                         inner.Open (timeout);
244                 }
245
246                 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
247                 {
248                         return inner.BeginOpen (timeout, callback, state);
249                 }
250
251                 protected override void OnEndOpen (IAsyncResult result)
252                 {
253                         inner.EndOpen (result);
254                 }
255
256                 protected override void OnClose (TimeSpan timeout)
257                 {
258                         inner.Close (timeout);
259                 }
260
261                 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
262                 {
263                         return inner.BeginClose (timeout, callback, state);
264                 }
265
266                 protected override void OnEndClose (IAsyncResult result)
267                 {
268                         inner.EndClose (result);
269                 }
270         }
271
272         class InterceptorRequestChannel : ChannelBase, IRequestChannel
273         {
274                 InterceptorChannelFactory<IRequestChannel> source;
275                 IRequestChannel inner;
276
277                 public InterceptorRequestChannel (InterceptorChannelFactory<IRequestChannel> source, IRequestChannel inner)
278                         : base (source)
279                 {
280                         this.source = source;
281                         this.inner = inner;
282                 }
283
284                 public EndpointAddress RemoteAddress {
285                         get { return inner.RemoteAddress; }
286                 }
287
288                 public Uri Via {
289                         get { return inner.Via; }
290                 }
291
292                 public Message Request (Message message)
293                 {
294                         return inner.Request (message);
295                 }
296                 public Message Request (Message message, TimeSpan timeout)
297                 {
298                         return inner.Request (message, timeout);
299                 }
300                 public IAsyncResult BeginRequest (Message message, AsyncCallback callback, object state)
301                 {
302                         return inner.BeginRequest (message, callback, state);
303                 }
304                 public IAsyncResult BeginRequest (Message message, TimeSpan timeout, AsyncCallback callback, object state)
305                 {
306                         return inner.BeginRequest (message, timeout, callback, state);
307                 }
308                 public Message EndRequest (IAsyncResult result)
309                 {
310                         return inner.EndRequest (result);
311                 }
312
313
314                 protected override void OnAbort ()
315                 {
316                         inner.Abort ();
317                 }
318
319                 protected override void OnOpen (TimeSpan timeout)
320                 {
321                         inner.Open (timeout);
322                 }
323
324                 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
325                 {
326                         return inner.BeginOpen (timeout, callback, state);
327                 }
328
329                 protected override void OnEndOpen (IAsyncResult result)
330                 {
331                         inner.EndOpen (result);
332                 }
333
334                 protected override void OnClose (TimeSpan timeout)
335                 {
336                         inner.Close (timeout);
337                 }
338
339                 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
340                 {
341                         return inner.BeginClose (timeout, callback, state);
342                 }
343
344                 protected override void OnEndClose (IAsyncResult result)
345                 {
346                         inner.EndClose (result);
347                 }
348         }
349
350         class InterceptorReplyChannel : ReplyChannelBase
351         {
352                 InterceptorChannelListener<IReplyChannel> source;
353                 IReplyChannel inner;
354
355                 public InterceptorReplyChannel (InterceptorChannelListener<IReplyChannel> source, IReplyChannel inner)
356                         : base (source)
357                 {
358                         this.source = source;
359                         this.inner = inner;
360                 }
361
362                 public override EndpointAddress LocalAddress {
363                         get { return inner.LocalAddress; }
364                 }
365
366                 RequestContext Inspect (RequestContext src)
367                 {
368                         CopyRequestContext ret = new CopyRequestContext (src);
369                         source.Element.Handler (ret.Buffer);
370                         return ret;
371                 }
372
373                 public override RequestContext ReceiveRequest ()
374                 {
375                         return Inspect (inner.ReceiveRequest ());
376                 }
377
378                 public override RequestContext ReceiveRequest (TimeSpan timeout)
379                 {
380                         return Inspect (inner.ReceiveRequest (timeout));
381                 }
382
383                 public override IAsyncResult BeginReceiveRequest (AsyncCallback callback, object state)
384                 {
385                         return inner.BeginReceiveRequest (callback, state);
386                 }
387
388                 public override IAsyncResult BeginReceiveRequest (TimeSpan timeout, AsyncCallback callback, object state)
389                 {
390                         return inner.BeginReceiveRequest (timeout, callback, state);
391                 }
392
393                 public override RequestContext EndReceiveRequest (IAsyncResult result)
394                 {
395                         return Inspect (inner.EndReceiveRequest (result));
396                 }
397
398                 public override bool TryReceiveRequest (TimeSpan timeout, out RequestContext context)
399                 {
400                         if (inner.TryReceiveRequest (timeout, out context)) {
401                                 context = Inspect (context);
402                                 return true;
403                         }
404                         context = null;
405                         return false;
406                 }
407
408                 public override IAsyncResult BeginTryReceiveRequest (TimeSpan timeout, AsyncCallback callback, object state)
409                 {
410                         return inner.BeginTryReceiveRequest (timeout, callback, state);
411                 }
412
413                 public override bool EndTryReceiveRequest (IAsyncResult result, out RequestContext context)
414                 {
415                         if (inner.EndTryReceiveRequest (result, out context)) {
416                                 context = Inspect (context);
417                                 return true;
418                         }
419                         context = null;
420                         return false;
421                 }
422
423                 public override bool WaitForRequest (TimeSpan timeout)
424                 {
425                         return inner.WaitForRequest (timeout);
426                 }
427
428                 public override IAsyncResult BeginWaitForRequest (TimeSpan timeout, AsyncCallback callback, object state)
429                 {
430                         return inner.BeginWaitForRequest (timeout, callback, state);
431                 }
432
433                 public override bool EndWaitForRequest (IAsyncResult result)
434                 {
435                         return inner.EndWaitForRequest (result);
436                 }
437
438                 protected override void OnAbort ()
439                 {
440                         inner.Abort ();
441                 }
442
443                 protected override void OnClose (TimeSpan timeout)
444                 {
445                         inner.Close (timeout);
446                 }
447
448                 protected override void OnOpen (TimeSpan timeout)
449                 {
450                         inner.Open (timeout);
451                 }
452         }
453
454         class CopyRequestContext : RequestContext
455         {
456                 RequestContext src;
457                 MessageBuffer buffer;
458                 Message copy_msg;
459
460                 public CopyRequestContext (RequestContext src)
461                 {
462                         this.src = src;
463                         buffer = src.RequestMessage.CreateBufferedCopy (0x10000);
464                         copy_msg = buffer.CreateMessage ();
465                 }
466
467                 public MessageBuffer Buffer {
468                         get { return buffer; }
469                 }
470
471                 public override void Abort ()
472                 {
473                         src.Abort ();
474                 }
475
476                 public override void Close ()
477                 {
478                         src.Close ();
479                 }
480
481                 public override void Close (TimeSpan timeout)
482                 {
483                         src.Close (timeout);
484                 }
485
486                 public override IAsyncResult BeginReply (Message message, AsyncCallback callback, object state)
487                 {
488                         return src.BeginReply (message, callback, state);
489                 }
490
491                 public override IAsyncResult BeginReply (Message message, TimeSpan timeout, AsyncCallback callback, object state)
492                 {
493                         return src.BeginReply (message, timeout, callback, state);
494                 }
495
496                 public override void EndReply (IAsyncResult result)
497                 {
498                         src.EndReply (result);
499                 }
500
501                 public override void Reply (Message message)
502                 {
503                         src.Reply (message);
504                 }
505
506                 public override void Reply (Message message, TimeSpan timeout)
507                 {
508                         src.Reply (message, timeout);
509                 }
510
511                 public override Message RequestMessage {
512                         get { return copy_msg; }
513                 }
514         }
515 }