From ff3954c7085d6957a9e3d2fa2528e6de77d283ee Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Wed, 6 Jan 2010 03:39:07 +0000 Subject: [PATCH] 2010-01-06 Atsushi Enomoto * BinaryMessageEncoder.cs : enable workaround buffering only when the argument stream does *not* support seek. This fixes some net.tcp connection problem. * BinaryMessageEncodingBindingElementTest.cs : added test for connection-based tests for both TCP and HTTP (they give difference: see BinaryMessageEncoder.cs change too). svn path=/trunk/mcs/; revision=149103 --- .../BinaryMessageEncoder.cs | 22 ++--- .../System.ServiceModel.Channels/ChangeLog | 6 ++ ...BinaryMessageEncodingBindingElementTest.cs | 87 +++++++++++++++++++ .../System.ServiceModel.Channels/ChangeLog | 6 ++ 4 files changed, 111 insertions(+), 10 deletions(-) diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BinaryMessageEncoder.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BinaryMessageEncoder.cs index 89deb2b0570..70f6928701d 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BinaryMessageEncoder.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BinaryMessageEncoder.cs @@ -245,16 +245,18 @@ namespace System.ServiceModel.Channels if (contentType != ContentType) throw new ProtocolException ("Only content type 'application/soap+msbin1' is allowed."); -// FIXME: remove this extraneous buffering. It is somehow required for HTTP + binary encoding binding ... -var tmpms = new MemoryStream (); -var bytes = new byte [4096]; -int len; -do { - len = stream.Read (bytes, 0, bytes.Length); - tmpms.Write (bytes, 0, len); -} while (len > 0); -tmpms.Seek (0, SeekOrigin.Begin); -stream = tmpms; + // FIXME: remove this extraneous buffering. It is somehow required for HTTP + binary encoding binding. The culprit is probably in binary xml reader or writer, but not sure. + if (!stream.CanSeek) { + var tmpms = new MemoryStream (); + var bytes = new byte [4096]; + int len; + do { + len = stream.Read (bytes, 0, bytes.Length); + tmpms.Write (bytes, 0, len); + } while (len > 0); + tmpms.Seek (0, SeekOrigin.Begin); + stream = tmpms; + } return Message.CreateMessage ( XmlDictionaryReader.CreateBinaryReader (stream, soap_dictionary, owner != null ? owner.Owner.ReaderQuotas : new XmlDictionaryReaderQuotas (), session ? CurrentReaderSession : null), diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog index db9a70f0292..d5e0a1d6ce5 100755 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog @@ -1,3 +1,9 @@ +2010-01-06 Atsushi Enomoto + + * BinaryMessageEncoder.cs : enable workaround buffering only when + the argument stream does *not* support seek. This fixes some + net.tcp connection problem. + 2009-12-26 Atsushi Enomoto * TcpBinaryFrameManager.cs : If preamble byte is not available from diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/BinaryMessageEncodingBindingElementTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/BinaryMessageEncodingBindingElementTest.cs index 57742b0d37b..9c51d150f40 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/BinaryMessageEncodingBindingElementTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/BinaryMessageEncodingBindingElementTest.cs @@ -28,6 +28,7 @@ using System; using System.Collections.ObjectModel; using System.IO; +using System.Net.Sockets; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; @@ -183,6 +184,92 @@ namespace MonoTests.System.ServiceModel.Channels } } + [Test] + public void ConnectionTcpTransport () + { + var host = new ServiceHost (typeof (Foo)); + var bindingsvc = new CustomBinding (new BindingElement [] { + new BinaryMessageEncodingBindingElement (), + new TcpTransportBindingElement () }); + host.AddServiceEndpoint (typeof (IFoo), bindingsvc, "net.tcp://localhost:37564/"); + host.Description.Behaviors.Find ().IncludeExceptionDetailInFaults = true; + host.Open (TimeSpan.FromSeconds (5)); + try { + for (int i = 0; i < 2; i++) { + var bindingcli = new NetTcpBinding (); + bindingcli.Security.Mode = SecurityMode.None; + var cli = new ChannelFactory (bindingcli, new EndpointAddress ("net.tcp://localhost:37564/")).CreateChannel (); + Assert.AreEqual ("test for echo", cli.Echo ("TEST FOR ECHO"), "#1"); + var sid = cli.SessionId; + Assert.AreEqual (3000, cli.Add (1000, 2000), "#2"); + Assert.AreEqual (sid, cli.SessionId, "#3"); + cli.Close (); + } + } finally { + host.Close (TimeSpan.FromSeconds (5)); + var t = new TcpListener (37564); + t.Start (); + t.Stop (); + } + } + + [Test] + public void ConnectionHttpTransport () + { + var host = new ServiceHost (typeof (Foo)); + var bindingsvc = new CustomBinding (new BindingElement [] { + new BinaryMessageEncodingBindingElement (), + new HttpTransportBindingElement () }); + host.AddServiceEndpoint (typeof (IFoo), bindingsvc, "http://localhost:37564/"); + host.Description.Behaviors.Find ().IncludeExceptionDetailInFaults = true; + host.Open (TimeSpan.FromSeconds (5)); + try { + for (int i = 0; i < 2; i++) { + var bindingcli = new CustomBinding (new BindingElement [] { + new BinaryMessageEncodingBindingElement (), + new HttpTransportBindingElement () }); + var cli = new ChannelFactory (bindingcli, new EndpointAddress ("http://localhost:37564/")).CreateChannel (); + Assert.AreEqual ("test for echo", cli.Echo ("TEST FOR ECHO"), "#1"); + var sid = cli.SessionId; + Assert.AreEqual (3000, cli.Add (1000, 2000), "#2"); + Assert.AreEqual (sid, cli.SessionId, "#3"); + cli.Close (); + } + } finally { + host.Close (TimeSpan.FromSeconds (5)); + var t = new TcpListener (37564); + t.Start (); + t.Stop (); + } + } + + public interface IFooClient : IFoo, IClientChannel + { + } + + [ServiceContract] + public interface IFoo + { + [OperationContract] + string Echo (string msg); + + [OperationContract] + uint Add (uint v1, uint v2); + } + + class Foo : IFoo + { + public string Echo (string msg) + { + return msg.ToLower (); + } + + public uint Add (uint v1, uint v2) + { + return v1 + v2; + } + } + void AssertNode (XmlReader reader, int depth, XmlNodeType nodeType, string prefix, string localName, string ns, string value, string label) { Assert.AreEqual (nodeType, reader.NodeType, label + ".NodeType"); diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog index ff920626968..9055cb41ef7 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog @@ -1,3 +1,9 @@ +2010-01-06 Atsushi Enomoto + + * BinaryMessageEncodingBindingElementTest.cs : added test for + connection-based tests for both TCP and HTTP (they give difference: + see BinaryMessageEncoder.cs change too). + 2009-12-21 Atsushi Enomoto * MessageFaultTest.cs : add CreateFault test with MessageVersion.None. -- 2.25.1