Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@ -0,0 +1,126 @@
2010-07-08 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : Set an a default DispatchOperation to throw
EndpointNotFoundException instead of raising null Invoker error.
And add error handler that converts the exception to HTTP 404.
2010-03-19 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : set FilterPriority to make it in higher
priority than conflicting endpoints (such as mex endpoint).
2010-03-16 Jb Evain <jbevain@novell.com>
* WebHttpBehavior.cs: use MOONLIGHT symbol to
disambiguate MonoTouch and Moonlight code.
2009-10-23 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : add experimental monotouch build.
2009-10-08 Atsushi Enomoto <atsushi@ximian.com>
* WebScriptEnablingBehavior.cs : use JsonQueryStringConverter, with
"d" wrapper name. Allow only WrappedRequest.
2009-10-07 Atsushi Enomoto <atsushi@ximian.com>
* WebScriptEnablingBehavior.cs : validate body style.
* WebHttpBehavior.cs : operations could miss WebGet/WebInvoke and
we should not crash by NRE because of missing of those atts.
2009-10-06 Atsushi Enomoto <atsushi@ximian.com>
* WebScriptEnablingBehavior.cs : fix listen uri which used to result
in unexpected relative recalculation against the base uri.
2009-09-18 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : parameter Wrapped check in Validate() should
not be done only for GET.
2009-09-17 Atsushi Enomoto <atsushi@ximian.com>
* WebScriptEnablingBehavior.cs : basic implementation. Create custom
ChannelDispatchers for "/js" and "/jsdebug" like we do for
/wsdl (ServiceMetadataExtension). And they return Javascript
generated from ProxyGenerator in Sys.Web.Extensions.
2009-09-02 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : now message formatters are pairs of request/
reply formatters.
2009-09-02 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : BodyStyle is operation specific.
2009-09-01 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : on validation, check wrapped parameter style.
2009-08-06 Atsushi Enomoto <atsushi@ximian.com>
* WebScriptEnablingBehavior.cs : revert GetQueryStringConverter().
(MSDN missing entry issue.)
2009-08-05 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs, WebScriptEnablingBehavior.cs :
implemented properties as in documented way.
Remove extra derived GetQueryStringConverter().
2009-08-05 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs, WebScriptEnablingBehavior.cs :
mostly implemented Validate().
2008-04-21 Igor Zelmanovich <igorz@mainsoft.com>
* WebHttpBehavior.cs : override endpoint's ContractFilter
as well as AddressFilter.
2008-04-16 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : now that ServiceHost calls Validate(),
it prevents webHttpBinding working. So, removed NIE.
2008-02-15 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : removed couple of MonoTODOs.
2008-02-15 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : ApplyDispatchBehavior() sets address filter.
2008-02-15 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs :
Call AddClientErrorInspector() in ApplyClientBehavior().
Call AddServerErrorHandlers() in ApplyDispatchBehavior().
2008-02-14 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : pass itself to WebMessageFormatter too.
2008-02-14 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : now WebMessageFormatter requires
QueryStringConverter. Hence implemented GetQueryStringConverter().
2008-02-14 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : use WebMessageFormatter (note that they are
not done yet).
2008-02-13 Atsushi Enomoto <atsushi@ximian.com>
* WebScriptEnablingBehavior.cs : new stub.
2008-02-12 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : some implementation (sorta wrong).
2008-02-07 Atsushi Enomoto <atsushi@ximian.com>
* WebHttpBehavior.cs : stub.

View File

