HttpTransportBindingElementTest.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. //
  2. // HttpTransportBindingElementTest.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.IO;
  31. using System.Net;
  32. using System.Net.Security;
  33. using System.Reflection;
  34. using System.ServiceModel;
  35. using System.ServiceModel.Channels;
  36. using System.ServiceModel.Description;
  37. using System.Threading;
  38. using System.Xml;
  39. using NUnit.Framework;
  40. namespace MonoTests.System.ServiceModel.Channels
  41. {
  42. [TestFixture]
  43. public class HttpTransportBindingElementTest
  44. {
  45. static BindingParameterCollection empty_params =
  46. new BindingParameterCollection ();
  47. [Test]
  48. public void DefaultValues ()
  49. {
  50. HttpTransportBindingElement be =
  51. new HttpTransportBindingElement ();
  52. Assert.AreEqual (false, be.AllowCookies, "#1");
  53. Assert.AreEqual (AuthenticationSchemes.Anonymous,
  54. be.AuthenticationScheme, "#2");
  55. Assert.AreEqual (false, be.BypassProxyOnLocal, "#3");
  56. Assert.AreEqual (default (HostNameComparisonMode),
  57. be.HostNameComparisonMode, "#4");
  58. Assert.AreEqual (0x10000, be.MaxBufferSize, "#6");
  59. Assert.IsNull (be.ProxyAddress, "#7");
  60. Assert.AreEqual (AuthenticationSchemes.Anonymous,
  61. be.ProxyAuthenticationScheme, "#8");
  62. Assert.AreEqual (String.Empty, be.Realm, "#9");
  63. Assert.AreEqual ("http", be.Scheme, "#10");
  64. Assert.AreEqual (default (TransferMode),
  65. be.TransferMode, "#11");
  66. Assert.AreEqual (false,
  67. be.UnsafeConnectionNtlmAuthentication, "#12");
  68. Assert.AreEqual (true, be.UseDefaultWebProxy, "#13");
  69. }
  70. [Test]
  71. public void CanBuildChannelFactory ()
  72. {
  73. HttpTransportBindingElement be =
  74. new HttpTransportBindingElement ();
  75. BindingContext ctx = new BindingContext (
  76. new CustomBinding (), empty_params);
  77. Assert.IsTrue (be.CanBuildChannelFactory<IRequestChannel> (ctx), "#1");
  78. Assert.IsFalse (be.CanBuildChannelFactory<IInputChannel> (ctx), "#2");
  79. Assert.IsFalse (be.CanBuildChannelFactory<IReplyChannel> (ctx), "#3");
  80. Assert.IsFalse (be.CanBuildChannelFactory<IOutputChannel> (ctx), "#4");
  81. // seems like it does not support session channels by itself ?
  82. Assert.IsFalse (be.CanBuildChannelFactory<IRequestSessionChannel> (ctx), "#5");
  83. Assert.IsFalse (be.CanBuildChannelFactory<IInputSessionChannel> (ctx), "#6");
  84. Assert.IsFalse (be.CanBuildChannelFactory<IReplySessionChannel> (ctx), "#7");
  85. Assert.IsFalse (be.CanBuildChannelFactory<IOutputSessionChannel> (ctx), "#8");
  86. // IServiceChannel is not supported
  87. Assert.IsFalse (be.CanBuildChannelListener<IServiceChannel> (ctx), "#9");
  88. }
  89. [Test]
  90. public void CanBuildChannelListener ()
  91. {
  92. HttpTransportBindingElement be =
  93. new HttpTransportBindingElement ();
  94. BindingContext ctx = new BindingContext (
  95. new CustomBinding (), empty_params);
  96. Assert.IsTrue (be.CanBuildChannelListener<IReplyChannel> (ctx), "#1");
  97. Assert.IsFalse (be.CanBuildChannelListener<IOutputChannel> (ctx), "#2");
  98. Assert.IsFalse (be.CanBuildChannelListener<IRequestChannel> (ctx), "#3");
  99. Assert.IsFalse (be.CanBuildChannelListener<IInputChannel> (ctx), "#4");
  100. // seems like it does not support session channels by itself ?
  101. Assert.IsFalse (be.CanBuildChannelListener<IReplySessionChannel> (ctx), "#5");
  102. Assert.IsFalse (be.CanBuildChannelListener<IOutputSessionChannel> (ctx), "#6");
  103. Assert.IsFalse (be.CanBuildChannelListener<IRequestSessionChannel> (ctx), "#7");
  104. Assert.IsFalse (be.CanBuildChannelListener<IInputSessionChannel> (ctx), "#8");
  105. // IServiceChannel is not supported
  106. Assert.IsFalse (be.CanBuildChannelListener<IServiceChannel> (ctx), "#9");
  107. }
  108. [Test]
  109. public void BuildChannelFactory ()
  110. {
  111. BindingContext ctx = new BindingContext (
  112. new CustomBinding (
  113. new HttpTransportBindingElement ()),
  114. empty_params);
  115. // returns HttpChannelFactory
  116. IChannelFactory<IRequestChannel> f =
  117. ctx.BuildInnerChannelFactory<IRequestChannel> ();
  118. f.Open (); // required
  119. IChannel c = f.CreateChannel (new EndpointAddress (
  120. "http://www.mono-project.com"));
  121. }
  122. [Test]
  123. [ExpectedException (typeof (InvalidOperationException))]
  124. public void CreateChannelWithoutOpen ()
  125. {
  126. BindingContext ctx = new BindingContext (
  127. new CustomBinding (
  128. new HttpTransportBindingElement ()),
  129. empty_params);
  130. // returns HttpChannelFactory
  131. IChannelFactory<IRequestChannel> f =
  132. ctx.BuildInnerChannelFactory<IRequestChannel> ();
  133. IChannel c = f.CreateChannel (new EndpointAddress (
  134. "http://www.mono-project.com"));
  135. }
  136. [Test]
  137. public void BuildChannelFactoryTwoHttp ()
  138. {
  139. BindingContext ctx = new BindingContext (
  140. new CustomBinding (
  141. new HttpTransportBindingElement (),
  142. new HttpTransportBindingElement ()),
  143. empty_params);
  144. ctx.BuildInnerChannelFactory<IRequestChannel> ();
  145. }
  146. [Test]
  147. public void BuildChannelFactoryHttpThenMessage ()
  148. {
  149. BindingContext ctx = new BindingContext (
  150. new CustomBinding (
  151. new HttpTransportBindingElement (),
  152. new BinaryMessageEncodingBindingElement ()),
  153. empty_params);
  154. IChannelFactory<IRequestChannel> cf =
  155. ctx.BuildInnerChannelFactory<IRequestChannel> ();
  156. cf.Open ();
  157. }
  158. [Test]
  159. // with July CTP it still works ...
  160. public void BuildChannelFactoryHttpNoMessage ()
  161. {
  162. BindingContext ctx = new BindingContext (
  163. new CustomBinding (
  164. new HttpTransportBindingElement ()),
  165. empty_params);
  166. IChannelFactory<IRequestChannel> cf =
  167. ctx.BuildInnerChannelFactory<IRequestChannel> ();
  168. cf.Open ();
  169. }
  170. [Test]
  171. public void BuildChannelFactoryIgnoresRemaining ()
  172. {
  173. BindingContext ctx = new BindingContext (
  174. new CustomBinding (
  175. new HttpTransportBindingElement (),
  176. new InvalidBindingElement ()),
  177. empty_params);
  178. ctx.BuildInnerChannelFactory<IRequestChannel> ();
  179. }
  180. [Test]
  181. [ExpectedException (typeof (ArgumentException))]
  182. public void CreateChannelInvalidScheme ()
  183. {
  184. IChannelFactory<IRequestChannel> f = new BasicHttpBinding ().BuildChannelFactory<IRequestChannel> (new BindingParameterCollection ());
  185. f.Open ();
  186. f.CreateChannel (new EndpointAddress ("stream:dummy"));
  187. }
  188. [Test]
  189. public void BuildChannelListenerWithoutListenUri ()
  190. {
  191. new BasicHttpBinding ().BuildChannelListener<IReplyChannel> (new BindingParameterCollection ());
  192. }
  193. // when AddressingVersion is None (in MessageVersion), then
  194. // EndpointAddress.Uri and via URIs must match.
  195. [Test]
  196. [ExpectedException (typeof (ArgumentException))]
  197. public void EndpointAddressAndViaMustMatchOnAddressingNone ()
  198. {
  199. try {
  200. var ch = ChannelFactory<IFoo>.CreateChannel (new BasicHttpBinding (), new EndpointAddress ("http://localhost:37564/"), new Uri ("http://localhost:8080/HogeService"));
  201. ((ICommunicationObject) ch).Close ();
  202. } catch (TargetInvocationException) {
  203. // we throw this exception so far. Since it is
  204. // very internal difference (channel is created
  205. // inside ClientRuntimeChannel.ctor() while .NET
  206. // does it in ChannelFactory<T>.CreateChannel(),
  207. // there is no point of treating it as failure).
  208. throw new ArgumentException ();
  209. }
  210. }
  211. [Test]
  212. public void GetPrpertyBindingDeliveryCapabilities ()
  213. {
  214. var be = new HttpTransportBindingElement ();
  215. var dc = be.GetProperty<IBindingDeliveryCapabilities> (new BindingContext (new CustomBinding (), empty_params));
  216. Assert.IsFalse (dc.AssuresOrderedDelivery, "#1");
  217. Assert.IsFalse (dc.QueuedDelivery, "#2");
  218. }
  219. [Test]
  220. public void GetPrpertySecurityCapabilities ()
  221. {
  222. var be = new HttpTransportBindingElement ();
  223. var sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
  224. Assert.IsNotNull (sec, "#1.1");
  225. Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#1.2");
  226. Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#1.3");
  227. Assert.IsFalse (sec.SupportsClientAuthentication, "#1.4");
  228. Assert.IsFalse (sec.SupportsClientWindowsIdentity, "#1.5");
  229. Assert.IsFalse (sec.SupportsServerAuthentication , "#1.6");
  230. be = new HttpTransportBindingElement ();
  231. be.AuthenticationScheme = AuthenticationSchemes.Negotiate;
  232. sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
  233. Assert.IsNotNull (sec, "#2.1");
  234. Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#2.2");
  235. Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#2.3");
  236. Assert.IsTrue (sec.SupportsClientAuthentication, "#2.4");
  237. Assert.IsTrue (sec.SupportsClientWindowsIdentity, "#2.5");
  238. Assert.IsTrue (sec.SupportsServerAuthentication , "#2.6");
  239. // almost the same, only differ at SupportsServerAuth
  240. be = new HttpTransportBindingElement ();
  241. be.AuthenticationScheme = AuthenticationSchemes.Ntlm;
  242. sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
  243. Assert.IsNotNull (sec, "#3.1");
  244. Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#3.2");
  245. Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#3.3");
  246. Assert.IsTrue (sec.SupportsClientAuthentication, "#3.4");
  247. Assert.IsTrue (sec.SupportsClientWindowsIdentity, "#3.5");
  248. Assert.IsFalse (sec.SupportsServerAuthentication , "#3.6");
  249. be = new HttpTransportBindingElement ();
  250. be.AuthenticationScheme = AuthenticationSchemes.Basic;
  251. sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
  252. Assert.IsNotNull (sec, "#4.1");
  253. Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#4.2");
  254. Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#4.3");
  255. Assert.IsTrue (sec.SupportsClientAuthentication, "#4.4");
  256. Assert.IsTrue (sec.SupportsClientWindowsIdentity, "#4.5");
  257. Assert.IsFalse (sec.SupportsServerAuthentication , "#4.6");
  258. be = new HttpTransportBindingElement ();
  259. be.AuthenticationScheme = AuthenticationSchemes.Digest;
  260. sec = be.GetProperty<ISecurityCapabilities> (new BindingContext (new CustomBinding (), empty_params));
  261. Assert.IsNotNull (sec, "#5.1");
  262. Assert.AreEqual (ProtectionLevel.None, sec.SupportedRequestProtectionLevel, "#5.2");
  263. Assert.AreEqual (ProtectionLevel.None, sec.SupportedResponseProtectionLevel, "#5.3");
  264. Assert.IsTrue (sec.SupportsClientAuthentication, "#5.4");
  265. Assert.IsTrue (sec.SupportsClientWindowsIdentity, "#5.5");
  266. Assert.IsFalse (sec.SupportsServerAuthentication , "#5.6");
  267. }
  268. #region contracts
  269. [ServiceContract]
  270. interface IFoo
  271. {
  272. [OperationContract]
  273. string DoWork (string s1, string s2);
  274. }
  275. #endregion
  276. #region connection test
  277. string svcret;
  278. [Test]
  279. [Ignore ("It somehow fails...")]
  280. // It is almost identical to http-low-level-binding
  281. public void LowLevelHttpConnection ()
  282. {
  283. HttpTransportBindingElement lel =
  284. new HttpTransportBindingElement ();
  285. // Service
  286. BindingContext lbc = new BindingContext (
  287. new CustomBinding (),
  288. new BindingParameterCollection (),
  289. new Uri ("http://localhost:37564"),
  290. String.Empty, ListenUriMode.Explicit);
  291. listener = lel.BuildChannelListener<IReplyChannel> (lbc);
  292. try {
  293. listener.Open ();
  294. svcret = "";
  295. Thread svc = new Thread (delegate () {
  296. try {
  297. svcret = LowLevelHttpConnection_SetupService ();
  298. } catch (Exception ex) {
  299. svcret = ex.ToString ();
  300. }
  301. });
  302. svc.Start ();
  303. // Client code goes here.
  304. HttpTransportBindingElement el =
  305. new HttpTransportBindingElement ();
  306. BindingContext ctx = new BindingContext (
  307. new CustomBinding (),
  308. new BindingParameterCollection ());
  309. IChannelFactory<IRequestChannel> factory =
  310. el.BuildChannelFactory<IRequestChannel> (ctx);
  311. factory.Open ();
  312. IRequestChannel request = factory.CreateChannel (
  313. new EndpointAddress ("http://localhost:37564"));
  314. request.Open ();
  315. try {
  316. try {
  317. Message reqmsg = Message.CreateMessage (
  318. MessageVersion.Default, "Echo");
  319. // sync version does not work here.
  320. Message msg = request.Request (reqmsg, TimeSpan.FromSeconds (5));
  321. using (XmlWriter w = XmlWriter.Create (TextWriter.Null)) {
  322. msg.WriteMessage (w);
  323. }
  324. if (svcret != null)
  325. Assert.Fail (svcret.Length > 0 ? svcret : "service code did not finish until this test expected.");
  326. } finally {
  327. if (request.State == CommunicationState.Opened)
  328. request.Close ();
  329. }
  330. } finally {
  331. if (factory.State == CommunicationState.Opened)
  332. factory.Close ();
  333. }
  334. } finally {
  335. if (listener.State == CommunicationState.Opened)
  336. listener.Close ();
  337. }
  338. }
  339. IChannelListener<IReplyChannel> listener;
  340. string LowLevelHttpConnection_SetupService ()
  341. {
  342. IReplyChannel reply = listener.AcceptChannel ();
  343. reply.Open ();
  344. if (!reply.WaitForRequest (TimeSpan.FromSeconds (10)))
  345. return "No request reached here.";
  346. svcret = "Receiving request ...";
  347. RequestContext ctx = reply.ReceiveRequest ();
  348. if (ctx == null)
  349. return "No request context returned.";
  350. svcret = "Starting reply ...";
  351. ctx.Reply (Message.CreateMessage (MessageVersion.Default, "Ack"));
  352. return null; // OK
  353. }
  354. #endregion
  355. }
  356. }