Inheritance: System.IO.Stream, WebSocketBase.IWebSocketStream
        private static void OnReadCompleted(object sender, HttpListenerAsyncEventArgs eventArgs)
        {
            Debug.Assert(eventArgs != null, "'eventArgs' MUST NOT be NULL.");
            WebSocketHttpListenerDuplexStream thisPtr = eventArgs.CurrentStream;

            Debug.Assert(thisPtr != null, "'thisPtr' MUST NOT be NULL.");
#if DEBUG
            Debug.Assert(Interlocked.Decrement(ref thisPtr._outstandingOperations._reads) >= 0,
                         "'thisPtr.m_OutstandingOperations.m_Reads' MUST NOT be negative.");
#endif

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(thisPtr);
            }

            if (eventArgs.Exception != null)
            {
                thisPtr._readTaskCompletionSource.TrySetException(eventArgs.Exception);
            }
            else
            {
                thisPtr._readTaskCompletionSource.TrySetResult(eventArgs.BytesTransferred);
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(thisPtr);
            }
        }
Esempio n. 2
0
        private static void OnCancel(object state)
        {
            Debug.Assert(state != null, "'state' MUST NOT be NULL.");
            WebSocketHttpListenerDuplexStream thisPtr = state as WebSocketHttpListenerDuplexStream;

            Debug.Assert(thisPtr != null, "'thisPtr' MUST NOT be NULL.");

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Enter(state);
            }

            try
            {
                thisPtr._outputStream.SetClosedFlag();
                thisPtr._context.Abort();
            }
            catch { }

            thisPtr._readTaskCompletionSource?.TrySetCanceled();
            thisPtr._writeTaskCompletionSource?.TrySetCanceled();

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Exit(state);
            }
        }
            // Method called to prepare for a native async http.sys call.
            // This method performs the tasks common to all http.sys operations.
            internal void StartOperationCommon(WebSocketHttpListenerDuplexStream currentStream, ThreadPoolBoundHandle boundHandle)
            {
                // Change status to "in-use".
                if (Interlocked.CompareExchange(ref _operating, InProgress, Free) != Free)
                {
                    // If it was already "in-use" check if Dispose was called.
                    if (_disposeCalled)
                    {
                        // Dispose was called - throw ObjectDisposed.
                        throw new ObjectDisposedException(GetType().FullName);
                    }

                    Debug.Fail("Only one outstanding async operation is allowed per HttpListenerAsyncEventArgs instance.");
                    // Only one at a time.
                    throw new InvalidOperationException();
                }

                // HttpSendResponseEntityBody can return ERROR_INVALID_PARAMETER if the InternalHigh field of the overlapped
                // is not IntPtr.Zero, so we have to reset this field because we are reusing the Overlapped.
                // When using the IAsyncResult based approach of HttpListenerResponseStream the Overlapped is reinitialized
                // for each operation by the CLR when returned from the OverlappedDataCache.

                InitializeOverlapped(boundHandle);

                _exception        = null;
                _bytesTransferred = 0;
            }
 public HttpListenerAsyncEventArgs(WebSocketBase webSocket, WebSocketHttpListenerDuplexStream stream)
     : base()
 {
     m_WebSocket     = webSocket;
     m_CurrentStream = stream;
     InitializeOverlapped();
 }
        private static void OnReadCompleted(object sender, HttpListenerAsyncEventArgs eventArgs)
        {
            Contract.Assert(eventArgs != null, "'eventArgs' MUST NOT be NULL.");
            WebSocketHttpListenerDuplexStream thisPtr = eventArgs.CurrentStream;

            Contract.Assert(thisPtr != null, "'thisPtr' MUST NOT be NULL.");
#if DEBUG
            Contract.Assert(Interlocked.Decrement(ref thisPtr.m_OutstandingOperations.m_Reads) >= 0,
                            "'thisPtr.m_OutstandingOperations.m_Reads' MUST NOT be negative.");
#endif

            if (WebSocketBase.LoggingEnabled)
            {
                Logging.Enter(Logging.WebSockets, thisPtr, Methods.OnReadCompleted, string.Empty);
            }

            if (eventArgs.Exception != null)
            {
                thisPtr.m_ReadTaskCompletionSource.TrySetException(eventArgs.Exception);
            }
            else
            {
                thisPtr.m_ReadTaskCompletionSource.TrySetResult(eventArgs.BytesTransferred);
            }

            if (WebSocketBase.LoggingEnabled)
            {
                Logging.Exit(Logging.WebSockets, thisPtr, Methods.OnReadCompleted, string.Empty);
            }
        }
        private static void OnCancel(object?state)
        {
            Debug.Assert(state != null, "'state' MUST NOT be NULL.");
            WebSocketHttpListenerDuplexStream thisPtr = (state as WebSocketHttpListenerDuplexStream) !;

            Debug.Assert(thisPtr != null, "'thisPtr' MUST NOT be NULL.");

            try
            {
                thisPtr._outputStream.SetClosedFlag();
                thisPtr._context.Abort();
            }
            catch { }

            thisPtr._readTaskCompletionSource?.TrySetCanceled();
            thisPtr._writeTaskCompletionSource?.TrySetCanceled();
        }
        private static void OnWriteCompleted(object?sender, HttpListenerAsyncEventArgs eventArgs)
        {
            Debug.Assert(eventArgs != null, "'eventArgs' MUST NOT be NULL.");
            WebSocketHttpListenerDuplexStream thisPtr = eventArgs.CurrentStream;

            Debug.Assert(thisPtr != null, "'thisPtr' MUST NOT be NULL.");
#if DEBUG
            Debug.Assert(Interlocked.Decrement(ref thisPtr._outstandingOperations._writes) >= 0,
                         "'thisPtr.m_OutstandingOperations.m_Writes' MUST NOT be negative.");
#endif

            if (eventArgs.Exception != null)
            {
                thisPtr._writeTaskCompletionSource !.TrySetException(eventArgs.Exception);
            }
            else
            {
                thisPtr._writeTaskCompletionSource !.TrySetResult();
            }
        }
        private static void OnCancel(object state)
        {
            Contract.Assert(state != null, "'state' MUST NOT be NULL.");
            WebSocketHttpListenerDuplexStream thisPtr = state as WebSocketHttpListenerDuplexStream;

            Contract.Assert(thisPtr != null, "'thisPtr' MUST NOT be NULL.");

            if (WebSocketBase.LoggingEnabled)
            {
                Logging.Enter(Logging.WebSockets, state, Methods.OnCancel, string.Empty);
            }

            try
            {
                thisPtr.m_OutputStream.SetClosedFlag();
                thisPtr.m_Context.Abort();
            }
            catch { }

            TaskCompletionSource <int> readTaskCompletionSourceSnapshot = thisPtr.m_ReadTaskCompletionSource;

            if (readTaskCompletionSourceSnapshot != null)
            {
                readTaskCompletionSourceSnapshot.TrySetCanceled();
            }

            TaskCompletionSource <object> writeTaskCompletionSourceSnapshot = thisPtr.m_WriteTaskCompletionSource;

            if (writeTaskCompletionSourceSnapshot != null)
            {
                writeTaskCompletionSourceSnapshot.TrySetCanceled();
            }

            if (WebSocketBase.LoggingEnabled)
            {
                Logging.Exit(Logging.WebSockets, state, Methods.OnCancel, string.Empty);
            }
        }
 public HttpListenerAsyncEventArgs(WebSocketBase webSocket, WebSocketHttpListenerDuplexStream stream)
     : base()
 {
     _webSocket     = webSocket;
     _currentStream = stream;
 }
