Open and close client/service runtime channels in chains. Fixed bug #663278.
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Dispatcher / InputOrReplyRequestProcessor.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ServiceModel;
4 using System.ServiceModel.Channels;
5 using System.ServiceModel.Security;
6 using System.ServiceModel.Security.Tokens;
7 using System.Text;
8 using System.ServiceModel.MonoInternal;
9
10 namespace System.ServiceModel.Dispatcher
11 {
12         internal class InputOrReplyRequestProcessor : BaseRequestProcessor
13         {
14                 DispatchRuntime dispatch_runtime;
15                 IChannel reply_or_input;
16
17                 public InputOrReplyRequestProcessor (DispatchRuntime runtime, IChannel replyOrInput)
18                 {
19                         Init (runtime, replyOrInput);
20
21                         //initialization
22                         InitializeChain.AddHandler (new InitializingHandler ());
23
24                         //processing
25                         ProcessingChain.AddHandler (new PostReceiveRequestHandler ()).
26                                                         AddHandler (new OperationInvokerHandler (replyOrInput));
27
28                         //errors
29                         ErrorChain.AddHandler (new ErrorProcessingHandler (replyOrInput));
30
31                         //finalize
32                         FinalizationChain.AddHandler (new FinalizeProcessingHandler ());
33                 }
34
35                 void Init (DispatchRuntime runtime, IChannel replyOrInput)
36                 {
37                         dispatch_runtime = runtime;
38                         reply_or_input = replyOrInput;
39                 }
40
41                 public void ProcessInput (Message message)
42                 {
43                         OperationContext opcx = CreateOperationContext (message);
44                         ProcessRequest (new MessageProcessingContext (opcx));
45                 }
46
47                 public void ProcessReply (RequestContext rc)
48                 {
49                         OperationContext opcx = CreateOperationContext (rc.RequestMessage);
50                         opcx.RequestContext = rc;
51                         ProcessRequest (new MessageProcessingContext (opcx));
52                 }
53
54                 OperationContext CreateOperationContext (Message incoming)
55                 {
56                         ServiceRuntimeChannel contextChannel;
57                         if (dispatch_runtime.CallbackClientRuntime.CallbackClientType != null) {
58                                 var type = ServiceProxyGenerator.CreateCallbackProxyType (dispatch_runtime, dispatch_runtime.CallbackClientRuntime.CallbackClientType);
59                                 contextChannel = (ServiceRuntimeChannel) Activator.CreateInstance (type, new object [] {reply_or_input, dispatch_runtime});
60                         }
61                         else
62                                 contextChannel = new ServiceRuntimeChannel (reply_or_input, dispatch_runtime);
63                         contextChannel.Open (); // FIXME: timeout?
64                         OperationContext opCtx = new OperationContext (contextChannel);
65                         opCtx.IncomingMessage = incoming;
66                         opCtx.EndpointDispatcher = dispatch_runtime.EndpointDispatcher;
67                         return opCtx;
68                 }
69         }
70 }