| File: FrameworkFork\System.ServiceModel\System\ServiceModel\WSHttpBindingBase.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. namespace System.ServiceModel { using System; using System.Text; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Net; using System.Net.Security; using System.Runtime.Serialization; using System.Security.Principal; using System.ServiceModel.Channels; using System.ServiceModel.Security; using System.ComponentModel; using Microsoft.Xml; public abstract class WSHttpBindingBase : Binding, IBindingRuntimePreferences { private WSMessageEncoding _messageEncoding; private OptionalReliableSession _reliableSession; // private BindingElements private HttpTransportBindingElement _httpTransport; private HttpsTransportBindingElement _httpsTransport; private TextMessageEncodingBindingElement _textEncoding; private MtomMessageEncodingBindingElement _mtomEncoding; private TransactionFlowBindingElement _txFlow; private ReliableSessionBindingElement _session; protected WSHttpBindingBase() : base() { Initialize(); } protected WSHttpBindingBase(bool reliableSessionEnabled) : this() { this.ReliableSession.Enabled = reliableSessionEnabled; } [DefaultValue(false)] public bool TransactionFlow { get { return _txFlow.Transactions; } set { _txFlow.Transactions = value; } } [DefaultValue(HttpTransportDefaults.HostNameComparisonMode)] public HostNameComparisonMode HostNameComparisonMode { get { return _httpTransport.HostNameComparisonMode; } set { _httpTransport.HostNameComparisonMode = value; _httpsTransport.HostNameComparisonMode = value; } } [DefaultValue(TransportDefaults.MaxBufferPoolSize)] public long MaxBufferPoolSize { get { return _httpTransport.MaxBufferPoolSize; } set { _httpTransport.MaxBufferPoolSize = value; _httpsTransport.MaxBufferPoolSize = value; } } [DefaultValue(TransportDefaults.MaxReceivedMessageSize)] public long MaxReceivedMessageSize { get { return _httpTransport.MaxReceivedMessageSize; } set { if (value > int.MaxValue) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("value.MaxReceivedMessageSize", SRServiceModel.MaxReceivedMessageSizeMustBeInIntegerRange)); } _httpTransport.MaxReceivedMessageSize = value; _httpsTransport.MaxReceivedMessageSize = value; _mtomEncoding.MaxBufferSize = (int)value; } } [DefaultValue(WSHttpBindingDefaults.MessageEncoding)] public WSMessageEncoding MessageEncoding { get { return _messageEncoding; } set { _messageEncoding = value; } } public XmlDictionaryReaderQuotas ReaderQuotas { get { return _textEncoding.ReaderQuotas; } set { if (value == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); value.CopyTo(_textEncoding.ReaderQuotas); value.CopyTo(_mtomEncoding.ReaderQuotas); } } public OptionalReliableSession ReliableSession { get { return _reliableSession; } set { if (value == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value")); } _reliableSession.CopySettings(value); } } public override string Scheme { get { return GetTransport().Scheme; } } public EnvelopeVersion EnvelopeVersion { get { return EnvelopeVersion.Soap12; } } // TODO: [TypeConverter(typeof(EncodingConverter))] public System.Text.Encoding TextEncoding { get { return _textEncoding.WriteEncoding; } set { _textEncoding.WriteEncoding = value; _mtomEncoding.WriteEncoding = value; } } bool IBindingRuntimePreferences.ReceiveSynchronously { get { return false; } } internal HttpTransportBindingElement HttpTransport { get { return _httpTransport; } } internal HttpsTransportBindingElement HttpsTransport { get { return _httpsTransport; } } internal ReliableSessionBindingElement ReliableSessionBindingElement { get { return _session; } } internal TransactionFlowBindingElement TransactionFlowBindingElement { get { return _txFlow; } } private static TransactionFlowBindingElement GetDefaultTransactionFlowBindingElement() { TransactionFlowBindingElement tfbe = new TransactionFlowBindingElement(false); tfbe.TransactionProtocol = TransactionProtocol.WSAtomicTransactionOctober2004; return tfbe; } private void Initialize() { _httpTransport = new HttpTransportBindingElement(); _httpsTransport = new HttpsTransportBindingElement(); _messageEncoding = WSHttpBindingDefaults.MessageEncoding; _txFlow = GetDefaultTransactionFlowBindingElement(); _session = new ReliableSessionBindingElement(true); _textEncoding = new TextMessageEncodingBindingElement(); _textEncoding.MessageVersion = MessageVersion.Soap12WSAddressing10; _mtomEncoding = new MtomMessageEncodingBindingElement(); _mtomEncoding.MessageVersion = MessageVersion.Soap12WSAddressing10; _reliableSession = new OptionalReliableSession(_session); } private void InitializeFrom(HttpTransportBindingElement transport, MessageEncodingBindingElement encoding, TransactionFlowBindingElement txFlow, ReliableSessionBindingElement session) { this.HostNameComparisonMode = transport.HostNameComparisonMode; this.MaxBufferPoolSize = transport.MaxBufferPoolSize; this.MaxReceivedMessageSize = transport.MaxReceivedMessageSize; // this binding only supports Text and Mtom encoding if (encoding is TextMessageEncodingBindingElement) { this.MessageEncoding = WSMessageEncoding.Text; TextMessageEncodingBindingElement text = (TextMessageEncodingBindingElement)encoding; this.TextEncoding = text.WriteEncoding; this.ReaderQuotas = text.ReaderQuotas; } else if (encoding is MtomMessageEncodingBindingElement) { _messageEncoding = WSMessageEncoding.Mtom; MtomMessageEncodingBindingElement mtom = (MtomMessageEncodingBindingElement)encoding; this.TextEncoding = mtom.WriteEncoding; this.ReaderQuotas = mtom.ReaderQuotas; } this.TransactionFlow = txFlow.Transactions; _reliableSession.Enabled = session != null; //session if (session != null) { // only set properties that have standard binding manifestations _session.InactivityTimeout = session.InactivityTimeout; _session.Ordered = session.Ordered; } } // check that properties of the HttpTransportBindingElement and // MessageEncodingBindingElement not exposed as properties on BasicHttpBinding // match default values of the binding elements private bool IsBindingElementsMatch(HttpTransportBindingElement transport, MessageEncodingBindingElement encoding, TransactionFlowBindingElement txFlow, ReliableSessionBindingElement session) { if (!this.GetTransport().IsMatch(transport)) return false; if (this.MessageEncoding == WSMessageEncoding.Text) { if (!_textEncoding.IsMatch(encoding)) return false; } else if (this.MessageEncoding == WSMessageEncoding.Mtom) { if (!_mtomEncoding.IsMatch(encoding)) return false; } if (!_txFlow.IsMatch(txFlow)) return false; if (_reliableSession.Enabled) { if (!_session.IsMatch(session)) return false; } else if (session != null) { return false; } return true; } public override BindingElementCollection CreateBindingElements() { // return collection of BindingElements BindingElementCollection bindingElements = new BindingElementCollection(); // order of BindingElements is important // context bindingElements.Add(_txFlow); // reliable if (_reliableSession.Enabled) { bindingElements.Add(_session); } // add security (*optional) SecurityBindingElement wsSecurity = this.CreateMessageSecurity(); if (wsSecurity != null) { bindingElements.Add(wsSecurity); } // add encoding (text or mtom) WSMessageEncodingHelper.SyncUpEncodingBindingElementProperties(_textEncoding, _mtomEncoding); if (this.MessageEncoding == WSMessageEncoding.Text) bindingElements.Add(_textEncoding); else if (this.MessageEncoding == WSMessageEncoding.Mtom) bindingElements.Add(_mtomEncoding); // add transport (http or https) bindingElements.Add(GetTransport()); return bindingElements.Clone(); } internal static bool TryCreate(BindingElementCollection elements, out Binding binding) { binding = null; if (elements.Count > 6) return false; // collect all binding elements PrivacyNoticeBindingElement privacy = null; TransactionFlowBindingElement txFlow = null; ReliableSessionBindingElement session = null; SecurityBindingElement security = null; MessageEncodingBindingElement encoding = null; HttpTransportBindingElement transport = null; foreach (BindingElement element in elements) { if (element is SecurityBindingElement) security = element as SecurityBindingElement; else if (element is TransportBindingElement) transport = element as HttpTransportBindingElement; else if (element is MessageEncodingBindingElement) encoding = element as MessageEncodingBindingElement; else if (element is TransactionFlowBindingElement) txFlow = element as TransactionFlowBindingElement; else if (element is ReliableSessionBindingElement) session = element as ReliableSessionBindingElement; else if (element is PrivacyNoticeBindingElement) privacy = element as PrivacyNoticeBindingElement; else return false; } if (transport == null) return false; if (encoding == null) return false; if (!transport.AuthenticationScheme.IsSingleton()) { //multiple authentication schemes selected -- not supported in StandardBindings return false; } HttpsTransportBindingElement httpsTransport = transport as HttpsTransportBindingElement; if ((security != null) && (httpsTransport != null) && (httpsTransport.RequireClientCertificate != TransportDefaults.RequireClientCertificate)) { return false; } if (null != privacy || !WSHttpBinding.TryCreate(security, transport, session, txFlow, out binding)) if (!WSFederationHttpBinding.TryCreate(security, transport, privacy, session, txFlow, out binding)) if (!WS2007HttpBinding.TryCreate(security, transport, session, txFlow, out binding)) if (!WS2007FederationHttpBinding.TryCreate(security, transport, privacy, session, txFlow, out binding)) return false; if (txFlow == null) { txFlow = GetDefaultTransactionFlowBindingElement(); if ((binding is WS2007HttpBinding) || (binding is WS2007FederationHttpBinding)) { txFlow.TransactionProtocol = TransactionProtocol.WSAtomicTransaction11; } } WSHttpBindingBase wSHttpBindingBase = binding as WSHttpBindingBase; wSHttpBindingBase.InitializeFrom(transport, encoding, txFlow, session); if (!wSHttpBindingBase.IsBindingElementsMatch(transport, encoding, txFlow, session)) return false; return true; } protected abstract TransportBindingElement GetTransport(); protected abstract SecurityBindingElement CreateMessageSecurity(); } }