Esempio n. 10
0
        private static async Task <HttpListenerWebSocketContext> AcceptWebSocketAsyncCore(HttpListenerContext context,
                                                                                          string subProtocol,
                                                                                          int receiveBufferSize,
                                                                                          TimeSpan keepAliveInterval,
                                                                                          ArraySegment <byte> internalBuffer)
        {
            HttpListenerWebSocketContext webSocketContext = null;

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null, context);
            }

            try
            {
                // get property will create a new response if one doesn't exist.
                HttpListenerResponse response = context.Response;
                HttpListenerRequest  request  = context.Request;
                ValidateWebSocketHeaders(context);

                string secWebSocketVersion = request.Headers[HttpKnownHeaderNames.SecWebSocketVersion];

                // Optional for non-browser client
                string origin = request.Headers[HttpKnownHeaderNames.Origin];

                List <string> secWebSocketProtocols = new List <string>();
                string        outgoingSecWebSocketProtocolString;
                bool          shouldSendSecWebSocketProtocolHeader =
                    ProcessWebSocketProtocolHeader(
                        request.Headers[HttpKnownHeaderNames.SecWebSocketProtocol],
                        subProtocol,
                        out outgoingSecWebSocketProtocolString);

                if (shouldSendSecWebSocketProtocolHeader)
                {
                    secWebSocketProtocols.Add(outgoingSecWebSocketProtocolString);
                    response.Headers.Add(HttpKnownHeaderNames.SecWebSocketProtocol,
                                         outgoingSecWebSocketProtocolString);
                }

                // negotiate the websocket key return value
                string secWebSocketKey    = request.Headers[HttpKnownHeaderNames.SecWebSocketKey];
                string secWebSocketAccept = HttpWebSocket.GetSecWebSocketAcceptString(secWebSocketKey);

                response.Headers.Add(HttpKnownHeaderNames.Connection, HttpKnownHeaderNames.Upgrade);
                response.Headers.Add(HttpKnownHeaderNames.Upgrade, WebSocketUpgradeToken);
                response.Headers.Add(HttpKnownHeaderNames.SecWebSocketAccept, secWebSocketAccept);

                response.StatusCode = (int)HttpStatusCode.SwitchingProtocols; // HTTP 101
                response.ComputeCoreHeaders();
                ulong hresult = SendWebSocketHeaders(response);
                if (hresult != 0)
                {
                    throw new WebSocketException((int)hresult,
                                                 SR.Format(SR.net_WebSockets_NativeSendResponseHeaders,
                                                           nameof(AcceptWebSocketAsync),
                                                           hresult));
                }

                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(null, $"{HttpKnownHeaderNames.Origin} = {origin}");
                    NetEventSource.Info(null, $"{HttpKnownHeaderNames.SecWebSocketVersion} = {secWebSocketVersion}");
                    NetEventSource.Info(null, $"{HttpKnownHeaderNames.SecWebSocketKey} = {secWebSocketKey}");
                    NetEventSource.Info(null, $"{HttpKnownHeaderNames.SecWebSocketAccept} = {secWebSocketAccept}");
                    NetEventSource.Info(null, $"{HttpKnownHeaderNames.SecWebSocketProtocol} = {request.Headers[HttpKnownHeaderNames.SecWebSocketProtocol]}");
                    NetEventSource.Info(null, $"{HttpKnownHeaderNames.SecWebSocketProtocol} = {outgoingSecWebSocketProtocolString}");
                }

                await response.OutputStream.FlushAsync().SuppressContextFlow();

                HttpResponseStream responseStream = response.OutputStream as HttpResponseStream;
                Debug.Assert(responseStream != null, "'responseStream' MUST be castable to System.Net.HttpResponseStream.");
                ((HttpResponseStream)response.OutputStream).SwitchToOpaqueMode();
                HttpRequestStream requestStream = new HttpRequestStream(context);
                requestStream.SwitchToOpaqueMode();
                WebSocketHttpListenerDuplexStream webSocketStream =
                    new WebSocketHttpListenerDuplexStream(requestStream, responseStream, context);
                WebSocket webSocket = ServerWebSocket.Create(webSocketStream,
                                                             subProtocol,
                                                             receiveBufferSize,
                                                             keepAliveInterval,
                                                             internalBuffer);

                webSocketContext = new HttpListenerWebSocketContext(
                    request.Url,
                    request.Headers,
                    request.Cookies,
                    context.User,
                    request.IsAuthenticated,
                    request.IsLocal,
                    request.IsSecureConnection,
                    origin,
                    secWebSocketProtocols.AsReadOnly(),
                    secWebSocketVersion,
                    secWebSocketKey,
                    webSocket);

                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Associate(context, webSocketContext);
                    NetEventSource.Associate(webSocketContext, webSocket);
                }
            }
            catch (Exception ex)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(context, ex);
                }
                throw;
            }
            finally
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(context);
                }
            }

            return(webSocketContext);
        }
 public HttpListenerAsyncEventArgs(WebSocketBase webSocket, WebSocketHttpListenerDuplexStream stream)
     : base()
 {
     _webSocket = webSocket;
     _currentStream = stream;
 }
            // Method called to prepare for a native async http.sys call.
            // This method performs the tasks common to all http.sys operations.
            internal void StartOperationCommon(WebSocketHttpListenerDuplexStream currentStream, ThreadPoolBoundHandle boundHandle)
            {
                // Change status to "in-use".
                if (Interlocked.CompareExchange(ref _operating, InProgress, Free) != Free)
                {
                    // If it was already "in-use" check if Dispose was called.
                    if (_disposeCalled)
                    {
                        // Dispose was called - throw ObjectDisposed.
                        throw new ObjectDisposedException(GetType().FullName);
                    }

                    Debug.Assert(false, "Only one outstanding async operation is allowed per HttpListenerAsyncEventArgs instance.");
                    // Only one at a time.
                    throw new InvalidOperationException();
                }

                // HttpSendResponseEntityBody can return ERROR_INVALID_PARAMETER if the InternalHigh field of the overlapped
                // is not IntPtr.Zero, so we have to reset this field because we are reusing the Overlapped.
                // When using the IAsyncResult based approach of HttpListenerResponseStream the Overlapped is reinitialized
                // for each operation by the CLR when returned from the OverlappedDataCache.

                InitializeOverlapped(boundHandle);

                _exception = null;
                _bytesTransferred = 0;
            }
 public HttpListenerAsyncEventArgs(WebSocketBase webSocket, WebSocketHttpListenerDuplexStream stream)
     : base()
 {
     m_WebSocket = webSocket;
     m_CurrentStream = stream;
     InitializeOverlapped();
 }
            public HttpListenerAsyncEventArgs(WebSocketBase webSocket, WebSocketHttpListenerDuplexStream stream)
                : base()
            {
                m_WebSocket = webSocket;
                m_CurrentStream = stream;
                m_AllocateOverlappedOnDemand = LocalAppContextSwitches.AllocateOverlappedOnDemand;

                if (!m_AllocateOverlappedOnDemand)
                {
                    InitializeOverlapped();
                }
            }