2010-07-14 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / TcpRequestChannel.cs
index 591c3ac07bd75f822b527aca4f91c3a448b79fc2..6ce9f7c6b07efb0bbed15196899b9e272990eb88 100644 (file)
@@ -1,10 +1,10 @@
 //
-// HttpRequestChannel.cs
+// TcpRequestChannel.cs
 //
 // Author:
 //     Atsushi Enomoto <atsushi@ximian.com>
 //
-// Copyright (C) 2006 Novell, Inc.  http://www.novell.com
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -33,6 +33,7 @@ using System.Net.Sockets;
 using System.ServiceModel;
 using System.ServiceModel.Description;
 using System.Threading;
+using System.Xml;
 
 namespace System.ServiceModel.Channels
 {
@@ -65,29 +66,42 @@ namespace System.ServiceModel.Channels
 
                protected override void OnOpen (TimeSpan timeout)
                {
-                       int explicitPort = RemoteAddress.Uri.Port;
-                       client = new TcpClient (RemoteAddress.Uri.Host, explicitPort <= 0 ? TcpTransportBindingElement.DefaultPort : explicitPort);
+                       CreateClient (timeout);
+               }
+
+               void CreateClient (TimeSpan timeout)
+               {
+                       int explicitPort = Via.Port;
+                       client = new TcpClient (Via.Host, explicitPort <= 0 ? TcpTransportBindingElement.DefaultPort : explicitPort);
                        
                        NetworkStream ns = client.GetStream ();
                        frame = new TcpBinaryFrameManager (TcpBinaryFrameManager.SingletonUnsizedMode, ns, false) {
                                Encoder = this.Encoder,
-                               Via = RemoteAddress.Uri,
+                               Via = this.Via,
                                EncodingRecord = TcpBinaryFrameManager.EncodingBinary };
-                       frame.ProcessPreambleInitiator ();
-                       frame.ProcessPreambleAckInitiator ();
                }
 
                public override Message Request (Message input, TimeSpan timeout)
                {
                        DateTime start = DateTime.Now;
 
+                       // FIXME: use timeouts.
+                       frame.ProcessPreambleInitiator ();
+                       frame.ProcessPreambleAckInitiator ();
+
                        if (input.Headers.To == null)
                                input.Headers.To = RemoteAddress.Uri;
+                       if (input.Headers.MessageId == null)
+                               input.Headers.MessageId = new UniqueId ();
+
+                       frame.WriteUnsizedMessage (input, timeout - (DateTime.Now - start));
+
+                       // LAMESPEC: it contradicts the protocol described at section 3.1.1.1.1 in [MC-NMF].
+                       // Moving this WriteEndRecord() after ReadUnsizedMessage() causes TCP connection blocking.
+                       frame.WriteEndRecord ();
 
-                       frame.WriteUnsizedMessage (input, timeout);
                        var ret = frame.ReadUnsizedMessage (timeout - (DateTime.Now - start));
-                       frame.ProcessEndRecordInitiator ();
-                       frame.ProcessEndRecordRecipient (); // both
+                       frame.ReadEndRecord (); // both
                        return ret;
                }
        }