Merge pull request #1870 from saper/langinfo_h
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel.Channels / CustomBindingTest.cs
1 //
2 // CustomBindingTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 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.Security;
31 using System.IdentityModel.Tokens;
32 using System.Runtime.Serialization;
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.Text;
40 using System.Xml;
41 using NUnit.Framework;
42
43 using MonoTests.Helpers;
44
45 namespace MonoTests.System.ServiceModel.Channels
46 {
47         [TestFixture]
48         public class CustomBindingTest
49         {
50                 [Test]
51                 public void DefaultCtor ()
52                 {
53                         CustomBinding cb = new CustomBinding ();
54                         
55                         Assert.AreEqual (0, cb.Elements.Count, "#1");
56                         Assert.AreEqual ("CustomBinding", cb.Name, "#3");
57                         Assert.AreEqual ("http://tempuri.org/", cb.Namespace, "#4");
58                         Assert.AreEqual (TimeSpan.FromMinutes (1), cb.OpenTimeout, "#5");
59                         Assert.AreEqual (TimeSpan.FromMinutes (1), cb.CloseTimeout, "#6");
60                         Assert.AreEqual (TimeSpan.FromMinutes (1), cb.SendTimeout, "#7");
61                         Assert.AreEqual (TimeSpan.FromMinutes (10), cb.ReceiveTimeout, "#8");
62                         Assert.AreEqual (0, cb.CreateBindingElements ().Count, "#9");
63                 }
64
65                 class MyBinding : Binding
66                 {
67                         public override string Scheme { get { return "hoge"; } }
68
69                         public override BindingElementCollection CreateBindingElements ()
70                         {
71                                 throw new ApplicationException ("HEHE");
72                         }
73                 }
74
75                 [Test]
76                 public void CtorFromAnotherBinding ()
77                 {
78                         CustomBinding cb =
79                                 new CustomBinding (new WSHttpBinding ());
80                         // Its properties become mostly copy of the original one
81                         Assert.AreEqual (4, cb.Elements.Count, "#1");
82                         Assert.AreEqual ("http", cb.Scheme, "#2");
83                         Assert.AreEqual ("WSHttpBinding", cb.Name, "#3");
84                         Assert.AreEqual ("http://tempuri.org/", cb.Namespace, "#4");
85
86                         Assert.AreEqual (4, cb.CreateBindingElements ().Count, "#9");
87                 }
88
89                 class MessageVersionBindingElement : BindingElement {
90                         public MessageVersion Version {
91                                 get;
92                                 private set;
93                         }
94                         
95                         public MessageVersionBindingElement (MessageVersion version)
96                         {
97                                 this.Version = version;
98                         }
99                         
100                         public override BindingElement Clone ()
101                         {
102                                 return new MessageVersionBindingElement (Version);
103                         }
104                         
105                         public override T GetProperty<T> (BindingContext context)
106                         {
107                                 if (typeof (T) == typeof (MessageVersion))
108                                         return (T)(object) Version;
109                                 return null;
110                         }
111                 }
112                 
113                 [Test]
114                 public void MessageVersionProperty ()
115                 {
116                         Assert.IsNull (new CustomBinding ().MessageVersion, "#1");
117                         Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new CustomBinding (new HttpTransportBindingElement ()).MessageVersion, "#2");
118                         Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new CustomBinding (new TextMessageEncodingBindingElement ()).MessageVersion, "#3");
119
120                         var versions = new[] {
121                                 MessageVersion.Soap11, MessageVersion.Soap11WSAddressing10,
122                                 MessageVersion.Soap11WSAddressingAugust2004,
123                                 MessageVersion.Soap12, MessageVersion.Soap12WSAddressing10,
124                                 MessageVersion.Soap12WSAddressingAugust2004
125                         };
126                         
127                         foreach (var version in versions) {
128                                 var binding = new CustomBinding ();
129                                 binding.Elements.Add (new MessageVersionBindingElement (version));
130                                 Assert.AreEqual (version, binding.MessageVersion, "#4:" + version);
131                         }
132                 }
133
134                 [Test]
135                 [ExpectedException (typeof (ApplicationException))]
136                 public void CtorFromAnotherBindingCallsCreateBindingElement ()
137                 {
138                         new CustomBinding (new MyBinding ());
139                 }
140
141                 Message reqmsg, resmsg;
142
143                 [Test]
144                 public void CustomTransportDoesNotRequireMessageEncoding ()
145                 {
146                         ReplyHandler replier = delegate (Message msg) {
147                                 resmsg = msg;
148                         };
149
150                         RequestReceiver receiver = delegate () {
151                                 return reqmsg;
152                         };
153
154                         RequestSender sender = delegate (Message msg) {
155                                 reqmsg = msg;
156
157                                 CustomBinding br = new CustomBinding (
158                                         new HandlerTransportBindingElement (replier, receiver));
159                                 IChannelListener<IReplyChannel> l =
160                                         br.BuildChannelListener<IReplyChannel> (
161                                                 new BindingParameterCollection ());
162                                 l.Open ();
163                                 IReplyChannel rch = l.AcceptChannel ();
164                                 rch.Open ();
165                                 Message res = Message.CreateMessage (MessageVersion.Default, "urn:succeeded");
166                                 rch.ReceiveRequest ().Reply (res);
167                                 rch.Close ();
168                                 l.Close ();
169
170                                 return resmsg;
171                         };
172
173                         CustomBinding bs = new CustomBinding (
174                                 new HandlerTransportBindingElement (sender));
175
176                         IChannelFactory<IRequestChannel> f =
177                                 bs.BuildChannelFactory<IRequestChannel> (
178                                         new BindingParameterCollection ());
179                         f.Open ();
180                         IRequestChannel ch = f.CreateChannel (new EndpointAddress ("urn:dummy"));
181                         ch.Open ();
182                         Message result = ch.Request (Message.CreateMessage (MessageVersion.Default, "urn:request"));
183                 }
184
185                 [Test]
186                 public void TransportBindingElementDefaultMessageVersion ()
187                 {
188                         Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new HandlerTransportBindingElement (null).GetProperty<MessageVersion> (new BindingContext (new CustomBinding (), new BindingParameterCollection ())), "version");
189                 }
190
191                 [Test]
192                 [ExpectedException (typeof (InvalidOperationException))]
193                 //  Envelope Version 'EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none)'
194                 // does not support adding Message Headers.
195                 public void MessageSecurityPOX ()
196                 {
197                         SymmetricSecurityBindingElement sbe =
198                                 new SymmetricSecurityBindingElement ();
199                         sbe.ProtectionTokenParameters =
200                                 new X509SecurityTokenParameters ();
201                         RequestSender sender = delegate (Message input) {
202                                 MessageBuffer buf = input.CreateBufferedCopy (0x10000);
203                                 using (XmlWriter w = XmlWriter.Create (Console.Error)) {
204                                         buf.CreateMessage ().WriteMessage (w);
205                                 }
206                                 return buf.CreateMessage ();
207                         };
208
209                         CustomBinding binding = new CustomBinding (
210                                 sbe,
211                                 new TextMessageEncodingBindingElement (
212                                         MessageVersion.None, Encoding.UTF8),
213                                 new HandlerTransportBindingElement (sender));
214
215                         EndpointAddress address = new EndpointAddress (
216                                 new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()),
217                                 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
218
219                         ChannelFactory<IRequestChannel> cf =
220                                 new ChannelFactory<IRequestChannel> (binding, address);
221                         IRequestChannel ch = cf.CreateChannel ();
222 /*
223                         // neither of Endpoint, Contract nor its Operation seems
224                         // to have applicable behaviors (except for
225                         // ClientCredentials)
226                         Assert.AreEqual (1, cf.Endpoint.Behaviors.Count, "EndpointBehavior");
227                         Assert.AreEqual (0, cf.Endpoint.Contract.Behaviors.Count, "ContractBehavior");
228                         Assert.AreEqual (1, cf.Endpoint.Contract.Operations.Count, "Operations");
229                         OperationDescription od = cf.Endpoint.Contract.Operations [0];
230                         Assert.AreEqual (0, od.Behaviors.Count, "OperationBehavior");
231 */
232
233                         ch.Open ();
234                         try {
235                                 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction"));
236                         } finally {
237                                 ch.Close ();
238                         }
239                 }
240
241                 [Test]
242                 [Ignore ("it's underway")]
243                 [Category ("NotWorking")]
244                 public void MessageSecurityManualProtection ()
245                 {
246                         SymmetricSecurityBindingElement sbe =
247                                 new SymmetricSecurityBindingElement ();
248                         sbe.ProtectionTokenParameters =
249                                 new X509SecurityTokenParameters ();
250                         RequestSender sender = delegate (Message input) {
251                                 MessageBuffer buf = input.CreateBufferedCopy (0x10000);
252                                 using (XmlWriter w = XmlWriter.Create (Console.Error)) {
253                                         buf.CreateMessage ().WriteMessage (w);
254                                 }
255                                 return buf.CreateMessage ();
256                         };
257
258                         CustomBinding binding = new CustomBinding (
259                                 sbe,
260                                 new TextMessageEncodingBindingElement (),
261                                 new HandlerTransportBindingElement (sender));
262
263                         EndpointAddress address = new EndpointAddress (
264                                 new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()),
265                                 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
266
267                         ChannelProtectionRequirements reqs =
268                                 new ChannelProtectionRequirements ();
269                         reqs.OutgoingSignatureParts.AddParts (
270                                 new MessagePartSpecification (new XmlQualifiedName ("SampleValue", "urn:foo")), "urn:myaction");
271                         BindingParameterCollection parameters =
272                                 new BindingParameterCollection ();
273                         parameters.Add (reqs);
274 /*
275                         SymmetricSecurityBindingElement innersbe =
276                                 new SymmetricSecurityBindingElement ();
277                         innersbe.ProtectionTokenParameters =
278                                 new X509SecurityTokenParameters ();
279                         sbe.ProtectionTokenParameters =
280                                 new SecureConversationSecurityTokenParameters (
281                                         innersbe, false, reqs);
282 */
283
284                         IChannelFactory<IRequestChannel> cf =
285                                 binding.BuildChannelFactory<IRequestChannel> (parameters);
286                         cf.Open ();
287                         IRequestChannel ch = cf.CreateChannel (address);
288
289                         ch.Open ();
290                         try {
291                                 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction", new SampleValue ()));
292                         } finally {
293                                 ch.Close ();
294                         }
295                 }
296
297                 [Test]
298                 [ExpectedException (typeof (InvalidOperationException))]
299                 public void CanBuildChannelListenerNoTransport ()
300                 {
301                         CustomBinding cb = new CustomBinding ();
302                         BindingContext ctx = new BindingContext (
303                                 cb, new BindingParameterCollection ());
304                         Assert.IsFalse (new TextMessageEncodingBindingElement ().CanBuildChannelListener<IReplyChannel> (ctx), "#1");
305                 }
306
307                 [Test]
308                 [ExpectedException (typeof (InvalidOperationException))]
309                 public void BuildChannelListenerNoTransport ()
310                 {
311                         CustomBinding cb = new CustomBinding ();
312                         BindingContext ctx = new BindingContext (
313                                 cb, new BindingParameterCollection ());
314                         new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
315                 }
316
317                 [Test]
318                 [ExpectedException (typeof (ArgumentException))]
319                 [Category ("NotWorking")]
320                 public void BuildChannelListenerWithDuplicateElement ()
321                 {
322                         CustomBinding cb = new CustomBinding (
323                                 new TextMessageEncodingBindingElement (),
324                                 new HttpTransportBindingElement ());
325                         BindingContext ctx = new BindingContext (
326                                 cb, new BindingParameterCollection (),
327                                 new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()), String.Empty, ListenUriMode.Unique);
328                         new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
329                 }
330
331                 [Test]
332                 [ExpectedException (typeof (InvalidOperationException))]
333                 public void BuildChannelListenerWithNoMessageVersion ()
334                 {
335                         // MyBindingElement overrides GetProperty<T>() without calling GetInnerProperty<T>() and returns null in this case.
336                         // ServiceHost.Open() tries to get MessageVersion and raises an error if it cannot get any.
337                         // HttpTransportBindingElement can actually provide one.
338                         ServiceHost host = new ServiceHost (typeof (FooService));
339                         host.AddServiceEndpoint (typeof (IFooService),
340                                 new CustomBinding (new MyBindingElement (false), new HttpTransportBindingElement ()),
341                                 "http://localhost:" + NetworkHelpers.FindFreePort ());
342                         host.Open ();
343                 }
344
345                 [Test]
346                 [ExpectedException (typeof (MyException))]
347                 public void BuildChannelListenerWithMessageVersion ()
348                 {
349                         // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
350                         // HttpTransportBindingElement should return Soap11.
351                         ServiceHost host = new ServiceHost (typeof (FooService));
352                         host.AddServiceEndpoint (typeof (IFooService),
353                                 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
354                                 "http://localhost:" + NetworkHelpers.FindFreePort ());
355                         host.Open ();
356                         host.Close ();
357                 }
358
359                 [Test]
360                 [ExpectedException (typeof (InvalidOperationException))]
361                 public void RelativeListenUriNoBaseAddress ()
362                 {
363                         // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
364                         // HttpTransportBindingElement should return Soap11.
365                         ServiceHost host = new ServiceHost (typeof (FooService));
366                         host.AddServiceEndpoint (typeof (IFooService),
367                                 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
368                                 "http://localhost:" + NetworkHelpers.FindFreePort (), new Uri ("foobar", UriKind.Relative));
369                 }
370
371                 [Test]
372                 [ExpectedException (typeof (MyException))]
373                 public void RelativeListenUriWithBaseAddress ()
374                 {
375                         // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
376                         // HttpTransportBindingElement should return Soap11.
377                         ServiceHost host = new ServiceHost (typeof (FooService), new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()));
378                         host.AddServiceEndpoint (typeof (IFooService),
379                                 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
380                                 "http://localhost:" + NetworkHelpers.FindFreePort (), new Uri ("foobar", UriKind.Relative));
381                         host.Open ();
382                         host.Close ();
383                 }
384                 
385                 [ServiceContract]
386                 public interface IFooService
387                 {
388                         [OperationContract]
389                         string Hello (string msg);
390                 }
391                 public class FooService : IFooService
392                 {
393                         public string Hello (string msg)
394                         {
395                                 return "hello";
396                         }
397                 }
398
399                 class MyBindingElement : BindingElement
400                 {
401                         public MyBindingElement (bool returnProperty)
402                         {
403                                 return_property = returnProperty;
404                         }
405                         
406                         bool return_property;
407
408                         public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
409                                 BindingContext ctx)
410                         {
411                                 throw new NotImplementedException ();
412                         }
413
414                         public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
415                                 BindingContext ctx)
416                         {
417                                 throw new MyException ();
418                         }
419
420                         public override bool CanBuildChannelListener<TChannel> (BindingContext ctx)
421                         {
422                                 return true;
423                         }
424
425                         public override BindingElement Clone ()
426                         {
427                                 return new MyBindingElement (return_property);
428                         }
429
430                         public override T GetProperty<T> (BindingContext context)
431                         {
432                                 return return_property ? context.GetInnerProperty<T> () : null;
433                         }
434                 }
435                 
436                 public class MyException : Exception
437                 {
438                 }
439         }
440
441         [DataContract (Namespace = "urn:foo")]
442         class SampleValue
443         {
444         }
445 }