2 // CustomBindingTest.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 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;
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;
41 using NUnit.Framework;
43 using MonoTests.Helpers;
45 namespace MonoTests.System.ServiceModel.Channels
48 public class CustomBindingTest
51 public void DefaultCtor ()
53 CustomBinding cb = new CustomBinding ();
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");
65 class MyBinding : Binding
67 public override string Scheme { get { return "hoge"; } }
69 public override BindingElementCollection CreateBindingElements ()
71 throw new ApplicationException ("HEHE");
76 public void CtorFromAnotherBinding ()
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");
86 Assert.AreEqual (4, cb.CreateBindingElements ().Count, "#9");
89 class MessageVersionBindingElement : BindingElement {
90 public MessageVersion Version {
95 public MessageVersionBindingElement (MessageVersion version)
97 this.Version = version;
100 public override BindingElement Clone ()
102 return new MessageVersionBindingElement (Version);
105 public override T GetProperty<T> (BindingContext context)
107 if (typeof (T) == typeof (MessageVersion))
108 return (T)(object) Version;
114 public void MessageVersionProperty ()
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");
120 var versions = new[] {
121 MessageVersion.Soap11, MessageVersion.Soap11WSAddressing10,
122 MessageVersion.Soap11WSAddressingAugust2004,
123 MessageVersion.Soap12, MessageVersion.Soap12WSAddressing10,
124 MessageVersion.Soap12WSAddressingAugust2004
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);
135 [ExpectedException (typeof (ApplicationException))]
136 public void CtorFromAnotherBindingCallsCreateBindingElement ()
138 new CustomBinding (new MyBinding ());
141 Message reqmsg, resmsg;
144 public void CustomTransportDoesNotRequireMessageEncoding ()
146 ReplyHandler replier = delegate (Message msg) {
150 RequestReceiver receiver = delegate () {
154 RequestSender sender = delegate (Message msg) {
157 CustomBinding br = new CustomBinding (
158 new HandlerTransportBindingElement (replier, receiver));
159 IChannelListener<IReplyChannel> l =
160 br.BuildChannelListener<IReplyChannel> (
161 new BindingParameterCollection ());
163 IReplyChannel rch = l.AcceptChannel ();
165 Message res = Message.CreateMessage (MessageVersion.Default, "urn:succeeded");
166 rch.ReceiveRequest ().Reply (res);
173 CustomBinding bs = new CustomBinding (
174 new HandlerTransportBindingElement (sender));
176 IChannelFactory<IRequestChannel> f =
177 bs.BuildChannelFactory<IRequestChannel> (
178 new BindingParameterCollection ());
180 IRequestChannel ch = f.CreateChannel (new EndpointAddress ("urn:dummy"));
182 Message result = ch.Request (Message.CreateMessage (MessageVersion.Default, "urn:request"));
186 public void TransportBindingElementDefaultMessageVersion ()
188 Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new HandlerTransportBindingElement (null).GetProperty<MessageVersion> (new BindingContext (new CustomBinding (), new BindingParameterCollection ())), "version");
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 ()
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);
206 return buf.CreateMessage ();
209 CustomBinding binding = new CustomBinding (
211 new TextMessageEncodingBindingElement (
212 MessageVersion.None, Encoding.UTF8),
213 new HandlerTransportBindingElement (sender));
215 EndpointAddress address = new EndpointAddress (
216 new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()),
217 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
219 ChannelFactory<IRequestChannel> cf =
220 new ChannelFactory<IRequestChannel> (binding, address);
221 IRequestChannel ch = cf.CreateChannel ();
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");
235 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction"));
242 [Ignore ("it's underway")]
243 [Category ("NotWorking")]
244 public void MessageSecurityManualProtection ()
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);
255 return buf.CreateMessage ();
258 CustomBinding binding = new CustomBinding (
260 new TextMessageEncodingBindingElement (),
261 new HandlerTransportBindingElement (sender));
263 EndpointAddress address = new EndpointAddress (
264 new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()),
265 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
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);
275 SymmetricSecurityBindingElement innersbe =
276 new SymmetricSecurityBindingElement ();
277 innersbe.ProtectionTokenParameters =
278 new X509SecurityTokenParameters ();
279 sbe.ProtectionTokenParameters =
280 new SecureConversationSecurityTokenParameters (
281 innersbe, false, reqs);
284 IChannelFactory<IRequestChannel> cf =
285 binding.BuildChannelFactory<IRequestChannel> (parameters);
287 IRequestChannel ch = cf.CreateChannel (address);
291 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction", new SampleValue ()));
298 [ExpectedException (typeof (InvalidOperationException))]
299 public void CanBuildChannelListenerNoTransport ()
301 CustomBinding cb = new CustomBinding ();
302 BindingContext ctx = new BindingContext (
303 cb, new BindingParameterCollection ());
304 Assert.IsFalse (new TextMessageEncodingBindingElement ().CanBuildChannelListener<IReplyChannel> (ctx), "#1");
308 [ExpectedException (typeof (InvalidOperationException))]
309 public void BuildChannelListenerNoTransport ()
311 CustomBinding cb = new CustomBinding ();
312 BindingContext ctx = new BindingContext (
313 cb, new BindingParameterCollection ());
314 new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
318 [ExpectedException (typeof (ArgumentException))]
319 [Category ("NotWorking")]
320 public void BuildChannelListenerWithDuplicateElement ()
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);
332 [ExpectedException (typeof (InvalidOperationException))]
333 public void BuildChannelListenerWithNoMessageVersion ()
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 ());
346 [ExpectedException (typeof (MyException))]
347 public void BuildChannelListenerWithMessageVersion ()
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 ());
360 [ExpectedException (typeof (InvalidOperationException))]
361 public void RelativeListenUriNoBaseAddress ()
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));
372 [ExpectedException (typeof (MyException))]
373 public void RelativeListenUriWithBaseAddress ()
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));
386 public interface IFooService
389 string Hello (string msg);
391 public class FooService : IFooService
393 public string Hello (string msg)
399 class MyBindingElement : BindingElement
401 public MyBindingElement (bool returnProperty)
403 return_property = returnProperty;
406 bool return_property;
408 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
411 throw new NotImplementedException ();
414 public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
417 throw new MyException ();
420 public override bool CanBuildChannelListener<TChannel> (BindingContext ctx)
425 public override BindingElement Clone ()
427 return new MyBindingElement (return_property);
430 public override T GetProperty<T> (BindingContext context)
432 return return_property ? context.GetInnerProperty<T> () : null;
436 public class MyException : Exception
441 [DataContract (Namespace = "urn:foo")]