| File: FrameworkFork\System.ServiceModel\System\ServiceModel\NetHttpBinding.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. using System; using System.ComponentModel; using System.Runtime; using System.ServiceModel.Channels; using System.Text; using Microsoft.Xml; namespace System.ServiceModel { public class NetHttpBinding : HttpBindingBase { private BinaryMessageEncodingBindingElement _binaryMessageEncodingBindingElement; private ReliableSessionBindingElement _session; private OptionalReliableSession _reliableSession; private NetHttpMessageEncoding _messageEncoding; private BasicHttpSecurity _basicHttpSecurity; public NetHttpBinding() : this(BasicHttpSecurityMode.None) { } public NetHttpBinding(BasicHttpSecurityMode securityMode) : base() { this.Initialize(); _basicHttpSecurity.Mode = securityMode; } public NetHttpBinding(BasicHttpSecurityMode securityMode, bool reliableSessionEnabled) : this(securityMode) { this.ReliableSession.Enabled = reliableSessionEnabled; } public NetHttpBinding(string configurationName) : base() { this.Initialize(); } private NetHttpBinding(BasicHttpSecurity security) : base() { this.Initialize(); _basicHttpSecurity = security; } [DefaultValue(NetHttpMessageEncoding.Binary)] public NetHttpMessageEncoding MessageEncoding { get { return _messageEncoding; } set { _messageEncoding = value; } } public BasicHttpSecurity Security { get { return _basicHttpSecurity; } set { if (value == null) { throw FxTrace.Exception.ArgumentNull("value"); } _basicHttpSecurity = value; } } public OptionalReliableSession ReliableSession { get { return _reliableSession; } set { if (value == null) { throw FxTrace.Exception.ArgumentNull("value"); } _reliableSession.CopySettings(value); } } public WebSocketTransportSettings WebSocketSettings { get { return this.InternalWebSocketSettings; } } internal override BasicHttpSecurity BasicHttpSecurity { get { return _basicHttpSecurity; } } public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingParameterCollection parameters) { if ((this.BasicHttpSecurity.Mode == BasicHttpSecurityMode.Transport || this.BasicHttpSecurity.Mode == BasicHttpSecurityMode.TransportCredentialOnly) && this.BasicHttpSecurity.Transport.ClientCredentialType == HttpClientCredentialType.InheritedFromHost) { throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format(SRServiceModel.HttpClientCredentialTypeInvalid, this.BasicHttpSecurity.Transport.ClientCredentialType))); } return base.BuildChannelFactory<TChannel>(parameters); } public override BindingElementCollection CreateBindingElements() { this.CheckSettings(); // return collection of BindingElements BindingElementCollection bindingElements = new BindingElementCollection(); // order of BindingElements is important // add security (*optional) SecurityBindingElement messageSecurity = this.BasicHttpSecurity.CreateMessageSecurity(); if (messageSecurity != null) { bindingElements.Add(messageSecurity); } // add encoding switch (this.MessageEncoding) { case NetHttpMessageEncoding.Text: bindingElements.Add(this.TextMessageEncodingBindingElement); break; case NetHttpMessageEncoding.Mtom: throw ExceptionHelper.PlatformNotSupported(string.Format(SRServiceModel.UnsupportedBindingProperty, "MessageEncoding", MessageEncoding)); default: bindingElements.Add(_binaryMessageEncodingBindingElement); break; } // add transport (http or https) bindingElements.Add(this.GetTransport()); return bindingElements.Clone(); } internal override void SetReaderQuotas(XmlDictionaryReaderQuotas readerQuotas) { readerQuotas.CopyTo(_binaryMessageEncodingBindingElement.ReaderQuotas); } internal override EnvelopeVersion GetEnvelopeVersion() { return EnvelopeVersion.Soap12; } internal static bool TryCreate(BindingElementCollection elements, out Binding binding) { binding = null; if (elements.Count > 4) { return false; } ReliableSessionBindingElement session = null; SecurityBindingElement securityElement = null; MessageEncodingBindingElement encoding = null; HttpTransportBindingElement transport = null; foreach (BindingElement element in elements) { if (element is ReliableSessionBindingElement) { session = element as ReliableSessionBindingElement; } if (element is SecurityBindingElement) { securityElement = element as SecurityBindingElement; } else if (element is TransportBindingElement) { transport = element as HttpTransportBindingElement; } else if (element is MessageEncodingBindingElement) { encoding = element as MessageEncodingBindingElement; } else { return false; } } if (transport == null || transport.WebSocketSettings.TransportUsage != WebSocketTransportUsage.Always) { return false; } HttpsTransportBindingElement httpsTransport = transport as HttpsTransportBindingElement; if ((securityElement != null) && (httpsTransport != null) && (httpsTransport.RequireClientCertificate != TransportDefaults.RequireClientCertificate)) { return false; } // process transport binding element UnifiedSecurityMode mode; HttpTransportSecurity transportSecurity = new HttpTransportSecurity(); if (!GetSecurityModeFromTransport(transport, transportSecurity, out mode)) { return false; } if (encoding == null) { return false; } if (!(encoding is TextMessageEncodingBindingElement || encoding is MtomMessageEncodingBindingElement || encoding is BinaryMessageEncodingBindingElement)) { return false; } if (encoding.MessageVersion != MessageVersion.Soap12WSAddressing10) { return false; } BasicHttpSecurity security; if (!TryCreateSecurity(securityElement, mode, transportSecurity, out security)) { return false; } NetHttpBinding netHttpBinding = new NetHttpBinding(security); netHttpBinding.InitializeFrom(transport, encoding, session); // make sure all our defaults match if (!netHttpBinding.IsBindingElementsMatch(transport, encoding, session)) { return false; } binding = netHttpBinding; return true; } internal override void CheckSettings() { base.CheckSettings(); // Mtom is not supported. if (this.MessageEncoding == NetHttpMessageEncoding.Mtom) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(string.Format(SRServiceModel.UnsupportedBindingProperty, "MessageEncoding", this.MessageEncoding))); } } private void Initialize() { _messageEncoding = NetHttpBindingDefaults.MessageEncoding; _binaryMessageEncodingBindingElement = new BinaryMessageEncodingBindingElement() { MessageVersion = MessageVersion.Soap12WSAddressing10 }; this.TextMessageEncodingBindingElement.MessageVersion = MessageVersion.Soap12WSAddressing10; _session = new ReliableSessionBindingElement(); _reliableSession = new OptionalReliableSession(_session); this.WebSocketSettings.TransportUsage = NetHttpBindingDefaults.TransportUsage; this.WebSocketSettings.SubProtocol = WebSocketTransportSettings.SoapSubProtocol; _basicHttpSecurity = new BasicHttpSecurity(); } private void InitializeFrom(HttpTransportBindingElement transport, MessageEncodingBindingElement encoding, ReliableSessionBindingElement session) { this.InitializeFrom(transport, encoding); if (encoding is BinaryMessageEncodingBindingElement) { _messageEncoding = NetHttpMessageEncoding.Binary; BinaryMessageEncodingBindingElement binary = (BinaryMessageEncodingBindingElement)encoding; this.ReaderQuotas = binary.ReaderQuotas; } if (encoding is TextMessageEncodingBindingElement) { _messageEncoding = NetHttpMessageEncoding.Text; } else if (encoding is MtomMessageEncodingBindingElement) { _messageEncoding = NetHttpMessageEncoding.Mtom; } if (session != null) { // only set properties that have standard binding manifestations _session.InactivityTimeout = session.InactivityTimeout; _session.Ordered = session.Ordered; } } private bool IsBindingElementsMatch(HttpTransportBindingElement transport, MessageEncodingBindingElement encoding, ReliableSessionBindingElement session) { if (_reliableSession.Enabled) { if (!_session.IsMatch(session)) { return false; } } else if (session != null) { return false; } switch (this.MessageEncoding) { case NetHttpMessageEncoding.Text: if (!this.TextMessageEncodingBindingElement.IsMatch(encoding)) { return false; } break; case NetHttpMessageEncoding.Mtom: if (!this.MtomMessageEncodingBindingElement.IsMatch(encoding)) { return false; } break; default: // NetHttpMessageEncoding.Binary if (!_binaryMessageEncodingBindingElement.IsMatch(encoding)) { return false; } break; } if (!this.GetTransport().IsMatch(transport)) { return false; } return true; } } }