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");
88 public void MessageVersionProperty ()
90 Assert.IsNull (new CustomBinding ().MessageVersion, "#1");
91 Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new CustomBinding (new HttpTransportBindingElement ()).MessageVersion, "#2");
92 Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new CustomBinding (new TextMessageEncodingBindingElement ()).MessageVersion, "#3");
96 [ExpectedException (typeof (ApplicationException))]
97 public void CtorFromAnotherBindingCallsCreateBindingElement ()
99 new CustomBinding (new MyBinding ());
102 Message reqmsg, resmsg;
105 public void CustomTransportDoesNotRequireMessageEncoding ()
107 ReplyHandler replier = delegate (Message msg) {
111 RequestReceiver receiver = delegate () {
115 RequestSender sender = delegate (Message msg) {
118 CustomBinding br = new CustomBinding (
119 new HandlerTransportBindingElement (replier, receiver));
120 IChannelListener<IReplyChannel> l =
121 br.BuildChannelListener<IReplyChannel> (
122 new BindingParameterCollection ());
124 IReplyChannel rch = l.AcceptChannel ();
126 Message res = Message.CreateMessage (MessageVersion.Default, "urn:succeeded");
127 rch.ReceiveRequest ().Reply (res);
134 CustomBinding bs = new CustomBinding (
135 new HandlerTransportBindingElement (sender));
137 IChannelFactory<IRequestChannel> f =
138 bs.BuildChannelFactory<IRequestChannel> (
139 new BindingParameterCollection ());
141 IRequestChannel ch = f.CreateChannel (new EndpointAddress ("urn:dummy"));
143 Message result = ch.Request (Message.CreateMessage (MessageVersion.Default, "urn:request"));
147 public void TransportBindingElementDefaultMessageVersion ()
149 Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new HandlerTransportBindingElement (null).GetProperty<MessageVersion> (new BindingContext (new CustomBinding (), new BindingParameterCollection ())), "version");
153 [ExpectedException (typeof (InvalidOperationException))]
154 // Envelope Version 'EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none)'
155 // does not support adding Message Headers.
156 public void MessageSecurityPOX ()
158 SymmetricSecurityBindingElement sbe =
159 new SymmetricSecurityBindingElement ();
160 sbe.ProtectionTokenParameters =
161 new X509SecurityTokenParameters ();
162 RequestSender sender = delegate (Message input) {
163 MessageBuffer buf = input.CreateBufferedCopy (0x10000);
164 using (XmlWriter w = XmlWriter.Create (Console.Error)) {
165 buf.CreateMessage ().WriteMessage (w);
167 return buf.CreateMessage ();
170 CustomBinding binding = new CustomBinding (
172 new TextMessageEncodingBindingElement (
173 MessageVersion.None, Encoding.UTF8),
174 new HandlerTransportBindingElement (sender));
176 EndpointAddress address = new EndpointAddress (
177 new Uri ("http://localhost:37564"),
178 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
180 ChannelFactory<IRequestChannel> cf =
181 new ChannelFactory<IRequestChannel> (binding, address);
182 IRequestChannel ch = cf.CreateChannel ();
184 // neither of Endpoint, Contract nor its Operation seems
185 // to have applicable behaviors (except for
186 // ClientCredentials)
187 Assert.AreEqual (1, cf.Endpoint.Behaviors.Count, "EndpointBehavior");
188 Assert.AreEqual (0, cf.Endpoint.Contract.Behaviors.Count, "ContractBehavior");
189 Assert.AreEqual (1, cf.Endpoint.Contract.Operations.Count, "Operations");
190 OperationDescription od = cf.Endpoint.Contract.Operations [0];
191 Assert.AreEqual (0, od.Behaviors.Count, "OperationBehavior");
196 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction"));
203 [Ignore ("it's underway")]
204 [Category ("NotWorking")]
205 public void MessageSecurityManualProtection ()
207 SymmetricSecurityBindingElement sbe =
208 new SymmetricSecurityBindingElement ();
209 sbe.ProtectionTokenParameters =
210 new X509SecurityTokenParameters ();
211 RequestSender sender = delegate (Message input) {
212 MessageBuffer buf = input.CreateBufferedCopy (0x10000);
213 using (XmlWriter w = XmlWriter.Create (Console.Error)) {
214 buf.CreateMessage ().WriteMessage (w);
216 return buf.CreateMessage ();
219 CustomBinding binding = new CustomBinding (
221 new TextMessageEncodingBindingElement (),
222 new HandlerTransportBindingElement (sender));
224 EndpointAddress address = new EndpointAddress (
225 new Uri ("http://localhost:37564"),
226 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
228 ChannelProtectionRequirements reqs =
229 new ChannelProtectionRequirements ();
230 reqs.OutgoingSignatureParts.AddParts (
231 new MessagePartSpecification (new XmlQualifiedName ("SampleValue", "urn:foo")), "urn:myaction");
232 BindingParameterCollection parameters =
233 new BindingParameterCollection ();
234 parameters.Add (reqs);
236 SymmetricSecurityBindingElement innersbe =
237 new SymmetricSecurityBindingElement ();
238 innersbe.ProtectionTokenParameters =
239 new X509SecurityTokenParameters ();
240 sbe.ProtectionTokenParameters =
241 new SecureConversationSecurityTokenParameters (
242 innersbe, false, reqs);
245 IChannelFactory<IRequestChannel> cf =
246 binding.BuildChannelFactory<IRequestChannel> (parameters);
248 IRequestChannel ch = cf.CreateChannel (address);
252 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction", new SampleValue ()));
259 [ExpectedException (typeof (InvalidOperationException))]
260 public void CanBuildChannelListenerNoTransport ()
262 CustomBinding cb = new CustomBinding ();
263 BindingContext ctx = new BindingContext (
264 cb, new BindingParameterCollection ());
265 Assert.IsFalse (new TextMessageEncodingBindingElement ().CanBuildChannelListener<IReplyChannel> (ctx), "#1");
269 [ExpectedException (typeof (InvalidOperationException))]
270 public void BuildChannelListenerNoTransport ()
272 CustomBinding cb = new CustomBinding ();
273 BindingContext ctx = new BindingContext (
274 cb, new BindingParameterCollection ());
275 new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
279 [ExpectedException (typeof (ArgumentException))]
280 [Category ("NotWorking")]
281 public void BuildChannelListenerWithDuplicateElement ()
283 CustomBinding cb = new CustomBinding (
284 new TextMessageEncodingBindingElement (),
285 new HttpTransportBindingElement ());
286 BindingContext ctx = new BindingContext (
287 cb, new BindingParameterCollection (),
288 new Uri ("http://localhost:37564"), String.Empty, ListenUriMode.Unique);
289 new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
293 [ExpectedException (typeof (InvalidOperationException))]
294 public void BuildChannelListenerWithNoMessageVersion ()
296 // MyBindingElement overrides GetProperty<T>() without calling GetInnerProperty<T>() and returns null in this case.
297 // ServiceHost.Open() tries to get MessageVersion and raises an error if it cannot get any.
298 // HttpTransportBindingElement can actually provide one.
299 ServiceHost host = new ServiceHost (typeof (FooService));
300 host.AddServiceEndpoint (typeof (IFooService),
301 new CustomBinding (new MyBindingElement (false), new HttpTransportBindingElement ()),
302 "http://localhost:37564");
307 [ExpectedException (typeof (MyException))]
308 public void BuildChannelListenerWithMessageVersion ()
310 // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
311 // HttpTransportBindingElement should return Soap11.
312 ServiceHost host = new ServiceHost (typeof (FooService));
313 host.AddServiceEndpoint (typeof (IFooService),
314 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
315 "http://localhost:37564");
321 [ExpectedException (typeof (InvalidOperationException))]
322 public void RelativeListenUriNoBaseAddress ()
324 // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
325 // HttpTransportBindingElement should return Soap11.
326 ServiceHost host = new ServiceHost (typeof (FooService));
327 host.AddServiceEndpoint (typeof (IFooService),
328 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
329 "http://localhost:37564", new Uri ("foobar", UriKind.Relative));
333 [ExpectedException (typeof (MyException))]
334 public void RelativeListenUriWithBaseAddress ()
336 // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
337 // HttpTransportBindingElement should return Soap11.
338 ServiceHost host = new ServiceHost (typeof (FooService), new Uri ("http://localhost:37564"));
339 host.AddServiceEndpoint (typeof (IFooService),
340 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
341 "http://localhost:37564", new Uri ("foobar", UriKind.Relative));
347 public interface IFooService
350 string Hello (string msg);
352 public class FooService : IFooService
354 public string Hello (string msg)
360 class MyBindingElement : BindingElement
362 public MyBindingElement (bool returnProperty)
364 return_property = returnProperty;
367 bool return_property;
369 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
372 throw new NotImplementedException ();
375 public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
378 throw new MyException ();
381 public override bool CanBuildChannelListener<TChannel> (BindingContext ctx)
386 public override BindingElement Clone ()
388 return new MyBindingElement (return_property);
391 public override T GetProperty<T> (BindingContext context)
393 return return_property ? context.GetInnerProperty<T> () : null;
397 public class MyException : Exception
402 [DataContract (Namespace = "urn:foo")]