protected internal override async Task OnOpenAsync(TimeSpan timeout)
        {
            TimeoutHelper helper = new TimeoutHelper(timeout);

            bool success = false;
            try
            {
                if (TD.WebSocketConnectionRequestSendStartIsEnabled())
                {
                    TD.WebSocketConnectionRequestSendStart(
                        EventTraceActivity,
                        RemoteAddress != null ? RemoteAddress.ToString() : string.Empty);
                }

                ChannelParameterCollection channelParameterCollection = new ChannelParameterCollection();

                HttpsChannelFactory<IDuplexSessionChannel> httpsChannelFactory = _channelFactory as HttpsChannelFactory<IDuplexSessionChannel>;
                if (httpsChannelFactory != null && httpsChannelFactory.RequireClientCertificate)
                {
                    SecurityTokenProvider certificateProvider = httpsChannelFactory.CreateAndOpenCertificateTokenProvider(RemoteAddress, Via, channelParameterCollection, helper.RemainingTime());
                }

                try
                {
                    WebSocket = await CreateWebSocketWithFactoryAsync(helper);
                }
                finally
                {
                    if (WebSocket != null && _cleanupStarted)
                    {
                        WebSocket.Abort();
                        CommunicationObjectAbortedException communicationObjectAbortedException = new CommunicationObjectAbortedException(
                            new WebSocketException(WebSocketError.ConnectionClosedPrematurely).Message);
                        FxTrace.Exception.AsWarning(communicationObjectAbortedException);
                        throw communicationObjectAbortedException;
                    }
                }

                bool inputUseStreaming = TransferModeHelper.IsResponseStreamed(TransferMode);

                SetMessageSource(new WebSocketMessageSource(
                    this,
                    WebSocket,
                    inputUseStreaming,
                    this));

                success = true;

                if (TD.WebSocketConnectionRequestSendStopIsEnabled())
                {
                    TD.WebSocketConnectionRequestSendStop(
                        EventTraceActivity,
                        WebSocket != null ? WebSocket.GetHashCode() : -1);
                }
            }
            catch (WebSocketException ex)
            {
                if (TD.WebSocketConnectionFailedIsEnabled())
                {
                    TD.WebSocketConnectionFailed(EventTraceActivity, ex.Message);
                }

                TryConvertAndThrow(ex);
            }
            finally
            {
                CleanupTokenProviders();
                if (!success)
                {
                    CleanupOnError();
                }
            }
        }
        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));
        }
        internal static Exception ConvertAndTraceException(Exception ex, TimeSpan timeout, string operation)
        {
            ObjectDisposedException objectDisposedException = ex as ObjectDisposedException;
            if (objectDisposedException != null)
            {
                CommunicationObjectAbortedException communicationObjectAbortedException = new CommunicationObjectAbortedException(ex.Message, ex);
                FxTrace.Exception.AsWarning(communicationObjectAbortedException);
                return communicationObjectAbortedException;
            }

            AggregateException aggregationException = ex as AggregateException;
            if (aggregationException != null)
            {
                Exception exception = FxTrace.Exception.AsError<OperationCanceledException>(aggregationException);
                OperationCanceledException operationCanceledException = exception as OperationCanceledException;
                if (operationCanceledException != null)
                {
                    TimeoutException timeoutException = GetTimeoutException(exception, timeout, operation);
                    FxTrace.Exception.AsWarning(timeoutException);
                    return timeoutException;
                }
                else
                {
                    Exception communicationException = ConvertAggregateExceptionToCommunicationException(aggregationException);
                    if (communicationException is CommunicationObjectAbortedException)
                    {
                        FxTrace.Exception.AsWarning(communicationException);
                        return communicationException;
                    }
                    else
                    {
                        return FxTrace.Exception.AsError(communicationException);
                    }
                }
            }

            WebSocketException webSocketException = ex as WebSocketException;
            if (webSocketException != null)
            {
                switch (webSocketException.WebSocketErrorCode)
                {
                    case WebSocketError.InvalidMessageType:
                    case WebSocketError.UnsupportedProtocol:
                    case WebSocketError.UnsupportedVersion:
                        ex = new ProtocolException(ex.Message, ex);
                        break;
                    default:
                        ex = new CommunicationException(ex.Message, ex);
                        break;
                }
            }

            return FxTrace.Exception.AsError(ex);
        }
