[WCF] fix send timeout. Should fix bug #19697. Should fix bug #19697. Should fix...
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel / ClientRuntimeChannel.cs
1 //
2 // ClientRuntimeChannel.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 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.Generic;
30 using System.Reflection;
31 using System.Runtime.Serialization;
32 using System.ServiceModel.Channels;
33 using System.ServiceModel.Description;
34 using System.ServiceModel.Dispatcher;
35 using System.ServiceModel.Security;
36 using System.Threading;
37 using System.Xml;
38
39 namespace System.ServiceModel.MonoInternal
40 {
41 #if DISABLE_REAL_PROXY
42         // FIXME: This is a quick workaround for bug #571907
43         public
44 #endif
45         interface IInternalContextChannel
46         {
47                 ContractDescription Contract { get; }
48
49                 object Process (MethodBase method, string operationName, object [] parameters, OperationContext context);
50
51                 IAsyncResult BeginProcess (MethodBase method, string operationName, object [] parameters, AsyncCallback callback, object asyncState);
52
53                 object EndProcess (MethodBase method, string operationName, object [] parameters, IAsyncResult result);
54         }
55
56 #if DISABLE_REAL_PROXY
57         // FIXME: This is a quick workaround for bug #571907
58         public
59 #endif
60         class ClientRuntimeChannel
61                 : CommunicationObject, IClientChannel, IInternalContextChannel
62         {
63                 ClientRuntime runtime;
64                 EndpointAddress remote_address;
65                 ContractDescription contract;
66                 MessageVersion message_version;
67                 TimeSpan default_open_timeout, default_close_timeout;
68                 IChannel channel;
69                 IChannelFactory factory;
70                 TimeSpan? operation_timeout = null;
71                 ChannelFactory channel_factory;
72
73                 #region delegates
74                 readonly ProcessDelegate _processDelegate;
75
76                 delegate object ProcessDelegate (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context);
77
78                 readonly RequestDelegate requestDelegate;
79
80                 delegate Message RequestDelegate (Message msg, TimeSpan timeout);
81
82                 readonly SendDelegate sendDelegate;
83
84                 delegate void SendDelegate (Message msg, TimeSpan timeout);
85                 #endregion
86
87                 public ClientRuntimeChannel (ServiceEndpoint endpoint,
88                         ChannelFactory channelFactory, EndpointAddress remoteAddress, Uri via)
89                         : this (endpoint.CreateClientRuntime (null), endpoint.Contract, channelFactory.DefaultOpenTimeout, channelFactory.DefaultCloseTimeout, null, channelFactory.OpenedChannelFactory, endpoint.Binding.MessageVersion, remoteAddress, via)
90                 {
91                         channel_factory = channelFactory;
92                 }
93
94                 public ClientRuntimeChannel (ClientRuntime runtime, ContractDescription contract, TimeSpan openTimeout, TimeSpan closeTimeout, IChannel contextChannel, IChannelFactory factory, MessageVersion messageVersion, EndpointAddress remoteAddress, Uri via)
95                 {
96                         if (runtime == null)
97                                 throw new ArgumentNullException ("runtime");
98                         if (messageVersion == null)
99                                 throw new ArgumentNullException ("messageVersion");
100                         this.runtime = runtime;
101                         this.remote_address = remoteAddress;
102                         if (runtime.Via == null)
103                                 runtime.Via = via ?? (remote_address != null ?remote_address.Uri : null);
104                         this.contract = contract;
105                         this.message_version = messageVersion;
106                         default_open_timeout = openTimeout;
107                         default_close_timeout = closeTimeout;
108                         _processDelegate = new ProcessDelegate (Process);
109                         requestDelegate = new RequestDelegate (Request);
110                         sendDelegate = new SendDelegate (Send);
111
112                         // default values
113                         AllowInitializationUI = true;
114
115                         if (contextChannel != null)
116                                 channel = contextChannel;
117                         else {
118                                 var method = factory.GetType ().GetMethod ("CreateChannel", new Type [] {typeof (EndpointAddress), typeof (Uri)});
119                                 try {
120                                         channel = (IChannel) method.Invoke (factory, new object [] {remote_address, Via});
121                                         this.factory = factory;
122                                 } catch (TargetInvocationException ex) {
123                                         if (ex.InnerException != null)
124                                                 throw ex.InnerException;
125                                         else
126                                                 throw;
127                                 }
128                         }
129                 }
130
131                 public ContractDescription Contract {
132                         get { return contract; }
133                 }
134
135                 public ClientRuntime Runtime {
136                         get { return runtime; }
137                 }
138
139                 IRequestChannel RequestChannel {
140                         get { return channel as IRequestChannel; }
141                 }
142
143                 IOutputChannel OutputChannel {
144                         get { return channel as IOutputChannel; }
145                 }
146
147                 internal IDuplexChannel DuplexChannel {
148                         get { return channel as IDuplexChannel; }
149                 }
150
151                 #region IClientChannel
152
153                 bool did_interactive_initialization;
154
155                 public bool AllowInitializationUI { get; set; }
156
157                 public bool DidInteractiveInitialization {
158                         get { return did_interactive_initialization; }
159                 }
160
161                 public Uri Via {
162                         get { return runtime.Via; }
163                 }
164
165                 class DelegatingWaitHandle : WaitHandle
166                 {
167                         public DelegatingWaitHandle (IAsyncResult [] results)
168                         {
169                                 this.results = results;
170                         }
171
172                         IAsyncResult [] results;
173
174                         protected override void Dispose (bool disposing)
175                         {
176                                 if (disposing)
177                                         foreach (var r in results)
178                                                 r.AsyncWaitHandle.Close ();
179                         }
180
181                         public override bool WaitOne ()
182                         {
183                                 foreach (var r in results)
184                                         r.AsyncWaitHandle.WaitOne ();
185                                 return true;
186                         }
187
188                         public override bool WaitOne (int millisecondsTimeout)
189                         {
190                                 return WaitHandle.WaitAll (ResultWaitHandles, millisecondsTimeout);
191                         }
192
193                         WaitHandle [] ResultWaitHandles {
194                                 get {
195                                         var arr = new WaitHandle [results.Length];
196                                         for (int i = 0; i < arr.Length; i++)
197                                                 arr [i] = results [i].AsyncWaitHandle;
198                                         return arr;
199                                 }
200                         }
201
202                         public override bool WaitOne (int millisecondsTimeout, bool exitContext)
203                         {
204                                 return WaitHandle.WaitAll (ResultWaitHandles, millisecondsTimeout, exitContext);
205                         }
206
207                         public override bool WaitOne (TimeSpan timeout, bool exitContext)
208                         {
209                                 return WaitHandle.WaitAll (ResultWaitHandles, timeout, exitContext);
210                         }
211                 }
212
213                 class DisplayUIAsyncResult : IAsyncResult
214                 {
215                         public DisplayUIAsyncResult (IAsyncResult [] results)
216                         {
217                                 this.results = results;
218                         }
219
220                         IAsyncResult [] results;
221
222                         internal IAsyncResult [] Results {
223                                 get { return results; }
224                         }
225
226                         public object AsyncState {
227                                 get { return null; }
228                         }
229
230                         WaitHandle wait_handle;
231
232                         public WaitHandle AsyncWaitHandle {
233                                 get {
234                                         if (wait_handle == null)
235                                                 wait_handle = new DelegatingWaitHandle (results);
236                                         return wait_handle;
237                                 }
238                         }
239
240                         public bool CompletedSynchronously {
241                                 get {
242                                         foreach (var r in results)
243                                                 if (!r.CompletedSynchronously)
244                                                         return false;
245                                         return true;
246                                 }
247                         }
248                         public bool IsCompleted {
249                                 get {
250                                         foreach (var r in results)
251                                                 if (!r.IsCompleted)
252                                                         return false;
253                                         return true;
254                                 }
255                         }
256                 }
257
258                 public IAsyncResult BeginDisplayInitializationUI (
259                         AsyncCallback callback, object state)
260                 {
261                         OnInitializationUI ();
262                         IAsyncResult [] arr = new IAsyncResult [runtime.InteractiveChannelInitializers.Count];
263                         int i = 0;
264                         foreach (var init in runtime.InteractiveChannelInitializers)
265                                 arr [i++] = init.BeginDisplayInitializationUI (this, callback, state);
266                         return new DisplayUIAsyncResult (arr);
267                 }
268
269                 public void EndDisplayInitializationUI (
270                         IAsyncResult result)
271                 {
272                         DisplayUIAsyncResult r = (DisplayUIAsyncResult) result;
273                         int i = 0;
274                         foreach (var init in runtime.InteractiveChannelInitializers)
275                                 init.EndDisplayInitializationUI (r.Results [i++]);
276
277                         did_interactive_initialization = true;
278                 }
279
280                 public void DisplayInitializationUI ()
281                 {
282                         OnInitializationUI ();
283                         foreach (var init in runtime.InteractiveChannelInitializers)
284                                 init.EndDisplayInitializationUI (init.BeginDisplayInitializationUI (this, null, null));
285
286                         did_interactive_initialization = true;
287                 }
288
289                 void OnInitializationUI ()
290                 {
291                         if (!AllowInitializationUI && runtime.InteractiveChannelInitializers.Count > 0)
292                                 throw new InvalidOperationException ("AllowInitializationUI is set to false but the client runtime contains one or more InteractiveChannelInitializers.");
293                 }
294
295                 public void Dispose ()
296                 {
297                         Close ();
298                 }
299
300                 public event EventHandler<UnknownMessageReceivedEventArgs> UnknownMessageReceived;
301
302                 #endregion
303
304                 #region IContextChannel
305
306                 [MonoTODO]
307                 public bool AllowOutputBatching { get; set; }
308
309                 public IInputSession InputSession {
310                         get {
311                                 ISessionChannel<IInputSession> ch = RequestChannel as ISessionChannel<IInputSession>;
312                                 ch = ch ?? OutputChannel as ISessionChannel<IInputSession>;
313                                 if (ch != null)
314                                         return ch.Session;
315                                 var dch = OutputChannel as ISessionChannel<IDuplexSession>;
316                                 return dch != null ? dch.Session : null;
317                         }
318                 }
319
320                 public EndpointAddress LocalAddress {
321                         get {
322                                 var dc = OperationChannel as IDuplexChannel;
323                                 return dc != null ? dc.LocalAddress : null;
324                         }
325                 }
326
327                 public TimeSpan OperationTimeout {
328                         get { return this.operation_timeout ?? (channel_factory != null ? channel_factory.Endpoint.Binding.SendTimeout : DefaultCommunicationTimeouts.Instance.SendTimeout); }
329                         set { this.operation_timeout = value; }
330                 }
331
332                 public IOutputSession OutputSession {
333                         get {
334                                 ISessionChannel<IOutputSession> ch = RequestChannel as ISessionChannel<IOutputSession>;
335                                 ch = ch ?? OutputChannel as ISessionChannel<IOutputSession>;
336                                 if (ch != null)
337                                         return ch.Session;
338                                 var dch = OutputChannel as ISessionChannel<IDuplexSession>;
339                                 return dch != null ? dch.Session : null;
340                         }
341                 }
342
343                 public EndpointAddress RemoteAddress {
344                         get { return RequestChannel != null ? RequestChannel.RemoteAddress : OutputChannel.RemoteAddress; }
345                 }
346
347                 public string SessionId {
348                         get { return OutputSession != null ? OutputSession.Id : InputSession != null ? InputSession.Id : null; }
349                 }
350
351                 #endregion
352
353                 // CommunicationObject
354                 protected internal override TimeSpan DefaultOpenTimeout {
355                         get { return default_open_timeout; }
356                 }
357
358                 protected internal override TimeSpan DefaultCloseTimeout {
359                         get { return default_close_timeout; }
360                 }
361
362                 protected override void OnAbort ()
363                 {
364                         channel.Abort ();
365                         if (factory != null) // ... is it valid?
366                                 factory.Abort ();
367                 }
368
369                 Action<TimeSpan> close_delegate;
370
371                 protected override IAsyncResult OnBeginClose (
372                         TimeSpan timeout, AsyncCallback callback, object state)
373                 {
374                         if (close_delegate == null)
375                                 close_delegate = new Action<TimeSpan> (OnClose);
376                         return close_delegate.BeginInvoke (timeout, callback, state);
377                 }
378
379                 protected override void OnEndClose (IAsyncResult result)
380                 {
381                         close_delegate.EndInvoke (result);
382                 }
383
384                 protected override void OnClose (TimeSpan timeout)
385                 {
386                         DateTime start = DateTime.Now;
387                         if (channel.State == CommunicationState.Opened)
388                                 channel.Close (timeout);
389                 }
390
391                 Action<TimeSpan> open_callback;
392
393                 protected override IAsyncResult OnBeginOpen (
394                         TimeSpan timeout, AsyncCallback callback, object state)
395                 {
396                         if (open_callback == null)
397                                 open_callback = new Action<TimeSpan> (OnOpen);
398                         return open_callback.BeginInvoke (timeout, callback, state);
399                 }
400
401                 protected override void OnEndOpen (IAsyncResult result)
402                 {
403                         if (open_callback == null)
404                                 throw new InvalidOperationException ("Async open operation has not started");
405                         open_callback.EndInvoke (result);
406                 }
407
408                 protected override void OnOpen (TimeSpan timeout)
409                 {
410                         if (runtime.InteractiveChannelInitializers.Count > 0 && !DidInteractiveInitialization)
411                                 throw new InvalidOperationException ("The client runtime is assigned interactive channel initializers, and in such case DisplayInitializationUI must be called before the channel is opened.");
412                         if (channel.State == CommunicationState.Created)
413                                 channel.Open (timeout);
414                 }
415
416                 // IChannel
417
418                 IChannel OperationChannel {
419                         get { return channel; }
420                 }
421
422                 public T GetProperty<T> () where T : class
423                 {
424                         if (typeof (T) == typeof (MessageVersion))
425                                 return (T) (object) message_version;
426                         return OperationChannel.GetProperty<T> ();
427                 }
428
429                 // IExtensibleObject<IContextChannel>
430
431                 IExtensionCollection<IContextChannel> extensions;
432
433                 public IExtensionCollection<IContextChannel> Extensions {
434                         get {
435                                 if (extensions == null)
436                                         extensions = new ExtensionCollection<IContextChannel> (this);
437                                 return extensions;
438                         }
439                 }
440
441                 #region Request/Output processing
442
443                 public IAsyncResult BeginProcess (MethodBase method, string operationName, object [] parameters, AsyncCallback callback, object asyncState)
444                 {
445                         var p = parameters;
446                         var retval = _processDelegate.BeginInvoke (method, operationName, true, ref p, OperationContext.Current, callback, asyncState);
447                         if (p != parameters)
448                                 throw new InvalidOperationException ();
449                         return retval;
450                 }
451
452                 public object EndProcess (MethodBase method, string operationName, object [] parameters, IAsyncResult result)
453                 {
454                         if (result == null)
455                                 throw new ArgumentNullException ("result");
456                         if (parameters == null)
457                                 throw new ArgumentNullException ("parameters");
458
459                         object[] p = parameters;
460                         var retval = _processDelegate.EndInvoke (ref p, result);
461                         if (p == parameters)
462                                 return retval;
463
464                         if (p.Length != parameters.Length)
465                                 throw new InvalidOperationException ();
466                         Array.Copy (p, parameters, p.Length);
467                         return retval;
468                 }
469
470                 public object Process (MethodBase method, string operationName, object [] parameters, OperationContext context)
471                 {
472                         var p = parameters;
473                         var retval = Process (method, operationName, false, ref p, context);
474                         if (p != parameters)
475                                 throw new InvalidOperationException ();
476                         return retval;
477                 }
478
479                 object Process (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context)
480                 {
481                         var previousContext = OperationContext.Current;
482                         try {
483                                 // Inherit the context from the calling thread
484                                 OperationContext.Current = context;
485
486                                 return DoProcess (method, operationName, isAsync, ref parameters, context);
487                         } catch (Exception ex) {
488                                 throw;
489                         } finally {
490                                 // Reset the context before the thread goes back into the pool
491                                 OperationContext.Current = previousContext;
492                         }
493                 }
494
495                 object DoProcess (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context)
496                 {
497                         if (AllowInitializationUI)
498                                 DisplayInitializationUI ();
499                         OperationDescription od = SelectOperation (method, operationName, parameters);
500
501                         if (State != CommunicationState.Opened)
502                                 Open ();
503
504                         if (!od.IsOneWay)
505                                 return Request (od, isAsync, ref parameters, context);
506                         else {
507                                 Output (od, parameters, context);
508                                 return null;
509                         }
510                 }
511
512                 OperationDescription SelectOperation (MethodBase method, string operationName, object [] parameters)
513                 {
514                         string operation;
515                         if (Runtime.OperationSelector != null)
516                                 operation = Runtime.OperationSelector.SelectOperation (method, parameters);
517                         else
518                                 operation = operationName;
519                         OperationDescription od = contract.Operations.Find (operation);
520                         if (od == null)
521                                 throw new Exception (String.Format ("OperationDescription for operation '{0}' was not found in its internally-generated contract.", operation));
522                         return od;
523                 }
524
525                 void Output (OperationDescription od, object [] parameters, OperationContext context)
526                 {
527                         ClientOperation op = runtime.Operations [od.Name];
528                         Send (CreateRequest (op, parameters, context), OperationTimeout);
529                 }
530
531                 object Request (OperationDescription od, bool isAsync, ref object [] parameters, OperationContext context)
532                 {
533                         ClientOperation op = runtime.Operations [od.Name];
534                         object [] inspections = new object [runtime.MessageInspectors.Count];
535                         Message req = CreateRequest (op, parameters, context);
536
537                         for (int i = 0; i < inspections.Length; i++)
538                                 inspections [i] = runtime.MessageInspectors [i].BeforeSendRequest (ref req, this);
539
540                         Message res = Request (req, OperationTimeout);
541                         if (res.IsFault) {
542                                 var resb = res.CreateBufferedCopy (runtime.MaxFaultSize);
543                                 MessageFault fault = MessageFault.CreateFault (resb.CreateMessage (), runtime.MaxFaultSize);
544                                 var conv = OperationChannel.GetProperty<FaultConverter> () ?? FaultConverter.GetDefaultFaultConverter (res.Version);
545                                 Exception ex;
546                                 if (!conv.TryCreateException (resb.CreateMessage (), fault, out ex)) {
547                                         if (fault.HasDetail) {
548                                                 Type detailType = typeof (ExceptionDetail);
549                                                 var freader = fault.GetReaderAtDetailContents ();
550                                                 DataContractSerializer ds = null;
551                                                 foreach (var fci in op.FaultContractInfos)
552                                                         if (res.Headers.Action == fci.Action || fci.Serializer.IsStartObject (freader)) {
553                                                                 detailType = fci.Detail;
554                                                                 ds = fci.Serializer;
555                                                                 break;
556                                                         }
557                                                 if (ds == null)
558                                                         ds = new DataContractSerializer (detailType);
559                                                 var detail = ds.ReadObject (freader);
560                                                 ex = (Exception) Activator.CreateInstance (typeof (FaultException<>).MakeGenericType (detailType), new object [] {detail, fault.Reason, fault.Code, res.Headers.Action});
561                                         }
562
563                                         if (ex == null)
564                                                 ex = new FaultException (fault);
565                                 }
566                                 throw ex;
567                         }
568
569                         for (int i = 0; i < inspections.Length; i++)
570                                 runtime.MessageInspectors [i].AfterReceiveReply (ref res, inspections [i]);
571
572                         if (!op.DeserializeReply)
573                                 return res;
574
575                         if (isAsync && od.EndMethod != null) {
576                                 var endParams = od.EndMethod.GetParameters ();
577                                 parameters = new object [endParams.Length - 1];
578                         }
579
580                         return op.Formatter.DeserializeReply (res, parameters);
581                 }
582
583                 #region Message-based Request() and Send()
584                 // They are internal for ClientBase<T>.ChannelBase use.
585                 internal Message Request (Message msg, TimeSpan timeout)
586                 {
587                         if (RequestChannel != null)
588                                 return RequestChannel.Request (msg, timeout);
589                         else
590                                 return RequestCorrelated (msg, timeout, OutputChannel);
591                 }
592
593                 internal virtual Message RequestCorrelated (Message msg, TimeSpan timeout, IOutputChannel channel)
594                 {
595                         // FIXME: implement ConcurrencyMode check:
596                         // if it is .Single && this instance for a callback channel && the operation is invoked inside service operation, then error.
597
598                         DateTime startTime = DateTime.Now;
599                         OutputChannel.Send (msg, timeout);
600                         return ((IDuplexChannel) channel).Receive (timeout - (DateTime.Now - startTime));
601                 }
602
603                 internal IAsyncResult BeginRequest (Message msg, TimeSpan timeout, AsyncCallback callback, object state)
604                 {
605                         return requestDelegate.BeginInvoke (msg, timeout, callback, state);
606                 }
607
608                 internal Message EndRequest (IAsyncResult result)
609                 {
610                         return requestDelegate.EndInvoke (result);
611                 }
612
613                 internal void Send (Message msg, TimeSpan timeout)
614                 {
615                         if (OutputChannel != null)
616                                 OutputChannel.Send (msg, timeout);
617                         else
618                                 RequestChannel.Request (msg, timeout); // and ignore returned message.
619                 }
620
621                 internal IAsyncResult BeginSend (Message msg, TimeSpan timeout, AsyncCallback callback, object state)
622                 {
623                         return sendDelegate.BeginInvoke (msg, timeout, callback, state);
624                 }
625
626                 internal void EndSend (IAsyncResult result)
627                 {
628                         sendDelegate.EndInvoke (result);
629                 }
630                 #endregion
631
632                 Message CreateRequest (ClientOperation op, object [] parameters, OperationContext context)
633                 {
634                         MessageVersion version = message_version;
635                         if (version == null)
636                                 version = MessageVersion.Default;
637
638                         Message msg;
639                         if (op.SerializeRequest)
640                                 msg = op.Formatter.SerializeRequest (
641                                         version, parameters);
642                         else {
643                                 if (parameters.Length != 1)
644                                         throw new ArgumentException (String.Format ("Argument parameters does not match the expected input. It should contain only a Message, but has {0} parameters", parameters.Length));
645                                 if (!(parameters [0] is Message))
646                                         throw new ArgumentException (String.Format ("Argument should be only a Message, but has {0}", parameters [0] != null ? parameters [0].GetType ().FullName : "null"));
647                                 msg = (Message) parameters [0];
648                         }
649
650                         context = context ?? OperationContext.Current;
651                         if (context != null) {
652                                 // CopyHeadersFrom does not work here (brings duplicates -> error)
653                                 foreach (var mh in context.OutgoingMessageHeaders) {
654                                         int x = msg.Headers.FindHeader (mh.Name, mh.Namespace, mh.Actor);
655                                         if (x >= 0)
656                                                 msg.Headers.RemoveAt (x);
657                                         msg.Headers.Add ((MessageHeader) mh);
658                                 }
659                                 msg.Properties.CopyProperties (context.OutgoingMessageProperties);
660                         }
661
662                         // FIXME: disabling MessageId as it's not seen for bug #567672 case. But might be required for PeerDuplexChannel. Check it later.
663                         //if (OutputSession != null)
664                         //      msg.Headers.MessageId = new UniqueId (OutputSession.Id);
665                         msg.Properties.AllowOutputBatching = AllowOutputBatching;
666
667                         if (msg.Version.Addressing.Equals (AddressingVersion.WSAddressing10)) {
668                                 if (msg.Headers.MessageId == null)
669                                         msg.Headers.MessageId = new UniqueId ();
670                                 if (msg.Headers.ReplyTo == null)
671                                         msg.Headers.ReplyTo = new EndpointAddress (Constants.WsaAnonymousUri);
672                                 if (msg.Headers.To == null && RemoteAddress != null)
673                                         msg.Headers.To = RemoteAddress.Uri;
674                         }
675
676                         return msg;
677                 }
678
679                 #endregion
680         }
681 }