2010-01-06 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Wed, 6 Jan 2010 03:39:07 +0000 (03:39 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Wed, 6 Jan 2010 03:39:07 +0000 (03:39 -0000)
* 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

mcs/class/System.ServiceModel/System.ServiceModel.Channels/BinaryMessageEncoder.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog
mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/BinaryMessageEncodingBindingElementTest.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog

index 89deb2b057040adbb8597c3585a0f2bef5291af7..70f6928701d0fb87712eba8fbcaa45f84084af83 100644 (file)
@@ -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),
index db9a70f02926e5153377e30ec151228ba29b3f62..d5e0a1d6ce54ce7fa085ca7b81a927847f638c13 100755 (executable)
@@ -1,3 +1,9 @@
+2010-01-06  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * 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  <atsushi@ximian.com>
 
        * TcpBinaryFrameManager.cs : If preamble byte is not available from
index 57742b0d37b6566a8deda0813ff5a8c8f4255a10..9c51d150f40c75d072b1de3726e1516e63ec49c9 100644 (file)
@@ -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<ServiceBehaviorAttribute> ().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<IFooClient> (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<ServiceBehaviorAttribute> ().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<IFooClient> (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");
index ff920626968bf8443419131baf03b468fbf36372..9055cb41ef7db5e41d2f74fc695bdb50161e86b0 100644 (file)
@@ -1,3 +1,9 @@
+2010-01-06  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * 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  <atsushi@ximian.com>
 
        * MessageFaultTest.cs : add CreateFault test with MessageVersion.None.