@ -0,0 +1,339 @@
//
// WebHttpBehavior.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2008 Novell, Inc (http://www.novell.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;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
namespace System.ServiceModel.Description
{
internal static class WebHttpBehaviorExtensions
{
public static WebAttributeInfo GetWebAttributeInfo (this OperationDescription od)
{
foreach (IOperationBehavior ob in od.Behaviors) {
WebAttributeInfo info = null;
var wg = ob as WebGetAttribute;
if (wg != null)
return wg.Info;
var wi = ob as WebInvokeAttribute;
if (wi != null)
return wi.Info;
}
return new WebGetAttribute ().Info; // blank one
}
}
public class WebHttpBehavior : IEndpointBehavior
{
public WebHttpBehavior ()
{
DefaultBodyStyle = WebMessageBodyStyle.Bare;
DefaultOutgoingRequestFormat = WebMessageFormat.Xml;
DefaultOutgoingResponseFormat = WebMessageFormat.Xml;
}
#if NET_4_0
public virtual bool AutomaticFormatSelectionEnabled { get; set; }
public virtual bool FaultExceptionEnabled { get; set; }
public virtual bool HelpEnabled { get; set; }
#endif
public virtual WebMessageBodyStyle DefaultBodyStyle { get; set; }
public virtual WebMessageFormat DefaultOutgoingRequestFormat { get; set; }
public virtual WebMessageFormat DefaultOutgoingResponseFormat { get; set; }
public virtual void AddBindingParameters (ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
// nothing
}
[MonoTODO]
protected virtual void AddClientErrorInspector (ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
// clientRuntime.MessageInspectors.Add (something);
}
#if !NET_2_1
protected virtual void AddServerErrorHandlers (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add (new WebHttpErrorHandler ());
}
#endif
public virtual void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
AddClientErrorInspector (endpoint, clientRuntime);
foreach (ClientOperation oper in clientRuntime.Operations) {
var req = GetRequestClientFormatter (endpoint.Contract.Operations.Find (oper.Name), endpoint);
var res = GetReplyClientFormatter (endpoint.Contract.Operations.Find (oper.Name), endpoint);
oper.Formatter = new ClientPairFormatter (req, res);
}
}
public virtual void ApplyDispatchBehavior (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
#if NET_2_1
throw new NotImplementedException ();
#else
endpointDispatcher.DispatchRuntime.OperationSelector = GetOperationSelector (endpoint);
// FIXME: get HostNameComparisonMode from WebHttpBinding by some means.
endpointDispatcher.FilterPriority = 1; // It is to take higher priority than that of ServiceMetadataExtension (whose URL likely conflicts with this one).
endpointDispatcher.AddressFilter = new PrefixEndpointAddressMessageFilter (endpoint.Address);
endpointDispatcher.ContractFilter = new MatchAllMessageFilter ();
AddServerErrorHandlers (endpoint, endpointDispatcher);
foreach (DispatchOperation oper in endpointDispatcher.DispatchRuntime.Operations) {
var req = GetRequestDispatchFormatter (endpoint.Contract.Operations.Find (oper.Name), endpoint);
var res = GetReplyDispatchFormatter (endpoint.Contract.Operations.Find (oper.Name), endpoint);
oper.Formatter = new DispatchPairFormatter (req, res);
}
endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation = new DispatchOperation (endpointDispatcher.DispatchRuntime, "*", "*", "*") {
Invoker = new EndpointNotFoundOperationInvoker (),
DeserializeRequest = false,
SerializeReply = false};
#endif
}
internal class ClientPairFormatter : IClientMessageFormatter
{
public ClientPairFormatter (IClientMessageFormatter request, IClientMessageFormatter reply)
{
this.request = request;
this.reply = reply;
}
IClientMessageFormatter request, reply;
public Message SerializeRequest (MessageVersion messageVersion, object [] parameters)
{
return request.SerializeRequest (messageVersion, parameters);
}
public object DeserializeReply (Message message, object [] parameters)
{
return reply.DeserializeReply (message, parameters);
}
}
#if !NET_2_1
internal class DispatchPairFormatter : IDispatchMessageFormatter
{
public DispatchPairFormatter (IDispatchMessageFormatter request, IDispatchMessageFormatter reply)
{
this.request = request;
this.reply = reply;
}
IDispatchMessageFormatter request;
IDispatchMessageFormatter reply;
public void DeserializeRequest (Message message, object [] parameters)
{
request.DeserializeRequest (message, parameters);
}
public Message SerializeReply (MessageVersion messageVersion, object [] parameters, object result)
{
return reply.SerializeReply (messageVersion, parameters, result);
}
}
protected virtual WebHttpDispatchOperationSelector GetOperationSelector (ServiceEndpoint endpoint)
{
return new WebHttpDispatchOperationSelector (endpoint);
}
#endif
protected virtual QueryStringConverter GetQueryStringConverter (OperationDescription operationDescription)
{
return new QueryStringConverter ();
}
protected virtual IClientMessageFormatter GetReplyClientFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
{
return new WebMessageFormatter.ReplyClientFormatter (operationDescription, endpoint, GetQueryStringConverter (operationDescription), this);
}
#if !NET_2_1
protected virtual IDispatchMessageFormatter GetReplyDispatchFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
{
return new WebMessageFormatter.ReplyDispatchFormatter (operationDescription, endpoint, GetQueryStringConverter (operationDescription), this);
}
#endif
protected virtual IClientMessageFormatter GetRequestClientFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
{
return new WebMessageFormatter.RequestClientFormatter (operationDescription, endpoint, GetQueryStringConverter (operationDescription), this);
}
#if !NET_2_1
protected virtual IDispatchMessageFormatter GetRequestDispatchFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
{
return new WebMessageFormatter.RequestDispatchFormatter (operationDescription, endpoint, GetQueryStringConverter (operationDescription), this);
}
#endif
WebMessageBodyStyle GetBodyStyle (WebAttributeInfo wai)
{
return wai != null && wai.IsBodyStyleSetExplicitly ? wai.BodyStyle : DefaultBodyStyle;
}
protected void ValidateOperation (OperationDescription operation)
{
var wai = operation.GetWebAttributeInfo ();
if (wai.Method == "GET")
return;
var style = GetBodyStyle (wai);
// if the style is wrapped there won't be problems
if (style == WebMessageBodyStyle.Wrapped)
return;
string [] parameters;
if (wai.UriTemplate != null) {
// find all variables in the URI
var uri = new UriTemplate (wai.UriTemplate);
parameters = new string [uri.PathSegmentVariableNames.Count + uri.QueryValueVariableNames.Count];
uri.PathSegmentVariableNames.CopyTo (parameters, 0);
uri.QueryValueVariableNames.CopyTo (parameters, uri.PathSegmentVariableNames.Count);
// sort because Array.BinarySearch is the easiest way for case-insensitive search
Array.Sort (parameters, StringComparer.InvariantCultureIgnoreCase);
} else
parameters = new string [0];
bool hasBody = false;
foreach (var msg in operation.Messages) {
if (msg.Direction == MessageDirection.Input) {
// the message is for a request
// if requests are wrapped there is nothing to check
if (style == WebMessageBodyStyle.WrappedRequest)
continue;
foreach (var part in msg.Body.Parts) {
if (Array.BinarySearch (parameters, part.Name, StringComparer.InvariantCultureIgnoreCase) < 0) {
// this part of the message is not covered by a variable in the URI
// so it must be passed in the body
if (hasBody)
throw new InvalidOperationException (String.Format ("Operation '{0}' has multiple message body parts. Add parameters to the UriTemplate or change the BodyStyle to 'Wrapped' or 'WrappedRequest' on the WebInvoke/WebGet attribute.", operation.Name));
hasBody = true;
}
}
} else {
// the message is for a response
if (style != WebMessageBodyStyle.WrappedResponse && msg.Body.Parts.Count > 0)
throw new InvalidOperationException (String.Format ("Operation '{0}' has output parameters. BodyStyle must be 'Wrapped' or 'WrappedResponse' on the operation WebInvoke/WebGet attribute.", operation.Name));
}
}
}
[MonoTODO ("check UriTemplate validity")]
public virtual void Validate (ServiceEndpoint endpoint)
{
if (endpoint == null)
throw new ArgumentNullException ("endpoint");
foreach (var oper in endpoint.Contract.Operations) {
ValidateOperation (oper);
}
ValidateBinding (endpoint);
}
protected virtual void ValidateBinding (ServiceEndpoint endpoint)
{
switch (endpoint.Binding.Scheme) {
case "http":
case "https":
break;
default:
throw new InvalidOperationException ("Only http and https are allowed for WebHttpBehavior");
}
if (!endpoint.Binding.MessageVersion.Equals (MessageVersion.None))
throw new InvalidOperationException ("Only MessageVersion.None is allowed for WebHttpBehavior");
if (!endpoint.Binding.CreateBindingElements ().Find<TransportBindingElement> ().ManualAddressing)
throw new InvalidOperationException ("ManualAddressing in the transport binding element in the binding must be true for WebHttpBehavior");
}
#if !NET_2_1
internal class WebHttpErrorHandler : IErrorHandler
{
public void ProvideFault (Exception error, MessageVersion version, ref Message fault)
{
if (!(error is EndpointNotFoundException))
return;
fault = Message.CreateMessage (version, null);
var prop = new HttpResponseMessageProperty ();
prop.StatusCode = HttpStatusCode.NotFound;
fault.Properties.Add (HttpResponseMessageProperty.Name, prop);
}
public bool HandleError (Exception error)
{
return false;
}
}
class EndpointNotFoundOperationInvoker : IOperationInvoker
{
public bool IsSynchronous {
get { return true; }
}
public object [] AllocateInputs ()
{
return new object [1];
}
public object Invoke (object instance, object [] inputs, out object [] outputs)
{
throw new EndpointNotFoundException ();
}
public IAsyncResult InvokeBegin (object instance, object [] inputs, AsyncCallback callback, object state)
{
throw new EndpointNotFoundException ();
}
public object InvokeEnd (object instance, out object [] outputs, IAsyncResult result)
{
throw new InvalidOperationException ();
}
}
#endif
}
}

