886 lines · 35.3 KB · C#
RawDownload
//******************************************************************************************************//  SelfHostingService.cs - Gbtc////  Copyright © 2012, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  08/27/2009 - Pinal C. Patel//       Generated original version of source code.//  09/02/2009 - Pinal C. Patel//       Modified configuration of the default WebHttpBinding to enable receiving of large payloads.//  09/15/2009 - Stephen C. Wills//       Added new header and license agreement.//  11/27/2009 - Pinal C. Patel//       Fixed issue in the initialization of service contract name.//  03/30/2010 - Pinal C. Patel//       Updated CanRead and CanWrite to not include Enabled in its evaluation.//  05/28/2010 - Pinal C. Patel//       Added an endpoint for web service help.//  06/21/2010 - Pinal C. Patel//       Added Singleton property for added control over the hosting process.//  10/08/2010 - Pinal C. Patel//       Removed REST web service help endpoint since a similar feature is now part of WCF 4.0.//  10/14/2010 - Pinal C. Patel//       Made changes for hosting flexibility and enabling security://         Deleted DataFlow since access restriction can now be imposed by enabling security.//         Added SecurityPolicy and PublishMetadata.//         Renamed ServiceUri to Endpoints and ServiceContract to Contract.//  10/26/2010 - Pinal C. Patel//       Modified the implementation of ISupportLifecycle.Enabled property.//  10/29/2010 - Pinal C. Patel//       Modified CreateServiceBinding() to explicitly disable security on created binding if specified.//  11/19/2010 - Pinal C. Patel//       Changed to inherit from Adapter to take advantage of app domain isolation through AdapterLoader.//  12/09/2010 - Pinal C. Patel//       Modified GetUnusedPort() to use GSF.Security.Cryptography.Random instead of System.Random to//       unsure unique numbers.//  11/29/2011 - Pinal C. Patel//       Modified InitializeServiceHost() to not use a random port number for the service host address//       so that setting up security on the address is possible.//  08/02/2012 - J. Ritchie Carroll//       Added cross-domain access support for Silverlight and Flash application using self hosted//       web services (enables access to clientaccesspolicy.xml and crossdomain.xml).//  12/20/2012 - Starlynn Danyelle Gilliam//       Modified Header.//  12/11/2013 - Pinal C. Patel//       Added WindowsAuthentication property to allow Windows Authentication to be enabled explicitly//       even if SecurityPolicy is not configured to allow for more flexibility.//  09/28/2016 - J. Ritchie Carroll//       Added AutomaticFormatSelectionEnabled property to allow for non-XML based, e.g., JSON,//       formats for exception messages.////****************************************************************************************************** using System;using System.Collections.Generic;using System.IdentityModel.Policy;using System.IO;using System.Linq;using System.Net;using System.Net.NetworkInformation;using System.ServiceModel;using System.ServiceModel.Channels;using System.ServiceModel.Description;using System.ServiceModel.Web;using System.Text;using System.Text.RegularExpressions;using GSF.Adapters;using GSF.Configuration;using Random = GSF.Security.Cryptography.Random; namespace GSF.ServiceModel{    /// <summary>    /// A base class for web service that can send and receive data over REST (Representational State Transfer) interface.    /// </summary>    /// <example>    /// This example shows how to create a WCF service derived from <see cref="SelfHostingService"/> that is capable of hosting itself:    /// <code>    /// using System.ServiceModel;    /// using System.ServiceModel.Web;    /// using GSF.ServiceModel;    ///     /// namespace Services    /// {    ///     [ServiceContract()]    ///     public interface IService : ISelfHostingService    ///     {    ///         [OperationContract(), WebGet(UriTemplate = "/hello/{name}")]    ///         string Hello(string name);    ///     }    ///     ///     public class Service : SelfHostingService, IService    ///     {    ///         public string Hello(string name)    ///         {    ///             return string.Format("Hello {0}!", name);    ///         }    ///     }    /// }    /// </code>    /// This example shows how to activate a WCF service derived from <see cref="SelfHostingService"/> that is capable of hosting itself:    /// <code>    /// using System;    /// using System.ServiceModel;    /// using System.ServiceModel.Description;    /// using System.ServiceModel.Web;    /// using Services;    /// using GSF.ServiceModel;    ///     /// class Program    /// {    ///     static void Main(string[] args)    ///     {    ///         // Initialize web service.    ///         Service service = new Service();    ///         service.PublishMetadata = true;    ///         service.Endpoints = "http.soap11://localhost:4500/soap; http.rest://localhost:4500/rest";    ///         service.Initialize();    ///     ///         // Show web service status.    ///         if (service.ServiceHost.State == CommunicationState.Opened)    ///         {    ///             Console.WriteLine("\r\n{0} is running:", service.GetType().Name);    ///             foreach (ServiceEndpoint endpoint in service.ServiceHost.Description.Endpoints)    ///             {    ///                 Console.WriteLine("- {0} ({1})", endpoint.Address, endpoint.Binding.GetType().Name);    ///             }    ///             Console.Write("\r\nPress Enter key to stop...");    ///         }    ///         else    ///         {    ///             Console.WriteLine("\r\n{0} could not be started", service.GetType().Name);    ///         }    ///     ///         // Shutdown.    ///         Console.ReadLine();    ///         service.Dispose();    ///     }    /// }    /// </code>    /// This example shows how to host a WCF service derived from <see cref="SelfHostingService"/> inside ASP.NET:    /// <code>    /// <![CDATA[    /// <?xml version="1.0"?>    /// <configuration>    ///   <system.serviceModel>    ///     <services>    ///       <service name="Services.Service">    ///         <endpoint address="soap" contract="Services.IService" binding="basicHttpBinding"/>    ///         <endpoint address="rest" contract="Services.IService" binding="webHttpBinding" behaviorConfiguration="restBehavior"/>    ///       </service>    ///     </services>    ///     <behaviors>    ///       <serviceBehaviors>    ///         <behavior>    ///           <serviceMetadata httpGetEnabled="true"/>    ///         </behavior>    ///       </serviceBehaviors>    ///       <endpointBehaviors>    ///         <behavior name="restBehavior">    ///           <webHttp helpEnabled="true"/>    ///         </behavior>    ///       </endpointBehaviors>    ///     </behaviors>    ///     <serviceHostingEnvironment multipleSiteBindingsEnabled="true">    ///       <serviceActivations>    ///         <add relativeAddress="Service.svc" service="Services.Service, Services"/>    ///       </serviceActivations>    ///     </serviceHostingEnvironment>    ///   </system.serviceModel>    /// </configuration>    /// ]]>    /// </code>    /// </example>    public class SelfHostingService : Adapter, ISelfHostingService, IPolicyRetriever    {        #region [ Members ]         // Events         /// <summary>        /// Occurs when the <see cref="ServiceHost"/> has been created with the specified <see cref="Endpoints"/>.        /// </summary>        /// <remarks>        /// When <see cref="ServiceHostCreated"/> event is fired, changes like adding new endpoints can be made to the <see cref="ServiceHost"/>.        /// </remarks>        public event EventHandler ServiceHostCreated;         /// <summary>        /// Occurs when the <see cref="ServiceHost"/> has can process requests via all of its endpoints.        /// </summary>        public event EventHandler ServiceHostStarted;         /// <summary>        /// Occurs when an <see cref="Exception"/> is encountered when processing a request.        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T}.Argument"/> is the exception encountered when processing a request.        /// </remarks>        public event EventHandler<EventArgs<Exception>> ServiceProcessException;         // Fields        private string m_endpoints;        private string m_contractInterface;        private bool m_singleton;        private string m_securityPolicy;        private bool m_publishMetadata;        private bool m_allowCrossDomainAccess;        private string m_allowedDomainList;        private bool m_windowsAuthentication;        private bool m_jsonFaultHandlingEnabled;        private bool m_faultExceptionEnabled;        private bool m_automaticFormatSelectionEnabled;        private WebMessageFormat m_defaultOutgoingRequestFormat;        private WebMessageFormat m_defaultOutgoingResponseFormat;        private bool m_serviceEnabled;        private bool m_disposed;        private bool m_initialized;        private ServiceHost m_serviceHost;         #endregion         #region [ Constructors ]         /// <summary>        /// Initializes a new instance of the web service.        /// </summary>        protected SelfHostingService()        {            Type type = GetType();            m_endpoints = string.Empty;            m_contractInterface = type.Namespace + ".I" + type.Name + ", " + type.AssemblyQualifiedName.ToNonNullString().Split(',')[1].Trim();            m_allowCrossDomainAccess = false;            m_allowedDomainList = "*";            m_serviceEnabled = true;            m_faultExceptionEnabled = true;            m_defaultOutgoingRequestFormat = WebMessageFormat.Xml;            m_defaultOutgoingResponseFormat = WebMessageFormat.Xml;        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets or sets a boolean value that indicates whether the web service is currently enabled.        /// </summary>        public override bool Enabled        {            get            {                return ((object)m_serviceHost != null && m_serviceHost.State == CommunicationState.Opened);            }            set            {                if (value && !Enabled)                {                    // Enable                    if (!m_initialized)                        Initialize();                    else                        InitializeServiceHost();                }                else if (!value && Enabled)                {                    // Disable                    m_serviceHost.Close();                }            }        }         /// <summary>        /// Gets or sets a semicolon delimited list of URIs where the web service can be accessed.        /// </summary>        /// <remarks>        /// Set <see cref="Endpoints"/> to a null or empty string to disable web service hosting. Refer to <see cref="Service.CreateServiceBinding"/>         /// for a list of supported URI formats.        /// </remarks>        public string Endpoints        {            get            {                return m_endpoints;            }            set            {                m_endpoints = value;            }        }         /// <summary>        /// Gets or sets the <see cref="Type.FullName"/> of the contract interface implemented by the web service.        /// </summary>        /// <exception cref="ArgumentNullException">The value being assigned is a null or empty string.</exception>        public string ContractInterface        {            get            {                return m_contractInterface;            }            set            {                if (string.IsNullOrEmpty(value))                    throw new ArgumentNullException(nameof(value));                 m_contractInterface = value;            }        }         /// <summary>        /// Gets or sets a boolean value that indicates whether the <see cref="ServiceHost"/> will use the current instance of the web service for processing         /// requests or base the web service instance creation on <see cref="InstanceContextMode"/> specified in its <see cref="ServiceBehaviorAttribute"/>.        /// </summary>        public bool Singleton        {            get            {                return m_singleton;            }            set            {                m_singleton = value;            }        }         /// <summary>        /// Gets or sets the <see cref="Type.FullName"/> of <see cref="IAuthorizationPolicy"/> to be used for securing all web service <see cref="Endpoints"/>.        /// </summary>        public string SecurityPolicy        {            get            {                return m_securityPolicy;            }            set            {                m_securityPolicy = value;            }        }         /// <summary>        /// Gets or sets a boolean value that indicates whether web service metadata is to made available at all web service <see cref="Endpoints"/>.        /// </summary>        public bool PublishMetadata        {            get            {                return m_publishMetadata;            }            set            {                m_publishMetadata = value;            }        }         /// <summary>        /// Gets or sets flag that indicates if web services will enable cross-domain access for Silverlight and Flash applications.         /// </summary>        public bool AllowCrossDomainAccess        {            get            {                return m_allowCrossDomainAccess;            }            set            {                m_allowCrossDomainAccess = value;            }        }         /// <summary>        /// Gets or sets comma separated list of allowed domains when <see cref="AllowCrossDomainAccess"/> is <c>true</c>. Use * for domain wildcards, e.g., *.consoto.com.        /// </summary>        /// <remarks>        /// To allow all domains just set this property to "*".        /// </remarks>        public string AllowedDomainList        {            get            {                return m_allowedDomainList;            }            set            {                m_allowedDomainList = value;            }        }         /// <summary>        /// Gets or sets a boolean value that indicates whether Windows Authentication is to be enabled.        /// </summary>        public bool WindowsAuthentication        {            get            {                return m_windowsAuthentication;            }            set            {                m_windowsAuthentication = value;            }        }         /// <summary>        /// Gets or sets a boolean value that indicates whether the web service is to be enabled at startup.        /// </summary>        public bool ServiceEnabled        {            get            {                return m_serviceEnabled;            }            set            {                m_serviceEnabled = value;            }        }         /// <summary>        /// Gets or sets a value that determines if JSON formatted fault messages should be returned during exceptions.        /// </summary>        public bool JsonFaultHandlingEnabled        {            get            {                return m_jsonFaultHandlingEnabled;            }            set            {                m_jsonFaultHandlingEnabled = value;            }        }         /// <summary>        /// Gets or sets a value that determines if automatic format selection is enabled for Web HTTP bindings.        /// </summary>        public bool AutomaticFormatSelectionEnabled        {            get            {                return m_automaticFormatSelectionEnabled;            }            set            {                m_automaticFormatSelectionEnabled = value;            }        }         /// <summary>        /// Gets or sets the flag that specifies whether a FaultException is generated when an internal server error(HTTP status code: 500) occurs for Web HTTP bindings.        /// </summary>        public bool FaultExceptionEnabled        {            get            {                return m_faultExceptionEnabled;            }            set            {                m_faultExceptionEnabled = value;            }        }         /// <summary>        /// Gets and sets the default outgoing request format for Web HTTP bindings.        /// </summary>        public WebMessageFormat DefaultOutgoingRequestFormat        {            get            {                return m_defaultOutgoingRequestFormat;            }            set            {                m_defaultOutgoingRequestFormat = value;            }        }         /// <summary>        /// Gets and sets the default outgoing response format for Web HTTP bindings.        /// </summary>        public WebMessageFormat DefaultOutgoingResponseFormat        {            get            {                return m_defaultOutgoingResponseFormat;            }            set

Lines 1–500 of 886.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t