Esempio n. 1
0
        protected override void WriteCore(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout)
        {
            // as per http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b201213
            // we shouldn't write more than 64K synchronously to a socket
            const int maxSocketWrite = 64 * 1024;

            ConnectionUtilities.ValidateBufferBounds(buffer, offset, size);

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            try
            {
                int bytesToWrite = size;

                using (timeoutHelper.GetCancellationToken().Register(SendCancellationCallback, this))
                {
                    while (bytesToWrite > 0)
                    {
                        size = Math.Min(bytesToWrite, maxSocketWrite);
                        _outputStream.Write(buffer, offset, size);
                        if (immediate)
                        {
                            _outputStream.Flush();
                        }

                        bytesToWrite -= size;
                        offset += size;
                    }
                }
            }
            catch (ObjectDisposedException objectDisposedException)
            {
                Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Write);
                if (ReferenceEquals(exceptionToThrow, objectDisposedException))
                {
                    throw;
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exceptionToThrow);
                }
            }
            catch (Exception exception) 
            {
                if (RTSocketError.GetStatus(exception.HResult) != SocketErrorStatus.Unknown)
                {
                    SocketException socketException = new SocketException(exception.HResult & 0x0000FFFF);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        ConvertSendException(socketException, timeoutHelper.RemainingTime()));
                }
                throw;
            }
        }
Esempio n. 2
0
        protected override int ReadCore(byte[] buffer, int offset, int size, TimeSpan timeout, bool closing)
        {
            int bytesRead = 0;
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            try
            {
                using (timeoutHelper.GetCancellationToken().Register(ReceiveCancellationCallback, this))
                {
                    bytesRead = _inputStream.Read(buffer, offset, size);
                }
            }
            catch (ObjectDisposedException objectDisposedException)
            {
                Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Read);
                if (ReferenceEquals(exceptionToThrow, objectDisposedException))
                {
                    throw;
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exceptionToThrow);
                }
            }
            catch (Exception exception)
            {
                if (RTSocketError.GetStatus(exception.HResult) != SocketErrorStatus.Unknown)
                {
                    SocketException socketException = new SocketException(exception.HResult & 0x0000FFFF);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        ConvertReceiveException(socketException, timeoutHelper.RemainingTime()));
                }
                throw;
            }

            return bytesRead;
        }
            internal override async Task OpenAsync(TimeSpan timeout)
            {
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
                base.Open(timeoutHelper.RemainingTime());

                OutWrapper<TokenImpersonationLevel> impersonationLevelWrapper = new OutWrapper<TokenImpersonationLevel>();
                OutWrapper<bool> allowNtlmWrapper = new OutWrapper<bool>(); 
                
                SecurityUtils.OpenTokenProviderIfRequired(_clientTokenProvider, timeoutHelper.RemainingTime());
                _credential = await TransportSecurityHelpers.GetSspiCredentialAsync(
                    _clientTokenProvider,
                    impersonationLevelWrapper,
                    allowNtlmWrapper,
                    timeoutHelper.GetCancellationToken());

                _impersonationLevel = impersonationLevelWrapper.Value;
                _allowNtlm = allowNtlmWrapper; 

                return; 
            }
