Merge pull request #1542 from ninjarobot/UriTemplateMatchException
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Dispatcher / BaseRequestProcessor.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.IO;
9 using System.Xml;
10 using System.Net.Sockets;
11
12 namespace System.ServiceModel.Dispatcher
13 {
14         internal class BaseRequestProcessor
15         {
16                 HandlersChain initialize_handlers_chain = new HandlersChain();
17                 HandlersChain process_handlers_chain = new HandlersChain ();
18                 HandlersChain error_handlers_chain = new HandlersChain ();
19                 HandlersChain finalize_handlers_chain = new HandlersChain ();
20
21                 protected BaseRequestProcessor () { }
22
23                 protected virtual void ProcessRequest (MessageProcessingContext mrc)
24                 {
25                         initialize_handlers_chain.ProcessRequestChain (mrc);
26
27                         using (new OperationContextScope (mrc.OperationContext)) {
28                                 try {
29                                         process_handlers_chain.ProcessRequestChain (mrc);
30                                 } catch (IOException e) {
31                                         // FIXME?: On dropped connection do not
32                                         // dump a stacktrace, but should be safe
33                                         // to dump a console message as in
34                                         // default exception handler and 
35                                         // call error_handlers_chain
36                                         Console.WriteLine ("I/O Error (Dropped Connection?): " + e.Message);
37                                         mrc.ProcessingException = e;
38                                         error_handlers_chain.ProcessRequestChain (mrc);
39                                 } catch (SocketException e) {
40                                         // FIXME?: On dropped connection do not
41                                         // dump a stacktrace, but should be safe
42                                         // to dump a console message as in
43                                         // default exception handler and 
44                                         // call error_handlers_chain
45                                         Console.WriteLine ("SocketExcpetion (Dropped Connection?): " + e.Message);
46                                         mrc.ProcessingException = e;
47                                         error_handlers_chain.ProcessRequestChain (mrc);
48                                 } catch (XmlException e) {
49                                         // FIXME?: On dropped connection do not
50                                         // dump a stacktrace, but should be safe
51                                         // to dump a console message as in
52                                         // default exception handler and 
53                                         // call error_handlers_chain
54                                         Console.WriteLine ("XmlException (Dropped Connection?): " + e.Message);
55                                         mrc.ProcessingException = e;
56                                         error_handlers_chain.ProcessRequestChain (mrc);                         
57                                 } catch (Exception e) {
58                                         // FIXME: this is not really expected use of ChannelDispatcher.ErrorHandlers.
59                                         // They are now correctly used in process_handler_chain (namely OperationInvokerHandler).
60                                         // For this kind of "outsider" exceptions are actually left thrown
61                                         // (and could even cause server loop crash in .NET).
62
63                                         Console.WriteLine ("Exception " + e.Message + " " + e.StackTrace);
64                                         mrc.ProcessingException = e;
65                                         error_handlers_chain.ProcessRequestChain (mrc);
66                                 }
67                                 finally {
68                                         finalize_handlers_chain.ProcessRequestChain (mrc);
69                                 }
70                         }
71                 }
72
73                 public HandlersChain InitializeChain
74                 {
75                         get { return initialize_handlers_chain; }
76                 }
77
78                 public HandlersChain ProcessingChain
79                 {
80                         get { return process_handlers_chain; }
81                 }
82
83                 public HandlersChain ErrorChain
84                 {
85                         get { return error_handlers_chain; }
86                 }
87
88                 public HandlersChain FinalizationChain
89                 {
90                         get { return finalize_handlers_chain; }
91                 }               
92         }
93
94         internal class HandlersChain
95         {
96                 BaseRequestProcessorHandler chain;
97
98                 public void ProcessRequestChain (MessageProcessingContext mrc)
99                 {
100                         if (chain != null)
101                                 chain.ProcessRequestChain (mrc);
102                 }
103
104                 public HandlersChain AddHandler (BaseRequestProcessorHandler handler)
105                 {
106                         if (chain == null) {
107                                 chain = handler;
108                         }
109                         else {
110                                 BaseRequestProcessorHandler current = chain;
111                                 while (current.Next != null)
112                                         current = current.Next;
113                                 current.Next = handler;
114                         }
115                         return this;
116                 }
117         }
118 }