Exemple #4
0
        internal static Exception ConvertAndTraceException(Exception ex, TimeSpan timeout, string operation)
        {
            ObjectDisposedException objectDisposedException = ex as ObjectDisposedException;
            if (objectDisposedException != null)
            {
                CommunicationObjectAbortedException communicationObjectAbortedException = new CommunicationObjectAbortedException(ex.Message, ex);
                FxTrace.Exception.AsWarning(communicationObjectAbortedException);
                return communicationObjectAbortedException;
            }

            AggregateException aggregationException = ex as AggregateException;
            if (aggregationException != null)
            {
                Exception exception = FxTrace.Exception.AsError<OperationCanceledException>(aggregationException);
                OperationCanceledException operationCanceledException = exception as OperationCanceledException;
                if (operationCanceledException != null)
                {
                    TimeoutException timeoutException = GetTimeoutException(exception, timeout, operation);
                    FxTrace.Exception.AsWarning(timeoutException);
                    return timeoutException;
                }
                else
                {
                    Exception communicationException = ConvertAggregateExceptionToCommunicationException(aggregationException);
                    if (communicationException is CommunicationObjectAbortedException)
                    {
                        FxTrace.Exception.AsWarning(communicationException);
                        return communicationException;
                    }
                    else
                    {
                        return FxTrace.Exception.AsError(communicationException);
                    }
                }
            }

            return FxTrace.Exception.AsError(ex);
        }
Exemple #5
0
        protected internal override async Task OnOpenAsync(TimeSpan timeout)
        {
            TimeoutHelper helper = new TimeoutHelper(timeout);

            bool success = false;

            try
            {
                if (WcfEventSource.Instance.WebSocketConnectionRequestSendStartIsEnabled())
                {
                    WcfEventSource.Instance.WebSocketConnectionRequestSendStart(
                        EventTraceActivity,
                        RemoteAddress != null ? RemoteAddress.ToString() : string.Empty);
                }

                ChannelParameterCollection channelParameterCollection = new ChannelParameterCollection();

                if (HttpChannelFactory <IDuplexSessionChannel> .MapIdentity(RemoteAddress, _channelFactory.AuthenticationScheme))
                {
                    lock (ThisLock)
                    {
                        _cleanupIdentity = HttpTransportSecurityHelpers.AddIdentityMapping(Via, RemoteAddress);
                    }
                }

                X509Certificate2 clientCertificate = null;
                HttpsChannelFactory <IDuplexSessionChannel> httpsChannelFactory = _channelFactory as HttpsChannelFactory <IDuplexSessionChannel>;
                if (httpsChannelFactory != null && httpsChannelFactory.RequireClientCertificate)
                {
                    var certificateProvider    = httpsChannelFactory.CreateAndOpenCertificateTokenProvider(RemoteAddress, Via, channelParameterCollection, helper.RemainingTime());
                    var clientCertificateToken = httpsChannelFactory.GetCertificateSecurityToken(certificateProvider, RemoteAddress, Via, channelParameterCollection, ref helper);
                    var x509Token = (X509SecurityToken)clientCertificateToken.Token;
                    clientCertificate = x509Token.Certificate;
                }

                try
                {
                    WebSocket = await CreateWebSocketWithFactoryAsync(clientCertificate, helper);
                }
                finally
                {
                    if (WebSocket != null && _cleanupStarted)
                    {
                        WebSocket.Abort();
                        CommunicationObjectAbortedException communicationObjectAbortedException = new CommunicationObjectAbortedException(
                            new WebSocketException(WebSocketError.ConnectionClosedPrematurely).Message);
                        FxTrace.Exception.AsWarning(communicationObjectAbortedException);
                        throw communicationObjectAbortedException;
                    }
                }

                bool inputUseStreaming = TransferModeHelper.IsResponseStreamed(TransferMode);

                SetMessageSource(new WebSocketMessageSource(
                                     this,
                                     WebSocket,
                                     inputUseStreaming,
                                     this));

                success = true;

                if (WcfEventSource.Instance.WebSocketConnectionRequestSendStopIsEnabled())
                {
                    WcfEventSource.Instance.WebSocketConnectionRequestSendStop(
                        EventTraceActivity,
                        WebSocket != null ? WebSocket.GetHashCode() : -1);
                }
            }
            catch (WebSocketException ex)
            {
                if (WcfEventSource.Instance.WebSocketConnectionFailedIsEnabled())
                {
                    WcfEventSource.Instance.WebSocketConnectionFailed(EventTraceActivity, ex.Message);
                }

                TryConvertAndThrow(ex);
            }
            finally
            {
                CleanupTokenProviders();
                if (!success)
                {
                    CleanupOnError();
                }
            }
        }
Exemple #6
0
        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));
        }