View File

@ -0,0 +1,86 @@
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2010 Novell, Inc. http://www.novell.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.
//
#if NET_4_0
using System;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using System.Text;
using System.Xml;
namespace System.ServiceModel.Description
{
[MonoTODO]
public class WebHttpEndpoint : WebServiceEndpoint
{
public WebHttpEndpoint (ContractDescription contract)
: this (contract, null)
{
}
public WebHttpEndpoint (ContractDescription contract, EndpointAddress address)
: base (contract, address)
{
}
WebHttpBehavior wb {
get {
var b = Behaviors.Find<WebHttpBehavior> ();
if (b != null)
return b;
throw new InvalidOperationException ("The preset WebHttpBehavior was unexpectedly removed.");
}
}
public bool AutomaticFormatSelectionEnabled {
get { return wb.AutomaticFormatSelectionEnabled; }
set { wb.AutomaticFormatSelectionEnabled = value; }
}
public WebMessageFormat DefaultOutgoingResponseFormat {
get { return wb.DefaultOutgoingResponseFormat; }
set { wb.DefaultOutgoingResponseFormat = value; }
}
public bool FaultExceptionEnabled {
get { return wb.FaultExceptionEnabled; }
set { wb.FaultExceptionEnabled = value; }
}
public bool HelpEnabled {
get { return wb.HelpEnabled; }
set { wb.HelpEnabled = value; }
}
protected override Type WebEndpointType {
get { throw new NotImplementedException (); }
}
}
}
#endif

