2009-05-14 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 14 May 2009 09:38:45 +0000 (09:38 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 14 May 2009 09:38:45 +0000 (09:38 -0000)
* TcpDuplexSessionChannel.cs : more [MC-NMF] implementation. Via uri
  is mandatory in initiator preamble packet. Handle Fault reply in
  initiator preamble.

svn path=/trunk/mcs/; revision=134111

mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpDuplexSessionChannel.cs

index cee7312df141bc57ee97575d53dcbc542564e77f..efc692d08e86952040195bf1b12adf66780feacf 100755 (executable)
@@ -1,3 +1,9 @@
+2009-05-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * TcpDuplexSessionChannel.cs : more [MC-NMF] implementation. Via uri
+         is mandatory in initiator preamble packet. Handle Fault reply in
+         initiator preamble.
+
 2009-05-14  Atsushi Enomoto  <atsushi@ximian.com>
 
        * TcpDuplexSessionChannel.cs : ongoing refactoring to collect [MC-NMF]
index e6336c24cbc75d7dde0ad8898c3cd741dc8a3096..b8e41a0b08752128338d42705c189fb37278f576 100644 (file)
@@ -292,6 +292,7 @@ namespace System.ServiceModel.Channels
                                NetworkStream ns = client.GetStream ();
                                frame = new TcpBinaryFrameManager (TcpBinaryFrameManager.DuplexMode, ns);
                                // FIXME: it still results in SocketException (remote host closes the connection).
+                               frame.Via = RemoteAddress.Uri;
                                frame.ProcessPreambleInitiator ();
                        }
                        // Service side.
@@ -317,8 +318,21 @@ namespace System.ServiceModel.Channels
        }
 
        // seealso: [MC-NMF] Windows Protocol document.
-       class TcpBinaryFrameManager : BinaryReader
+       class TcpBinaryFrameManager
        {
+               class MyBinaryReader : BinaryReader
+               {
+                       public MyBinaryReader (Stream s)
+                               : base (s)
+                       {
+                       }
+
+                       public int ReadVariableInt ()
+                       {
+                               return Read7BitEncodedInt ();
+                       }
+               }
+
                public const byte VersionRecord = 0;
                public const byte ModeRecord = 1;
                public const byte ViaRecord = 2;
@@ -337,12 +351,15 @@ namespace System.ServiceModel.Channels
                public const byte DuplexMode = 2;
                public const byte SimplexMode = 3;
                public const byte SingletonSizedMode = 4;
+               MyBinaryReader reader;
+               BinaryWriter writer;
 
                public TcpBinaryFrameManager (int mode, Stream s)
-                       : base (s)
                {
                        this.mode = mode;
                        this.s = s;
+                       reader = new MyBinaryReader (s);
+                       writer = new BinaryWriter (s);
                }
 
                Stream s;
@@ -352,13 +369,13 @@ namespace System.ServiceModel.Channels
 
                public byte [] ReadSizedChunk ()
                {
-                       int length = Read7BitEncodedInt ();
+                       int length = reader.ReadVariableInt ();
                        
                        if (length > 65536)
                                throw new InvalidOperationException ("The message is too large.");
 
                        byte [] buffer = new byte [length];
-                       Read (buffer, 0, length);
+                       reader.Read (buffer, 0, length);
                        
                        return buffer;
                }
@@ -372,14 +389,22 @@ namespace System.ServiceModel.Channels
                        s.WriteByte (0);
                        s.WriteByte (ModeRecord);
                        s.WriteByte ((byte) mode);
+                       s.WriteByte (ViaRecord);
+                       writer.Write (Via.ToString ());
                        s.WriteByte (KnownEncodingRecord); // FIXME
                        s.WriteByte ((byte) encoding_record);
                        s.WriteByte (PreambleEndRecord);
                        s.Flush ();
 
-                       int b;
-                       if ((b = s.ReadByte ()) != PreambleAckRecord)
+                       int b = s.ReadByte ();
+                       switch (b) {
+                       case PreambleAckRecord:
+                               return; // success
+                       case FaultRecord:
+                               throw new FaultException (reader.ReadString ());
+                       default:
                                throw new ArgumentException (String.Format ("Preamble Ack Record is expected, got {0:X}", b));
+                       }
                }
 
                public void ProcessPreambleRecipient ()
@@ -399,7 +424,7 @@ namespace System.ServiceModel.Channels
                                                throw new ArgumentException (String.Format ("Duplex mode is expected to be {0:X}", mode));
                                        break;
                                case ViaRecord:
-                                       Via = new Uri (ReadString ());
+                                       Via = new Uri (reader.ReadString ());
                                        break;
                                case KnownEncodingRecord:
                                        encoding_record = s.ReadByte ();