Esempio n. 4
0
 protected override void ShutdownCore(TimeSpan timeout)
 {
     try
     {
         // All the steps of a socket shutdown are not possible with StreamSocket. As part of a socket shutdown
         // any pending data to write is given the chance to be sent so we'll attempt that.
         var toh = new TimeoutHelper(timeout);
         _outputStream.FlushAsync(toh.GetCancellationToken()).GetAwaiter().GetResult();
     }
     catch (ObjectDisposedException objectDisposedException)
     {
         Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Undefined);
         if (ReferenceEquals(exceptionToThrow, objectDisposedException))
         {
             throw;
         }
         else
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exceptionToThrow);
         }
     }
     catch (Exception exception)
     {
         if (RTSocketError.GetStatus(exception.HResult) != SocketErrorStatus.Unknown)
         {
             SocketException socketException = new SocketException(exception.HResult & 0x0000FFFF);
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                 ConvertSendException(socketException, TimeSpan.MaxValue));
         }
         throw;
     }
 }
        protected override void OnSendCore(Message message, TimeSpan timeout)
        {
            Fx.Assert(message != null, "message should not be null.");

            TimeoutHelper helper = new TimeoutHelper(timeout);
            WebSocketMessageType outgoingMessageType = GetWebSocketMessageType(message);

            if (IsStreamedOutput)
            {
                WebSocketStream webSocketStream = new WebSocketStream(WebSocket, outgoingMessageType, ((IDefaultCommunicationTimeouts)this).CloseTimeout);
                TimeoutStream timeoutStream = new TimeoutStream(webSocketStream, timeout);
                MessageEncoder.WriteMessage(message, timeoutStream);
                webSocketStream.WriteEndOfMessage();
            }
            else
            {
                ArraySegment<byte> messageData = EncodeMessage(message);
                bool success = false;
                try
                {
                    if (TD.WebSocketAsyncWriteStartIsEnabled())
                    {
                        TD.WebSocketAsyncWriteStart(
                            WebSocket.GetHashCode(),
                            messageData.Count,
                            RemoteAddress != null ? RemoteAddress.ToString() : string.Empty);
                    }

                    Task task = WebSocket.SendAsync(messageData, outgoingMessageType, true, helper.GetCancellationToken());
                    task.Wait(helper.RemainingTime(), WebSocketHelper.ThrowCorrectException, WebSocketHelper.SendOperation);

                    if (TD.WebSocketAsyncWriteStopIsEnabled())
                    {
                        TD.WebSocketAsyncWriteStop(_webSocket.GetHashCode());
                    }

                    success = true;
                }
                finally
                {
                    try
                    {
                        BufferManager.ReturnBuffer(messageData.Array);
                    }
                    catch (Exception ex)
                    {
                        if (Fx.IsFatal(ex) || success)
                        {
                            throw;
                        }

                        FxTrace.Exception.TraceUnhandledException(ex);
                    }
                }
            }
        }
        // TODO: Make TimeoutHelper disposeable which disposes it's cancellation token source
        protected override AsyncCompletionResult BeginCloseOutput(TimeSpan timeout, Action<object> callback, object state)
        {
            Fx.Assert(callback != null, "callback should not be null.");

            var helper = new TimeoutHelper(timeout);
            Task task = CloseOutputAsync(helper.GetCancellationToken());
            Fx.Assert(_pendingWritingMessageException == null, "'pendingWritingMessageException' MUST be NULL at this point.");

            if (task.IsCompleted)
            {
                _pendingWritingMessageException = WebSocketHelper.CreateExceptionOnTaskFailure(task, timeout, WebSocketHelper.CloseOperation);
                return AsyncCompletionResult.Completed;
            }

            HandleCloseOutputAsyncCompletion(task, timeout, callback, state);
            return AsyncCompletionResult.Queued;
        }
        protected override AsyncCompletionResult StartWritingBufferedMessage(Message message, ArraySegment<byte> messageData, bool allowOutputBatching, TimeSpan timeout, Action<object> callback, object state)
        {
            Contract.Assert(callback != null, "callback should not be null.");
            ConnectionUtilities.ValidateBufferBounds(messageData);

            TimeoutHelper helper = new TimeoutHelper(timeout);
            WebSocketMessageType outgoingMessageType = GetWebSocketMessageType(message);

            if (TD.WebSocketAsyncWriteStartIsEnabled())
            {
                TD.WebSocketAsyncWriteStart(
                    WebSocket.GetHashCode(),
                    messageData.Count,
                    RemoteAddress != null ? RemoteAddress.ToString() : string.Empty);
            }

            Task task = WebSocket.SendAsync(messageData, outgoingMessageType, true, helper.GetCancellationToken());
            Contract.Assert(_pendingWritingMessageException == null, "'pendingWritingMessageException' MUST be NULL at this point.");

            if (task.IsCompleted)
            {
                if (TD.WebSocketAsyncWriteStopIsEnabled())
                {
                    TD.WebSocketAsyncWriteStop(WebSocket.GetHashCode());
                }

                _pendingWritingMessageException = WebSocketHelper.CreateExceptionOnTaskFailure(task, timeout, WebSocketHelper.SendOperation);
                return AsyncCompletionResult.Completed;
            }

            HandleSendAsyncCompletion(task, timeout, callback, state);
            return AsyncCompletionResult.Queued;
        }
            void Cleanup()
            {
                if (_isForRead)
                {
                    if (Interlocked.CompareExchange(ref _messageSourceCleanState, WebSocketHelper.OperationFinished, WebSocketHelper.OperationNotStarted) == WebSocketHelper.OperationNotStarted)
                    {
                        Exception pendingException = null;
                        try
                        {
                            if (!_endofMessageReceived && (_webSocket.State == WebSocketState.Open || _webSocket.State == WebSocketState.CloseSent))
                            {
                                // Drain the reading stream
                                var closeTimeoutHelper = new TimeoutHelper(_closeTimeout);
                                do
                                {
                                    Task<WebSocketReceiveResult> receiveTask =
                                        _webSocket.ReceiveAsync(new ArraySegment<byte>(_initialReadBuffer.Array),
                                            closeTimeoutHelper.GetCancellationToken());
                                    receiveTask.Wait(closeTimeoutHelper.RemainingTime(),
                                        WebSocketHelper.ThrowCorrectException, WebSocketHelper.ReceiveOperation);
                                    _endofMessageReceived = receiveTask.GetAwaiter().GetResult().EndOfMessage;
                                } while (!_endofMessageReceived &&
                                         (_webSocket.State == WebSocketState.Open ||
                                          _webSocket.State == WebSocketState.CloseSent));
                            }
                        }
                        catch (Exception ex)
                        {
                            if (Fx.IsFatal(ex))
                            {
                                throw;
                            }

                            // Not throwing out this exception during stream cleanup. The exception
                            // will be thrown out when we are trying to receive the next message using the same
                            // WebSocket object.
                            pendingException = WebSocketHelper.ConvertAndTraceException(ex, _closeTimeout, WebSocketHelper.CloseOperation);
                        }

                        _bufferManager.ReturnBuffer(_initialReadBuffer.Array);
                        Fx.Assert(_messageSource != null, "messageSource should not be null.");
                        _messageSource.FinishUsingMessageStream(pendingException);
                    }
                }
                else
                {
                    if (Interlocked.CompareExchange(ref _endOfMessageWritten, WebSocketHelper.OperationFinished, WebSocketHelper.OperationNotStarted) == WebSocketHelper.OperationNotStarted)
                    {
                        WriteEndOfMessage();
                    }
                }
            }
            public void WriteEndOfMessage()
            {
                if (TD.WebSocketAsyncWriteStartIsEnabled())
                {
                    TD.WebSocketAsyncWriteStart(
                            _webSocket.GetHashCode(),
                            0,
                            string.Empty);
                }

                var timeoutHelper = new TimeoutHelper(_closeTimeout);

                if (Interlocked.CompareExchange(ref _endOfMessageWritten, WebSocketHelper.OperationFinished, WebSocketHelper.OperationNotStarted) == WebSocketHelper.OperationNotStarted)
                {
                    Task task = _webSocket.SendAsync(new ArraySegment<byte>(Array.Empty<byte>(), 0, 0), _outgoingMessageType, true, timeoutHelper.GetCancellationToken());
                    task.Wait(timeoutHelper.RemainingTime(), WebSocketHelper.ThrowCorrectException, WebSocketHelper.SendOperation);
                }

                if (TD.WebSocketAsyncWriteStopIsEnabled())
                {
                    TD.WebSocketAsyncWriteStop(_webSocket.GetHashCode());
                }
            }