2005-06-05 Peter Bartok <pbartok@novell.com>
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Protocols / WebServiceHandlerFactory.cs
1 // 
2 // System.Web.Services.Protocols.WebServiceHandlerFactory.cs
3 //
4 // Authors:
5 //      Tim Coleman (tim@timcoleman.com)
6 //      Dave Bettin (dave@opendotnet.com)
7 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //      Lluis Sanchez Gual (lluis@ximian.com)
9 //
10 // Copyright (C) Tim Coleman, 2002
11 // Copyright (c) 2003 Ximian, Inc. (http://www.ximian.com)
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System.IO;
36 using System.Web.Services;
37 using System.Web.Services.Configuration;
38 using System.Web.SessionState;
39 using System.Web.UI;
40 using System.Collections.Specialized;
41
42 namespace System.Web.Services.Protocols
43 {
44         class DummyHttpHandler : IHttpHandler
45         {
46                 bool IHttpHandler.IsReusable {
47                         get { return false; }
48                 }
49
50                 void IHttpHandler.ProcessRequest (HttpContext context)
51                 {
52                         // Do nothing
53                 }
54         }
55         
56         class SessionWrapperHandler : IHttpHandler, IRequiresSessionState
57         {
58                 IHttpHandler handler;
59
60                 public SessionWrapperHandler (IHttpHandler handler)
61                 {
62                         this.handler = handler;
63                 }
64                 
65                 public bool IsReusable {
66                         get { return handler.IsReusable; }
67                 }
68
69                 public void ProcessRequest (HttpContext context)
70                 {
71                         handler.ProcessRequest (context);
72                 }
73         }
74
75         class ReadOnlySessionWrapperHandler : IHttpHandler, IRequiresSessionState, IReadOnlySessionState
76         {
77                 IHttpHandler handler;
78
79                 public ReadOnlySessionWrapperHandler (IHttpHandler handler)
80                 {
81                         this.handler = handler;
82                 }
83                 
84                 public bool IsReusable {
85                         get { return handler.IsReusable; }
86                 }
87
88                 public void ProcessRequest (HttpContext context)
89                 {
90                         handler.ProcessRequest (context);
91                 }
92         }
93         public class WebServiceHandlerFactory : IHttpHandlerFactory
94         {
95
96                 #region Constructors
97
98                 public WebServiceHandlerFactory () 
99                 {
100                 }
101                 
102                 #endregion // Constructors
103
104                 #region Methods
105
106                 public IHttpHandler GetHandler (HttpContext context, string verb, string url, string filePath)
107                 {
108                         Type type = WebServiceParser.GetCompiledType (filePath, context);
109
110                         WSProtocol protocol = GuessProtocol (context, verb);
111                         IHttpHandler handler = null;
112
113                         if (!WSConfig.IsSupported (protocol))
114                                 return new DummyHttpHandler ();
115
116                         switch (protocol) {
117                         case WSProtocol.HttpSoap:
118                                 handler = GetTypeHandler (context, new HttpSoapWebServiceHandler (type));
119                                 break;
120                         case WSProtocol.HttpPost:
121                         case WSProtocol.HttpGet:
122                                 handler = GetTypeHandler (context, new HttpSimpleWebServiceHandler (type, protocol.ToString ()));
123                                 break;
124                         case WSProtocol.Documentation:
125                                 SoapDocumentationHandler soapHandler;
126                                 soapHandler = new SoapDocumentationHandler (type, context);
127                                 if (soapHandler.PageHandler is IRequiresSessionState) {
128                                         if (soapHandler.PageHandler is IReadOnlySessionState)
129                                                 handler = new ReadOnlySessionWrapperHandler (soapHandler);
130                                         else
131                                                 handler = new SessionWrapperHandler (soapHandler);
132                                 } else {
133                                         handler = soapHandler;
134                                 }
135                                 break;
136                         }
137
138                         return handler;
139                 }
140                 
141                 IHttpHandler GetTypeHandler (HttpContext context, WebServiceHandler handler)
142                 {
143                         MethodStubInfo method = handler.GetRequestMethod (context);
144                         if (method == null) return null;
145                         
146                         if (method.MethodInfo.EnableSession)
147                                 return new SessionWrapperHandler (handler);
148                         else
149                                 return handler;
150                 }
151
152                 static WSProtocol GuessProtocol (HttpContext context, string verb)
153                 {
154                         if (context.Request.PathInfo == null || context.Request.PathInfo == "")
155                         {
156                                 if (context.Request.RequestType == "GET")
157                                         return WSProtocol.Documentation;
158                                 else
159                                         return WSProtocol.HttpSoap;
160                         }
161                         else
162                         {
163                                 if (context.Request.RequestType == "GET")
164                                         return WSProtocol.HttpGet;
165                                 else
166                                         return WSProtocol.HttpPost;
167                         }
168                 }
169
170                 public void ReleaseHandler (IHttpHandler handler)
171                 {
172                 }
173
174                 #endregion // Methods
175         }
176 }