Jo Shields 3c1f479b9d Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
2015-04-07 09:35:12 +01:00

197 lines
5.7 KiB
C#

//
// System.Web.Services.Protocols.WebServiceHandlerFactory.cs
//
// Authors:
// Tim Coleman (tim@timcoleman.com)
// Dave Bettin (dave@opendotnet.com)
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
// Lluis Sanchez Gual (lluis@ximian.com)
//
// Copyright (C) Tim Coleman, 2002
// Copyright (c) 2003 Ximian, Inc. (http://www.ximian.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.IO;
using System.Net;
using System.Web.Compilation;
using System.Web.Services;
using System.Web.Services.Configuration;
using System.Web.SessionState;
using System.Web.UI;
using System.Collections.Specialized;
using WSConfig = System.Web.Services.Configuration.WebServicesSection;
using WSProtocol = System.Web.Services.Configuration.WebServiceProtocols;
namespace System.Web.Services.Protocols
{
class SessionWrapperHandler : IHttpHandler, IRequiresSessionState
{
IHttpHandler handler;
public SessionWrapperHandler (IHttpHandler handler)
{
this.handler = handler;
}
public bool IsReusable {
get { return handler.IsReusable; }
}
public void ProcessRequest (HttpContext context)
{
handler.ProcessRequest (context);
}
}
class ReadOnlySessionWrapperHandler : IHttpHandler, IRequiresSessionState, IReadOnlySessionState
{
IHttpHandler handler;
public ReadOnlySessionWrapperHandler (IHttpHandler handler)
{
this.handler = handler;
}
public bool IsReusable {
get { return handler.IsReusable; }
}
public void ProcessRequest (HttpContext context)
{
handler.ProcessRequest (context);
}
}
public class WebServiceHandlerFactory : IHttpHandlerFactory
{
#region Constructors
public WebServiceHandlerFactory ()
{
}
#endregion // Constructors
#region Methods
public IHttpHandler GetHandler (HttpContext context, string verb, string url, string filePath)
{
string fp = filePath != null ? filePath.Replace (HttpRuntime.AppDomainAppPath, "/").Replace (Path.DirectorySeparatorChar, '/') : null;
Type type;
type = BuildManager.GetCompiledType (url);
WSProtocol protocol = GuessProtocol (context, verb);
context.Items ["WebServiceSoapVersion"] =
protocol == WSProtocol.HttpSoap12 ?
SoapProtocolVersion.Soap12 :
SoapProtocolVersion.Default;
bool supported = false;
IHttpHandler handler = null;
supported = WSConfig.IsSupported (protocol);
if (!supported) {
switch (protocol) {
default:
if (((protocol & WSProtocol.AnyHttpSoap) != WSProtocol.Unknown) &&
(WSConfig.Current.EnabledProtocols & WSProtocol.AnyHttpSoap) != WSProtocol.Unknown)
throw new InvalidOperationException ("Possible SOAP version mismatch.");
break;
case WSProtocol.HttpPost:
if (WSConfig.IsSupported (WSProtocol.HttpPostLocalhost)) {
supported = context.Request.IsLocal;
}
break;
}
}
if (!supported)
throw new InvalidOperationException ("Unsupported request format.");
switch (protocol) {
case WSProtocol.HttpSoap12:
case WSProtocol.HttpSoap:
handler = GetTypeHandler (context, new HttpSoapWebServiceHandler (type));
break;
case WSProtocol.HttpPost:
case WSProtocol.HttpGet:
handler = GetTypeHandler (context, new HttpSimpleWebServiceHandler (type, protocol.ToString ()));
break;
case WSProtocol.Documentation:
SoapDocumentationHandler soapHandler;
soapHandler = new SoapDocumentationHandler (type, context);
if (soapHandler.PageHandler is IRequiresSessionState) {
if (soapHandler.PageHandler is IReadOnlySessionState)
handler = new ReadOnlySessionWrapperHandler (soapHandler);
else
handler = new SessionWrapperHandler (soapHandler);
} else {
handler = soapHandler;
}
break;
}
return handler;
}
IHttpHandler GetTypeHandler (HttpContext context, WebServiceHandler handler)
{
MethodStubInfo method = handler.GetRequestMethod (context);
if (method == null) return null;
int cache_duration = method.MethodInfo.CacheDuration;
if (cache_duration > 0)
context.Response.ExpiresAbsolute = DateTime.Now.AddSeconds (cache_duration);
if (method.MethodInfo.EnableSession)
return new SessionWrapperHandler (handler);
else
return handler;
}
static WSProtocol GuessProtocol (HttpContext context, string verb)
{
if (context.Request.PathInfo == null || context.Request.PathInfo == "")
{
if (context.Request.RequestType == "GET")
return WSProtocol.Documentation;
else
return context.Request.Headers ["SOAPAction"] != null ?
WSProtocol.HttpSoap : WSProtocol.HttpSoap12;
}
else
{
if (context.Request.RequestType == "GET")
return WSProtocol.HttpGet;
else
return WSProtocol.HttpPost;
}
}
public void ReleaseHandler (IHttpHandler handler)
{
}
#endregion // Methods
}
}