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 namespace MonoTests.System.ServiceModel.Channels
46 public class CustomBindingTest
49 public void DefaultCtor ()
51 CustomBinding cb = new CustomBinding ();
53 Assert.AreEqual (0, cb.Elements.Count, "#1");
54 Assert.AreEqual ("CustomBinding", cb.Name, "#3");
55 Assert.AreEqual ("http://tempuri.org/", cb.Namespace, "#4");
56 Assert.AreEqual (TimeSpan.FromMinutes (1), cb.OpenTimeout, "#5");
57 Assert.AreEqual (TimeSpan.FromMinutes (1), cb.CloseTimeout, "#6");
58 Assert.AreEqual (TimeSpan.FromMinutes (1), cb.SendTimeout, "#7");
59 Assert.AreEqual (TimeSpan.FromMinutes (10), cb.ReceiveTimeout, "#8");
60 Assert.AreEqual (0, cb.CreateBindingElements ().Count, "#9");
63 class MyBinding : Binding
65 public override string Scheme { get { return "hoge"; } }
67 public override BindingElementCollection CreateBindingElements ()
69 throw new ApplicationException ("HEHE");
74 public void CtorFromAnotherBinding ()
77 new CustomBinding (new WSHttpBinding ());
78 // Its properties become mostly copy of the original one
79 Assert.AreEqual (4, cb.Elements.Count, "#1");
80 Assert.AreEqual ("http", cb.Scheme, "#2");
81 Assert.AreEqual ("WSHttpBinding", cb.Name, "#3");
82 Assert.AreEqual ("http://tempuri.org/", cb.Namespace, "#4");
84 Assert.AreEqual (4, cb.CreateBindingElements ().Count, "#9");
87 class MessageVersionBindingElement : BindingElement {
88 public MessageVersion Version {
93 public MessageVersionBindingElement (MessageVersion version)
95 this.Version = version;
98 public override BindingElement Clone ()
100 return new MessageVersionBindingElement (Version);
103 public override T GetProperty<T> (BindingContext context)
105 if (typeof (T) == typeof (MessageVersion))
106 return (T)(object) Version;
112 public void MessageVersionProperty ()
114 Assert.IsNull (new CustomBinding ().MessageVersion, "#1");
115 Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new CustomBinding (new HttpTransportBindingElement ()).MessageVersion, "#2");
116 Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new CustomBinding (new TextMessageEncodingBindingElement ()).MessageVersion, "#3");
118 var versions = new[] {
119 MessageVersion.Soap11, MessageVersion.Soap11WSAddressing10,
120 MessageVersion.Soap11WSAddressingAugust2004,
121 MessageVersion.Soap12, MessageVersion.Soap12WSAddressing10,
122 MessageVersion.Soap12WSAddressingAugust2004
125 foreach (var version in versions) {
126 var binding = new CustomBinding ();
127 binding.Elements.Add (new MessageVersionBindingElement (version));
128 Assert.AreEqual (version, binding.MessageVersion, "#4:" + version);
133 [ExpectedException (typeof (ApplicationException))]
134 public void CtorFromAnotherBindingCallsCreateBindingElement ()
136 new CustomBinding (new MyBinding ());
139 Message reqmsg, resmsg;
142 public void CustomTransportDoesNotRequireMessageEncoding ()
144 ReplyHandler replier = delegate (Message msg) {
148 RequestReceiver receiver = delegate () {
152 RequestSender sender = delegate (Message msg) {
155 CustomBinding br = new CustomBinding (
156 new HandlerTransportBindingElement (replier, receiver));
157 IChannelListener<IReplyChannel> l =
158 br.BuildChannelListener<IReplyChannel> (
159 new BindingParameterCollection ());
161 IReplyChannel rch = l.AcceptChannel ();
163 Message res = Message.CreateMessage (MessageVersion.Default, "urn:succeeded");
164 rch.ReceiveRequest ().Reply (res);
171 CustomBinding bs = new CustomBinding (
172 new HandlerTransportBindingElement (sender));
174 IChannelFactory<IRequestChannel> f =
175 bs.BuildChannelFactory<IRequestChannel> (
176 new BindingParameterCollection ());
178 IRequestChannel ch = f.CreateChannel (new EndpointAddress ("urn:dummy"));
180 Message result = ch.Request (Message.CreateMessage (MessageVersion.Default, "urn:request"));
184 public void TransportBindingElementDefaultMessageVersion ()
186 Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new HandlerTransportBindingElement (null).GetProperty<MessageVersion> (new BindingContext (new CustomBinding (), new BindingParameterCollection ())), "version");
190 [ExpectedException (typeof (InvalidOperationException))]
191 // Envelope Version 'EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none)'
192 // does not support adding Message Headers.
193 public void MessageSecurityPOX ()
195 SymmetricSecurityBindingElement sbe =
196 new SymmetricSecurityBindingElement ();
197 sbe.ProtectionTokenParameters =
198 new X509SecurityTokenParameters ();
199 RequestSender sender = delegate (Message input) {
200 MessageBuffer buf = input.CreateBufferedCopy (0x10000);
201 using (XmlWriter w = XmlWriter.Create (Console.Error)) {
202 buf.CreateMessage ().WriteMessage (w);
204 return buf.CreateMessage ();
207 CustomBinding binding = new CustomBinding (
209 new TextMessageEncodingBindingElement (
210 MessageVersion.None, Encoding.UTF8),
211 new HandlerTransportBindingElement (sender));
213 EndpointAddress address = new EndpointAddress (
214 new Uri ("http://localhost:37564"),
215 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
217 ChannelFactory<IRequestChannel> cf =
218 new ChannelFactory<IRequestChannel> (binding, address);
219 IRequestChannel ch = cf.CreateChannel ();
221 // neither of Endpoint, Contract nor its Operation seems
222 // to have applicable behaviors (except for
223 // ClientCredentials)
224 Assert.AreEqual (1, cf.Endpoint.Behaviors.Count, "EndpointBehavior");
225 Assert.AreEqual (0, cf.Endpoint.Contract.Behaviors.Count, "ContractBehavior");
226 Assert.AreEqual (1, cf.Endpoint.Contract.Operations.Count, "Operations");
227 OperationDescription od = cf.Endpoint.Contract.Operations [0];
228 Assert.AreEqual (0, od.Behaviors.Count, "OperationBehavior");
233 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction"));
240 [Ignore ("it's underway")]
241 [Category ("NotWorking")]
242 public void MessageSecurityManualProtection ()
244 SymmetricSecurityBindingElement sbe =
245 new SymmetricSecurityBindingElement ();
246 sbe.ProtectionTokenParameters =
247 new X509SecurityTokenParameters ();
248 RequestSender sender = delegate (Message input) {
249 MessageBuffer buf = input.CreateBufferedCopy (0x10000);
250 using (XmlWriter w = XmlWriter.Create (Console.Error)) {
251 buf.CreateMessage ().WriteMessage (w);
253 return buf.CreateMessage ();
256 CustomBinding binding = new CustomBinding (
258 new TextMessageEncodingBindingElement (),
259 new HandlerTransportBindingElement (sender));
261 EndpointAddress address = new EndpointAddress (
262 new Uri ("http://localhost:37564"),
263 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
265 ChannelProtectionRequirements reqs =
266 new ChannelProtectionRequirements ();
267 reqs.OutgoingSignatureParts.AddParts (
268 new MessagePartSpecification (new XmlQualifiedName ("SampleValue", "urn:foo")), "urn:myaction");
269 BindingParameterCollection parameters =
270 new BindingParameterCollection ();
271 parameters.Add (reqs);
273 SymmetricSecurityBindingElement innersbe =
274 new SymmetricSecurityBindingElement ();
275 innersbe.ProtectionTokenParameters =
276 new X509SecurityTokenParameters ();
277 sbe.ProtectionTokenParameters =
278 new SecureConversationSecurityTokenParameters (
279 innersbe, false, reqs);
282 IChannelFactory<IRequestChannel> cf =
283 binding.BuildChannelFactory<IRequestChannel> (parameters);
285 IRequestChannel ch = cf.CreateChannel (address);
289 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction", new SampleValue ()));
296 [ExpectedException (typeof (InvalidOperationException))]
297 public void CanBuildChannelListenerNoTransport ()
299 CustomBinding cb = new CustomBinding ();
300 BindingContext ctx = new BindingContext (
301 cb, new BindingParameterCollection ());
302 Assert.IsFalse (new TextMessageEncodingBindingElement ().CanBuildChannelListener<IReplyChannel> (ctx), "#1");
306 [ExpectedException (typeof (InvalidOperationException))]
307 public void BuildChannelListenerNoTransport ()
309 CustomBinding cb = new CustomBinding ();
310 BindingContext ctx = new BindingContext (
311 cb, new BindingParameterCollection ());
312 new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
316 [ExpectedException (typeof (ArgumentException))]
317 [Category ("NotWorking")]
318 public void BuildChannelListenerWithDuplicateElement ()
320 CustomBinding cb = new CustomBinding (
321 new TextMessageEncodingBindingElement (),
322 new HttpTransportBindingElement ());
323 BindingContext ctx = new BindingContext (
324 cb, new BindingParameterCollection (),
325 new Uri ("http://localhost:37564"), String.Empty, ListenUriMode.Unique);
326 new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
330 [ExpectedException (typeof (InvalidOperationException))]
331 public void BuildChannelListenerWithNoMessageVersion ()
333 // MyBindingElement overrides GetProperty<T>() without calling GetInnerProperty<T>() and returns null in this case.
334 // ServiceHost.Open() tries to get MessageVersion and raises an error if it cannot get any.
335 // HttpTransportBindingElement can actually provide one.
336 ServiceHost host = new ServiceHost (typeof (FooService));
337 host.AddServiceEndpoint (typeof (IFooService),
338 new CustomBinding (new MyBindingElement (false), new HttpTransportBindingElement ()),
339 "http://localhost:37564");
344 [ExpectedException (typeof (MyException))]
345 public void BuildChannelListenerWithMessageVersion ()
347 // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
348 // HttpTransportBindingElement should return Soap11.
349 ServiceHost host = new ServiceHost (typeof (FooService));
350 host.AddServiceEndpoint (typeof (IFooService),
351 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
352 "http://localhost:37564");
358 [ExpectedException (typeof (InvalidOperationException))]
359 public void RelativeListenUriNoBaseAddress ()
361 // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
362 // HttpTransportBindingElement should return Soap11.
363 ServiceHost host = new ServiceHost (typeof (FooService));
364 host.AddServiceEndpoint (typeof (IFooService),
365 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
366 "http://localhost:37564", new Uri ("foobar", UriKind.Relative));
370 [ExpectedException (typeof (MyException))]
371 public void RelativeListenUriWithBaseAddress ()
373 // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
374 // HttpTransportBindingElement should return Soap11.
375 ServiceHost host = new ServiceHost (typeof (FooService), new Uri ("http://localhost:37564"));
376 host.AddServiceEndpoint (typeof (IFooService),
377 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
378 "http://localhost:37564", new Uri ("foobar", UriKind.Relative));
384 public interface IFooService
387 string Hello (string msg);
389 public class FooService : IFooService
391 public string Hello (string msg)
397 class MyBindingElement : BindingElement
399 public MyBindingElement (bool returnProperty)
401 return_property = returnProperty;
404 bool return_property;
406 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
409 throw new NotImplementedException ();
412 public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
415 throw new MyException ();
418 public override bool CanBuildChannelListener<TChannel> (BindingContext ctx)
423 public override BindingElement Clone ()
425 return new MyBindingElement (return_property);
428 public override T GetProperty<T> (BindingContext context)
430 return return_property ? context.GetInnerProperty<T> () : null;
434 public class MyException : Exception
439 [DataContract (Namespace = "urn:foo")]