View File

@ -0,0 +1,200 @@
//
// WebScriptEnablingBehavior.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2008 Novell, Inc (http://www.novell.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;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using System.Web.Script.Services;
namespace System.ServiceModel.Description
{
[ServiceContract (Namespace = "")]
internal class InteropScriptService
{
Type type;
string path;
bool debug;
public InteropScriptService (Type type, string path, bool debug)
{
this.type = type;
this.path = path;
this.debug = debug;
}
[WebGet (UriTemplate = "*")]
[OperationContract]
public string Get ()
{
return ProxyGenerator.GetClientProxyScript (type, path, debug);
}
}
public sealed class WebScriptEnablingBehavior : WebHttpBehavior
{
public WebScriptEnablingBehavior ()
{
DefaultBodyStyle = WebMessageBodyStyle.WrappedRequest;
DefaultOutgoingRequestFormat = WebMessageFormat.Json;
DefaultOutgoingResponseFormat = WebMessageFormat.Json;
}
public override WebMessageBodyStyle DefaultBodyStyle { get; set; }
public override WebMessageFormat DefaultOutgoingRequestFormat { get; set; }
public override WebMessageFormat DefaultOutgoingResponseFormat { get; set; }
[MonoTODO]
protected override void AddClientErrorInspector (ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
base.AddClientErrorInspector (endpoint, clientRuntime);
}
[MonoTODO]
protected override void AddServerErrorHandlers (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
base.AddServerErrorHandlers (endpoint, endpointDispatcher);
}
[MonoTODO]
public override void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
base.ApplyClientBehavior (endpoint, clientRuntime);
}
public override void ApplyDispatchBehavior (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
base.ApplyDispatchBehavior (endpoint, endpointDispatcher);
// doing similar to ServiceMetadataExtension
BuildScriptDispatcher (endpoint, endpointDispatcher, "js", false);
BuildScriptDispatcher (endpoint, endpointDispatcher, "jsdebug", true);
}
void BuildScriptDispatcher (ServiceEndpoint endpoint, EndpointDispatcher ed, string subPath, bool debug)
{
var instance = new InteropScriptService (endpoint.Contract.ContractType, endpoint.Address.Uri.ToString (), debug);
var cdOrg = ed.ChannelDispatcher;
var baseUriString = endpoint.ListenUri.ToString ();
var uri = new Uri (String.Concat (baseUriString, baseUriString [baseUriString.Length - 1] == '/' ? String.Empty : "/", subPath));
var listener = endpoint.Binding.BuildChannelListener<IReplyChannel> (uri);
var cd = new ChannelDispatcher (listener, String.Empty);
cd.MessageVersion = MessageVersion.None;
cd.Endpoints.Add (new EndpointDispatcher (new EndpointAddress (uri), "InteropScriptService", String.Empty)
{ ContractFilter = new MatchAllMessageFilter () });
var dr = cd.Endpoints [0].DispatchRuntime;
var dop = new DispatchOperation (dr, "Get", "*", "*");
dop.DeserializeRequest = false;
dop.SerializeReply = false;
dop.Invoker = new DummyInvoker (instance);
dr.UnhandledDispatchOperation = dop;
dr.InstanceContextProvider = new SingletonInstanceContextProvider (new InstanceContext (cdOrg.Host, instance));
var host = ed.ChannelDispatcher.Host;
host.ChannelDispatchers.Add (cd);
}
class DummyInvoker : IOperationInvoker
{
InteropScriptService instance;
public DummyInvoker (InteropScriptService instance)
{
this.instance = instance;
}
public object [] AllocateInputs ()
{
return new object [0];
}
public object Invoke (object instance, object [] inputs, out object [] outputs)
{
outputs = new object [0];
var msg = Message.CreateMessage (MessageVersion.None, "*", (object) null);
var hp = new HttpResponseMessageProperty ();
hp.Headers ["Content-Type"] = "text/javascript";
msg.Properties.Add (HttpResponseMessageProperty.Name, hp);
msg.Properties.Add (WebMessageEncoder.ScriptPropertyName, this.instance.Get ());
return msg;
}
public IAsyncResult InvokeBegin (object instance, object[] inputs, AsyncCallback callback, object state)
{
throw new NotSupportedException ();
}
public object InvokeEnd (object instance, out object [] outputs, IAsyncResult result)
{
throw new NotSupportedException ();
}
public bool IsSynchronous {
get { return true; }
}
}
protected override QueryStringConverter GetQueryStringConverter (OperationDescription operationDescription)
{
return new JsonQueryStringConverter () { CustomWrapperName = "d"};
}
[MonoTODO ("add non-XmlSerializer-ness check (but where?)")]
public override void Validate (ServiceEndpoint endpoint)
{
if (endpoint == null)
throw new ArgumentNullException ("endpoint");
ValidateBinding (endpoint);
foreach (var od in endpoint.Contract.Operations) {
var wai = od.GetWebAttributeInfo ();
if (wai.UriTemplate != null)
throw new InvalidOperationException ("UriTemplate must not be used with WebScriptEnablingBehavior");
var wia = od.Behaviors.Find<WebInvokeAttribute> ();
if (wia != null) {
switch (wia.Method.ToUpper ()) {
case "GET":
case "POST":
break;
default:
throw new InvalidOperationException ("Only GET and POST HTTP methods are valid used for WebScriptEnablingBehavior");
}
}
var style = wai != null && wai.IsBodyStyleSetExplicitly ? wai.BodyStyle : DefaultBodyStyle;
if (style != WebMessageBodyStyle.WrappedRequest)
throw new NotSupportedException (String.Format ("WebScriptEnableBehavior only allows WrappedRequest body style, but operation '{0}' uses {1}.", od.Name, style));
}
}
}
}

