CustomBindingTest.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. //
  2. // CustomBindingTest.cs
  3. //
  4. // Author:
  5. // Atsushi Enomoto <[email protected]>
  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. namespace MonoTests.System.ServiceModel.Channels
  43. {
  44. [TestFixture]
  45. public class CustomBindingTest
  46. {
  47. [Test]
  48. public void DefaultCtor ()
  49. {
  50. CustomBinding cb = new CustomBinding ();
  51. Assert.AreEqual (0, cb.Elements.Count, "#1");
  52. Assert.AreEqual ("CustomBinding", cb.Name, "#3");
  53. Assert.AreEqual ("http://tempuri.org/", cb.Namespace, "#4");
  54. Assert.AreEqual (TimeSpan.FromMinutes (1), cb.OpenTimeout, "#5");
  55. Assert.AreEqual (TimeSpan.FromMinutes (1), cb.CloseTimeout, "#6");
  56. Assert.AreEqual (TimeSpan.FromMinutes (1), cb.SendTimeout, "#7");
  57. Assert.AreEqual (TimeSpan.FromMinutes (10), cb.ReceiveTimeout, "#8");
  58. Assert.AreEqual (0, cb.CreateBindingElements ().Count, "#9");
  59. }
  60. class MyBinding : Binding
  61. {
  62. public override string Scheme { get { return "hoge"; } }
  63. public override BindingElementCollection CreateBindingElements ()
  64. {
  65. throw new ApplicationException ("HEHE");
  66. }
  67. }
  68. [Test]
  69. public void CtorFromAnotherBinding ()
  70. {
  71. CustomBinding cb =
  72. new CustomBinding (new WSHttpBinding ());
  73. // Its properties become mostly copy of the original one
  74. Assert.AreEqual (4, cb.Elements.Count, "#1");
  75. Assert.AreEqual ("http", cb.Scheme, "#2");
  76. Assert.AreEqual ("WSHttpBinding", cb.Name, "#3");
  77. Assert.AreEqual ("http://tempuri.org/", cb.Namespace, "#4");
  78. Assert.AreEqual (4, cb.CreateBindingElements ().Count, "#9");
  79. }
  80. [Test]
  81. [ExpectedException (typeof (ApplicationException))]
  82. public void CtorFromAnotherBindingCallsCreateBindingElement ()
  83. {
  84. new CustomBinding (new MyBinding ());
  85. }
  86. Message reqmsg, resmsg;
  87. [Test]
  88. public void CustomTransportDoesNotRequireMessageEncoding ()
  89. {
  90. ReplyHandler replier = delegate (Message msg) {
  91. resmsg = msg;
  92. };
  93. RequestReceiver receiver = delegate () {
  94. return reqmsg;
  95. };
  96. RequestSender sender = delegate (Message msg) {
  97. reqmsg = msg;
  98. CustomBinding br = new CustomBinding (
  99. new HandlerTransportBindingElement (replier, receiver));
  100. IChannelListener<IReplyChannel> l =
  101. br.BuildChannelListener<IReplyChannel> (
  102. new BindingParameterCollection ());
  103. l.Open ();
  104. IReplyChannel rch = l.AcceptChannel ();
  105. rch.Open ();
  106. Message res = Message.CreateMessage (MessageVersion.Default, "urn:succeeded");
  107. rch.ReceiveRequest ().Reply (res);
  108. rch.Close ();
  109. l.Close ();
  110. return resmsg;
  111. };
  112. CustomBinding bs = new CustomBinding (
  113. new HandlerTransportBindingElement (sender));
  114. IChannelFactory<IRequestChannel> f =
  115. bs.BuildChannelFactory<IRequestChannel> (
  116. new BindingParameterCollection ());
  117. f.Open ();
  118. IRequestChannel ch = f.CreateChannel (new EndpointAddress ("urn:dummy"));
  119. ch.Open ();
  120. Message result = ch.Request (Message.CreateMessage (MessageVersion.Default, "urn:request"));
  121. }
  122. [Test]
  123. [ExpectedException (typeof (InvalidOperationException))]
  124. // Envelope Version 'EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none)'
  125. // does not support adding Message Headers.
  126. public void MessageSecurityPOX ()
  127. {
  128. SymmetricSecurityBindingElement sbe =
  129. new SymmetricSecurityBindingElement ();
  130. sbe.ProtectionTokenParameters =
  131. new X509SecurityTokenParameters ();
  132. RequestSender sender = delegate (Message input) {
  133. MessageBuffer buf = input.CreateBufferedCopy (0x10000);
  134. using (XmlWriter w = XmlWriter.Create (Console.Error)) {
  135. buf.CreateMessage ().WriteMessage (w);
  136. }
  137. return buf.CreateMessage ();
  138. };
  139. CustomBinding binding = new CustomBinding (
  140. sbe,
  141. new TextMessageEncodingBindingElement (
  142. MessageVersion.None, Encoding.UTF8),
  143. new HandlerTransportBindingElement (sender));
  144. EndpointAddress address = new EndpointAddress (
  145. new Uri ("http://localhost:8080"),
  146. new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
  147. ChannelFactory<IRequestChannel> cf =
  148. new ChannelFactory<IRequestChannel> (binding, address);
  149. IRequestChannel ch = cf.CreateChannel ();
  150. /*
  151. // neither of Endpoint, Contract nor its Operation seems
  152. // to have applicable behaviors (except for
  153. // ClientCredentials)
  154. Assert.AreEqual (1, cf.Endpoint.Behaviors.Count, "EndpointBehavior");
  155. Assert.AreEqual (0, cf.Endpoint.Contract.Behaviors.Count, "ContractBehavior");
  156. Assert.AreEqual (1, cf.Endpoint.Contract.Operations.Count, "Operations");
  157. OperationDescription od = cf.Endpoint.Contract.Operations [0];
  158. Assert.AreEqual (0, od.Behaviors.Count, "OperationBehavior");
  159. */
  160. ch.Open ();
  161. try {
  162. ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction"));
  163. } finally {
  164. ch.Close ();
  165. }
  166. }
  167. [Test]
  168. [Ignore ("it's underway")]
  169. [Category ("NotWorking")]
  170. public void MessageSecurityManualProtection ()
  171. {
  172. SymmetricSecurityBindingElement sbe =
  173. new SymmetricSecurityBindingElement ();
  174. sbe.ProtectionTokenParameters =
  175. new X509SecurityTokenParameters ();
  176. RequestSender sender = delegate (Message input) {
  177. MessageBuffer buf = input.CreateBufferedCopy (0x10000);
  178. using (XmlWriter w = XmlWriter.Create (Console.Error)) {
  179. buf.CreateMessage ().WriteMessage (w);
  180. }
  181. return buf.CreateMessage ();
  182. };
  183. CustomBinding binding = new CustomBinding (
  184. sbe,
  185. new TextMessageEncodingBindingElement (),
  186. new HandlerTransportBindingElement (sender));
  187. EndpointAddress address = new EndpointAddress (
  188. new Uri ("http://localhost:8080"),
  189. new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
  190. ChannelProtectionRequirements reqs =
  191. new ChannelProtectionRequirements ();
  192. reqs.OutgoingSignatureParts.AddParts (
  193. new MessagePartSpecification (new XmlQualifiedName ("SampleValue", "urn:foo")), "urn:myaction");
  194. BindingParameterCollection parameters =
  195. new BindingParameterCollection ();
  196. parameters.Add (reqs);
  197. /*
  198. SymmetricSecurityBindingElement innersbe =
  199. new SymmetricSecurityBindingElement ();
  200. innersbe.ProtectionTokenParameters =
  201. new X509SecurityTokenParameters ();
  202. sbe.ProtectionTokenParameters =
  203. new SecureConversationSecurityTokenParameters (
  204. innersbe, false, reqs);
  205. */
  206. IChannelFactory<IRequestChannel> cf =
  207. binding.BuildChannelFactory<IRequestChannel> (parameters);
  208. cf.Open ();
  209. IRequestChannel ch = cf.CreateChannel (address);
  210. ch.Open ();
  211. try {
  212. ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction", new SampleValue ()));
  213. } finally {
  214. ch.Close ();
  215. }
  216. }
  217. [Test]
  218. [ExpectedException (typeof (InvalidOperationException))]
  219. public void CanBuildChannelListenerNoTransport ()
  220. {
  221. CustomBinding cb = new CustomBinding ();
  222. BindingContext ctx = new BindingContext (
  223. cb, new BindingParameterCollection ());
  224. Assert.IsFalse (new TextMessageEncodingBindingElement ().CanBuildChannelListener<IReplyChannel> (ctx), "#1");
  225. }
  226. [Test]
  227. [ExpectedException (typeof (InvalidOperationException))]
  228. public void BuildChannelListenerNoTransport ()
  229. {
  230. CustomBinding cb = new CustomBinding ();
  231. BindingContext ctx = new BindingContext (
  232. cb, new BindingParameterCollection ());
  233. new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
  234. }
  235. [Test]
  236. [ExpectedException (typeof (ArgumentException))]
  237. [Category ("NotWorking")]
  238. public void BuildChannelListenerWithDuplicateElement ()
  239. {
  240. CustomBinding cb = new CustomBinding (
  241. new TextMessageEncodingBindingElement (),
  242. new HttpTransportBindingElement ());
  243. BindingContext ctx = new BindingContext (
  244. cb, new BindingParameterCollection (),
  245. new Uri ("http://localhost:8080"), String.Empty, ListenUriMode.Unique);
  246. new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
  247. }
  248. [Test]
  249. [ExpectedException (typeof (InvalidOperationException))]
  250. public void BuildChannelListenerWithNoMessageVersion ()
  251. {
  252. // MyBindingElement overrides GetProperty<T>() without calling GetInnerProperty<T>() and returns null in this case.
  253. // ServiceHost.Open() tries to get MessageVersion and raises an error if it cannot get any.
  254. // HttpTransportBindingElement can actually provide one.
  255. ServiceHost host = new ServiceHost (typeof (FooService));
  256. host.AddServiceEndpoint (typeof (IFooService),
  257. new CustomBinding (new MyBindingElement (false), new HttpTransportBindingElement ()),
  258. "http://localhost:8080");
  259. host.Open ();
  260. }
  261. [Test]
  262. [ExpectedException (typeof (MyException))]
  263. public void BuildChannelListenerWithMessageVersion ()
  264. {
  265. // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
  266. // HttpTransportBindingElement should return Soap11.
  267. ServiceHost host = new ServiceHost (typeof (FooService));
  268. host.AddServiceEndpoint (typeof (IFooService),
  269. new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
  270. "http://localhost:8080");
  271. host.Open ();
  272. host.Close ();
  273. }
  274. [ServiceContract]
  275. public interface IFooService
  276. {
  277. [OperationContract]
  278. string Hello (string msg);
  279. }
  280. public class FooService : IFooService
  281. {
  282. public string Hello (string msg)
  283. {
  284. return "hello";
  285. }
  286. }
  287. class MyBindingElement : BindingElement
  288. {
  289. public MyBindingElement (bool returnProperty)
  290. {
  291. return_property = returnProperty;
  292. }
  293. bool return_property;
  294. public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
  295. BindingContext ctx)
  296. {
  297. throw new NotImplementedException ();
  298. }
  299. public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
  300. BindingContext ctx)
  301. {
  302. throw new MyException ();
  303. }
  304. public override bool CanBuildChannelListener<TChannel> (BindingContext ctx)
  305. {
  306. return true;
  307. }
  308. public override BindingElement Clone ()
  309. {
  310. return new MyBindingElement (return_property);
  311. }
  312. public override T GetProperty<T> (BindingContext context)
  313. {
  314. return return_property ? context.GetInnerProperty<T> () : null;
  315. }
  316. }
  317. public class MyException : Exception
  318. {
  319. }
  320. }
  321. [DataContract (Namespace = "urn:foo")]
  322. class SampleValue
  323. {
  324. }
  325. }