internal virtual void OnExportPolicy(MetadataExporter exporter, PolicyConversionContext policyContext) { List <string> assertionNames = new List <string>(); AuthenticationSchemes effectiveAuthenticationSchemes = HttpTransportBindingElement.GetEffectiveAuthenticationSchemes(this.AuthenticationScheme, policyContext.BindingParameters); if (effectiveAuthenticationSchemes != AuthenticationSchemes.None && !(effectiveAuthenticationSchemes.IsSet(AuthenticationSchemes.Anonymous))) { // ATTENTION: The order of the if-statements below is essential! When importing WSDL svcutil is actually // using the first assertion - and the HTTP spec requires clients to use the most secure authentication // scheme supported by the client. (especially important for downlevel (3.5/4.0) clients if (effectiveAuthenticationSchemes.IsSet(AuthenticationSchemes.Negotiate)) { assertionNames.Add(TransportPolicyConstants.NegotiateHttpAuthenticationName); } if (effectiveAuthenticationSchemes.IsSet(AuthenticationSchemes.Ntlm)) { assertionNames.Add(TransportPolicyConstants.NtlmHttpAuthenticationName); } if (effectiveAuthenticationSchemes.IsSet(AuthenticationSchemes.Digest)) { assertionNames.Add(TransportPolicyConstants.DigestHttpAuthenticationName); } if (effectiveAuthenticationSchemes.IsSet(AuthenticationSchemes.Basic)) { assertionNames.Add(TransportPolicyConstants.BasicHttpAuthenticationName); } if (assertionNames != null && assertionNames.Count > 0) { if (assertionNames.Count == 1) { policyContext.GetBindingAssertions().Add(new XmlDocument().CreateElement(TransportPolicyConstants.HttpTransportPrefix, assertionNames[0], TransportPolicyConstants.HttpTransportNamespace)); } else { XmlDocument dummy = new XmlDocument(); XmlElement root = dummy.CreateElement(MetadataStrings.WSPolicy.Prefix, MetadataStrings.WSPolicy.Elements.ExactlyOne, exporter.PolicyVersion.Namespace); foreach (string assertionName in assertionNames) { root.AppendChild(dummy.CreateElement(TransportPolicyConstants.HttpTransportPrefix, assertionName, TransportPolicyConstants.HttpTransportNamespace)); } policyContext.GetBindingAssertions().Add(root); } } } bool useWebSocketTransport = WebSocketHelper.UseWebSocketTransport(this.WebSocketSettings.TransportUsage, policyContext.Contract.IsDuplex()); if (useWebSocketTransport && this.TransferMode != TransferMode.Buffered) { policyContext.GetBindingAssertions().Add(new XmlDocument().CreateElement(TransportPolicyConstants.WebSocketPolicyPrefix, this.TransferMode.ToString(), TransportPolicyConstants.WebSocketPolicyNamespace)); } }
internal HttpChannelFactory(HttpTransportBindingElement bindingElement, BindingContext context) : base(bindingElement, context, HttpTransportDefaults.GetDefaultMessageEncoderFactory()) { // validate setting interactions if (bindingElement.TransferMode == TransferMode.Buffered) { if (bindingElement.MaxReceivedMessageSize > int.MaxValue) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("bindingElement.MaxReceivedMessageSize", SR.MaxReceivedMessageSizeMustBeInIntegerRange)); } if (bindingElement.MaxBufferSize != bindingElement.MaxReceivedMessageSize) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("bindingElement", SR.MaxBufferSizeMustMatchMaxReceivedMessageSize); } } else { if (bindingElement.MaxBufferSize > bindingElement.MaxReceivedMessageSize) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("bindingElement", SR.MaxBufferSizeMustNotExceedMaxReceivedMessageSize); } } if (TransferModeHelper.IsRequestStreamed(bindingElement.TransferMode) && bindingElement.AuthenticationScheme != AuthenticationSchemes.Anonymous) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("bindingElement", SR.HttpAuthDoesNotSupportRequestStreaming); } _allowCookies = bindingElement.AllowCookies; if (_allowCookies) { _httpCookieContainerManager = new HttpCookieContainerManager(); } if (!bindingElement.AuthenticationScheme.IsSingleton()) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.Format(SR.HttpRequiresSingleAuthScheme, bindingElement.AuthenticationScheme)); } _authenticationScheme = bindingElement.AuthenticationScheme; _maxBufferSize = bindingElement.MaxBufferSize; _transferMode = bindingElement.TransferMode; _useDefaultWebProxy = bindingElement.UseDefaultWebProxy; _channelCredentials = context.BindingParameters.Find <SecurityCredentialsManager>(); _securityCapabilities = bindingElement.GetProperty <ISecurityCapabilities>(context); _webSocketSettings = WebSocketHelper.GetRuntimeWebSocketSettings(bindingElement.WebSocketSettings); int webSocketBufferSize = WebSocketHelper.ComputeClientBufferSize(MaxReceivedMessageSize); _bufferPool = new ConnectionBufferPool(webSocketBufferSize); _clientWebSocketFactory = ClientWebSocketFactory.GetFactory(); _webSocketSoapContentType = new Lazy <string>(() => MessageEncoderFactory.CreateSessionEncoder().ContentType, LazyThreadSafetyMode.ExecutionAndPublication); }
void HandleHttpWebResponse(HttpWebRequest request, HttpWebResponse response) { this.ValidateHttpWebResponse(response); this.connection = response.GetResponseStream(); WebSocket clientWebSocket = null; try { if (this.connectionFactory != null) { this.WebSocket = clientWebSocket = this.CreateWebSocketWithFactory(); } else { byte[] internalBuffer = this.TakeBuffer(); try { this.WebSocket = clientWebSocket = WebSocket.CreateClientWebSocket( this.connection, this.WebSocketSettings.SubProtocol, WebSocketHelper.GetReceiveBufferSize(this.channelFactory.MaxReceivedMessageSize), WebSocketDefaults.BufferSize, this.WebSocketSettings.GetEffectiveKeepAliveInterval(), this.WebSocketSettings.DisablePayloadMasking, new ArraySegment <byte>(internalBuffer)); } finally { // even when setting this.InternalBuffer in the finally block // there is still a potential race condition, which could result // in not returning 'internalBuffer' to the pool. // This is acceptable since it is extremely unlikely, only for // the error case and there is no big harm if the buffers are // occasionally not returned to the pool. WebSocketBufferPool.Take() // will just allocate new buffers; this.InternalBuffer = internalBuffer; } } } finally { // There is a race condition betwene OnCleanup and OnOpen that // can result in cleaning up while the clientWebSocket instance is // created. In this case OnCleanup won't be called anymore and would // not clean up the WebSocket instance immediately - only GC would // cleanup during finalization. // To avoid this we abort the WebSocket (and implicitly this.connection) if (clientWebSocket != null && this.cleanupStarted) { clientWebSocket.Abort(); CommunicationObjectAbortedException communicationObjectAbortedException = new CommunicationObjectAbortedException( new WebSocketException(WebSocketError.ConnectionClosedPrematurely).Message); FxTrace.Exception.AsWarning(communicationObjectAbortedException); throw communicationObjectAbortedException; } } bool inputUseStreaming = TransferModeHelper.IsResponseStreamed(this.TransferMode); SecurityMessageProperty handshakeReplySecurityMessageProperty = this.channelFactory.CreateReplySecurityProperty(request, response); if (handshakeReplySecurityMessageProperty != null) { this.RemoteSecurity = handshakeReplySecurityMessageProperty; } this.SetMessageSource(new WebSocketMessageSource( this, this.WebSocket, inputUseStreaming, this)); }