2 // System.Web.Services.Protocols.WebServiceHandlerFactory.cs
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)
10 // Copyright (C) Tim Coleman, 2002
11 // Copyright (c) 2003 Ximian, Inc. (http://www.ximian.com)
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:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
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.
37 using System.Web.Compilation;
38 using System.Web.Services;
39 using System.Web.Services.Configuration;
40 using System.Web.SessionState;
42 using System.Collections.Specialized;
44 using WSConfig = System.Web.Services.Configuration.WebServicesSection;
45 using WSProtocol = System.Web.Services.Configuration.WebServiceProtocols;
48 namespace System.Web.Services.Protocols
50 class SessionWrapperHandler : IHttpHandler, IRequiresSessionState
54 public SessionWrapperHandler (IHttpHandler handler)
56 this.handler = handler;
59 public bool IsReusable {
60 get { return handler.IsReusable; }
63 public void ProcessRequest (HttpContext context)
65 handler.ProcessRequest (context);
69 class ReadOnlySessionWrapperHandler : IHttpHandler, IRequiresSessionState, IReadOnlySessionState
73 public ReadOnlySessionWrapperHandler (IHttpHandler handler)
75 this.handler = handler;
78 public bool IsReusable {
79 get { return handler.IsReusable; }
82 public void ProcessRequest (HttpContext context)
84 handler.ProcessRequest (context);
87 public class WebServiceHandlerFactory : IHttpHandlerFactory
92 public WebServiceHandlerFactory ()
96 #endregion // Constructors
100 public IHttpHandler GetHandler (HttpContext context, string verb, string url, string filePath)
105 string fp = filePath != null ? filePath.Replace (HttpRuntime.AppDomainAppPath, "/").Replace (Path.DirectorySeparatorChar, '/') : null;
109 #if NET_2_0 && !TARGET_JVM
110 type = BuildManager.GetCompiledType (url);
112 type = WebServiceParser.GetCompiledType (fp, context);
115 WSProtocol protocol = GuessProtocol (context, verb);
117 context.Items ["WebServiceSoapVersion"] =
118 protocol == WSProtocol.HttpSoap12 ?
119 SoapProtocolVersion.Soap12 :
120 SoapProtocolVersion.Default;
122 bool supported = false;
123 IHttpHandler handler = null;
125 supported = WSConfig.IsSupported (protocol);
130 if (((protocol & WSProtocol.AnyHttpSoap) != WSProtocol.Unknown) &&
131 (WSConfig.Current.EnabledProtocols & WSProtocol.AnyHttpSoap) != WSProtocol.Unknown)
132 throw new InvalidOperationException ("Possible SOAP version mismatch.");
135 case WSProtocol.HttpPost:
136 if (WSConfig.IsSupported (WSProtocol.HttpPostLocalhost)) {
138 supported = context.Request.IsLocal;
140 string localAddr = context.Request.ServerVariables ["LOCAL_ADDR"];
142 supported = localAddr != null &&
143 (localAddr == context.Request.ServerVariables ["REMOTE_ADDR"] ||
144 IPAddress.IsLoopback (IPAddress.Parse (localAddr)));
151 throw new InvalidOperationException ("Unsupported request format.");
154 case WSProtocol.HttpSoap12:
155 case WSProtocol.HttpSoap:
156 handler = GetTypeHandler (context, new HttpSoapWebServiceHandler (type));
158 case WSProtocol.HttpPost:
159 case WSProtocol.HttpGet:
160 handler = GetTypeHandler (context, new HttpSimpleWebServiceHandler (type, protocol.ToString ()));
162 case WSProtocol.Documentation:
163 SoapDocumentationHandler soapHandler;
164 soapHandler = new SoapDocumentationHandler (type, context);
165 if (soapHandler.PageHandler is IRequiresSessionState) {
166 if (soapHandler.PageHandler is IReadOnlySessionState)
167 handler = new ReadOnlySessionWrapperHandler (soapHandler);
169 handler = new SessionWrapperHandler (soapHandler);
171 handler = soapHandler;
179 IHttpHandler GetTypeHandler (HttpContext context, WebServiceHandler handler)
181 MethodStubInfo method = handler.GetRequestMethod (context);
182 if (method == null) return null;
184 int cache_duration = method.MethodInfo.CacheDuration;
185 if (cache_duration > 0)
186 context.Response.ExpiresAbsolute = DateTime.Now.AddSeconds (cache_duration);
187 if (method.MethodInfo.EnableSession)
188 return new SessionWrapperHandler (handler);
193 static WSProtocol GuessProtocol (HttpContext context, string verb)
195 if (context.Request.PathInfo == null || context.Request.PathInfo == "")
197 if (context.Request.RequestType == "GET")
198 return WSProtocol.Documentation;
201 return context.Request.Headers ["SOAPAction"] != null ?
202 WSProtocol.HttpSoap : WSProtocol.HttpSoap12;
204 return WSProtocol.HttpSoap;
209 if (context.Request.RequestType == "GET")
210 return WSProtocol.HttpGet;
212 return WSProtocol.HttpPost;
216 public void ReleaseHandler (IHttpHandler handler)
220 #endregion // Methods