View File

@ -0,0 +1,53 @@
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2010 Novell, Inc. http://www.novell.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.
//
#if NET_4_0
using System;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace System.ServiceModel.Description
{
[MonoTODO]
public class WebScriptEndpoint : WebServiceEndpoint
{
public WebScriptEndpoint (ContractDescription contract)
: this (contract, null)
{
}
public WebScriptEndpoint (ContractDescription contract, EndpointAddress address)
: base (contract, address)
{
}
protected override Type WebEndpointType {
get { throw new NotImplementedException (); }
}
}
}
#endif

View File

@ -0,0 +1,107 @@
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2010 Novell, Inc. http://www.novell.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.
//
#if NET_4_0
using System;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using System.Text;
using System.Xml;
namespace System.ServiceModel.Description
{
public abstract class WebServiceEndpoint : ServiceEndpoint
{
internal WebServiceEndpoint (ContractDescription contract, EndpointAddress address)
: base (contract, new WebHttpBinding (), address)
{
Behaviors.Add (new WebHttpBehavior ());
}
protected abstract Type WebEndpointType { get; }
WebHttpBinding wbind {
get {
if (Binding is WebHttpBinding)
return (WebHttpBinding) Binding;
throw new InvalidOperationException ("Binding on this standard endpoint is not supposed to be overwritten.");
}
}
public WebContentTypeMapper ContentTypeMapper {
get { return wbind.ContentTypeMapper; }
set { wbind.ContentTypeMapper = value; }
}
public bool CrossDomainScriptAccessEnabled {
get { return wbind.CrossDomainScriptAccessEnabled; }
set { wbind.CrossDomainScriptAccessEnabled = value; }
}
public HostNameComparisonMode HostNameComparisonMode {
get { return wbind.HostNameComparisonMode; }
set { wbind.HostNameComparisonMode = value; }
}
public long MaxBufferPoolSize {
get { return wbind.MaxBufferPoolSize; }
set { wbind.MaxBufferPoolSize = value; }
}
public int MaxBufferSize {
get { return wbind.MaxBufferSize; }
set { wbind.MaxBufferSize = value; }
}
public long MaxReceivedMessageSize {
get { return wbind.MaxReceivedMessageSize; }
set { wbind.MaxReceivedMessageSize = value; }
}
public XmlDictionaryReaderQuotas ReaderQuotas {
get { return wbind.ReaderQuotas; }
set { wbind.ReaderQuotas = value; }
}
public WebHttpSecurity Security {
get { return wbind.Security; }
}
public TransferMode TransferMode {
get { return wbind.TransferMode; }
set { wbind.TransferMode = value; }
}
public Encoding WriteEncoding {
get { return wbind.WriteEncoding; }
set { wbind.WriteEncoding = value; }
}
}
}
#endif