private static void OnWebSocketWriteComplete(WinHttpWebSocketState state) { Debug.Assert(state != null, "OnWebSocketWriteComplete: state is null"); state.PendingWriteOperation = false; state.TcsSend.TrySetResult(true); }
private static void OnWebSocketShutdownComplete(WinHttpWebSocketState state) { Debug.Assert(state != null, "OnWebSocketShutdownComplete: state is null"); state.UpdateState(WebSocketState.CloseSent); state.TcsCloseOutput.TrySetResult(true); }
private static void OnRequestError( WinHttpWebSocketState state, Interop.WinHttp.WINHTTP_ASYNC_RESULT asyncResult) { Debug.Assert(state != null, "OnRequestError: state is null"); var innerException = WinHttpException.CreateExceptionUsingError((int)asyncResult.dwError); switch ((uint)asyncResult.dwResult.ToInt32()) { case Interop.WinHttp.API_SEND_REQUEST: case Interop.WinHttp.API_RECEIVE_RESPONSE: { var exception = new WebSocketException(SR.net_webstatus_ConnectFailure, innerException); state.UpdateState(WebSocketState.Closed); state.TcsUpgrade.TrySetException(exception); } break; default: { Debug.Fail( "OnRequestError: Result (" + asyncResult.dwResult + ") is not expected.", "Error code: " + asyncResult.dwError + " (" + innerException.Message + ")"); } break; } }
private static void OnWebSocketError( WinHttpWebSocketState state, Interop.WinHttp.WINHTTP_WEB_SOCKET_ASYNC_RESULT asyncResult) { Debug.Assert(state != null, "OnWebSocketError: state is null"); var innerException = WinHttpException.CreateExceptionUsingError((int)(asyncResult.AsyncResult.dwError)); if (asyncResult.AsyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED) { var exception = new WebSocketException( WebSocketError.InvalidState, SR.Format( SR.net_WebSockets_InvalidState_ClosedOrAborted, "System.Net.WebSockets.InternalClientWebSocket", "Aborted"), innerException); state.UpdateState(WebSocketState.Aborted); if (state.TcsReceive != null) { state.TcsReceive.TrySetException(exception); } if (state.TcsSend != null) { state.TcsSend.TrySetException(exception); } return; } switch (asyncResult.Operation) { case Interop.WinHttp.WINHTTP_WEB_SOCKET_OPERATION.WINHTTP_WEB_SOCKET_SEND_OPERATION: state.PendingWriteOperation = false; state.TcsSend.TrySetException(innerException); break; case Interop.WinHttp.WINHTTP_WEB_SOCKET_OPERATION.WINHTTP_WEB_SOCKET_RECEIVE_OPERATION: state.PendingReadOperation = false; state.TcsReceive.TrySetException(innerException); break; case Interop.WinHttp.WINHTTP_WEB_SOCKET_OPERATION.WINHTTP_WEB_SOCKET_CLOSE_OPERATION: state.TcsClose.TrySetException(innerException); break; case Interop.WinHttp.WINHTTP_WEB_SOCKET_OPERATION.WINHTTP_WEB_SOCKET_SHUTDOWN_OPERATION: state.TcsCloseOutput.TrySetException(innerException); break; default: Debug.Fail( "OnWebSocketError: Operation (" + asyncResult.Operation + ") is not expected.", "Error code: " + asyncResult.AsyncResult.dwError + " (" + innerException.Message + ")"); break; } }
private static void OnWebSocketCloseComplete(WinHttpWebSocketState state) { Debug.Assert(state != null, "OnWebSocketCloseComplete: state is null"); state.UpdateState(WebSocketState.Closed); state.TcsClose.TrySetResult(true); }
private static void OnWebSocketHandleClosing(WinHttpWebSocketState state) { Debug.Assert(state != null, "OnWebSocketHandleClosing: state is null"); Debug.Assert(state.WebSocketHandle != null, "OnWebSocketHandleClosing: WebSocketHandle is null"); Debug.Assert(!state.WebSocketHandle.IsInvalid, "OnWebSocketHandleClosing: WebSocketHandle is invalid"); state.WebSocketHandle.DetachCallback(); state.WebSocketHandle = null; }
private static void WebSocketCallback( IntPtr handle, WinHttpWebSocketState state, uint internetStatus, IntPtr statusInformation, uint statusInformationLength) { switch (internetStatus) { case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE: OnWebSocketWriteComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_READ_COMPLETE: Debug.Assert( statusInformationLength == Marshal.SizeOf <Interop.WinHttp.WINHTTP_WEB_SOCKET_STATUS>(), "WebSocketCallback: statusInformationLength must be sizeof(WINHTTP_WEB_SOCKET_STATUS)."); var info = Marshal.PtrToStructure <Interop.WinHttp.WINHTTP_WEB_SOCKET_STATUS>(statusInformation); OnWebSocketReadComplete(state, info); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE: OnWebSocketCloseComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE: OnWebSocketShutdownComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING: OnWebSocketHandleClosing(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: Debug.Assert( statusInformationLength == Marshal.SizeOf <Interop.WinHttp.WINHTTP_WEB_SOCKET_ASYNC_RESULT>(), "WebSocketCallback: statusInformationLength must be sizeof(WINHTTP_WEB_SOCKET_ASYNC_RESULT)."); var asyncResult = Marshal.PtrToStructure <Interop.WinHttp.WINHTTP_WEB_SOCKET_ASYNC_RESULT>(statusInformation); OnWebSocketError(state, asyncResult); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SECURE_FAILURE: Debug.Assert( statusInformationLength == Marshal.SizeOf <uint>(), "WebSocketCallback: statusInformationLength must be sizeof(uint)."); // statusInformation contains a flag: WINHTTP_CALLBACK_STATUS_FLAG_* uint flags = (uint)statusInformation; OnRequestSecureFailure(state, flags); return; } }
private static void OnWebSocketSecureFailure(WinHttpWebSocketState state, uint flags) { Debug.Assert(state != null, "OnWebSocketSecureFailure: state is null"); var innerException = WinHttpException.CreateExceptionUsingError((int)Interop.WinHttp.ERROR_WINHTTP_SECURE_FAILURE); var exception = new WebSocketException(WebSocketError.ConnectionClosedPrematurely, innerException); // TODO (Issue 2509): handle SSL related exceptions. state.UpdateState(WebSocketState.Aborted); // TODO (Issue 2509): Create exception from WINHTTP_CALLBACK_STATUS_SECURE_FAILURE flags. state.TcsUpgrade.TrySetException(exception); }
private static void OnWebSocketHandleClosing(WinHttpWebSocketState state) { Debug.Assert(state != null, "OnWebSocketHandleClosing: state is null"); Debug.Assert(state.WebSocketHandle != null, "OnWebSocketHandleClosing: WebSocketHandle is null"); Debug.Assert(!state.WebSocketHandle.IsInvalid, "OnWebSocketHandleClosing: WebSocketHandle is invalid"); state.WebSocketHandle.DetachCallback(); state.WebSocketHandle = null; // Unpin the state object if there are no more open handles that are wired to the callback. if (state.DecrementHandlesOpenWithCallback() == 0) { state.Unpin(); } }
private static void RequestCallback( IntPtr handle, WinHttpWebSocketState state, uint internetStatus, IntPtr statusInformation, uint statusInformationLength) { switch (internetStatus) { case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE: OnRequestSendRequestComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE: OnRequestHeadersAvailable(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING: OnRequestHandleClosing(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: Debug.Assert( statusInformationLength == Marshal.SizeOf<Interop.WinHttp.WINHTTP_ASYNC_RESULT>(), "RequestCallback: statusInformationLength=" + statusInformationLength + " must be sizeof(WINHTTP_ASYNC_RESULT)=" + Marshal.SizeOf<Interop.WinHttp.WINHTTP_ASYNC_RESULT>()); var asyncResult = Marshal.PtrToStructure<Interop.WinHttp.WINHTTP_ASYNC_RESULT>(statusInformation); OnRequestError(state, asyncResult); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SECURE_FAILURE: Debug.Assert( statusInformationLength == Marshal.SizeOf<uint>(), "RequestCallback: statusInformationLength must be sizeof(uint)."); // statusInformation contains a flag: WINHTTP_CALLBACK_STATUS_FLAG_* uint flags = 0; unchecked { flags = (uint)Marshal.ReadInt32(statusInformation); } OnRequestSecureFailure(state, flags); return; } }
private static void RequestCallback( IntPtr handle, WinHttpWebSocketState state, uint internetStatus, IntPtr statusInformation, uint statusInformationLength) { switch (internetStatus) { case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE: OnRequestSendRequestComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE: OnRequestHeadersAvailable(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING: OnRequestHandleClosing(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: Debug.Assert( statusInformationLength == Marshal.SizeOf <Interop.WinHttp.WINHTTP_ASYNC_RESULT>(), "RequestCallback: statusInformationLength=" + statusInformationLength + " must be sizeof(WINHTTP_ASYNC_RESULT)=" + Marshal.SizeOf <Interop.WinHttp.WINHTTP_ASYNC_RESULT>()); var asyncResult = Marshal.PtrToStructure <Interop.WinHttp.WINHTTP_ASYNC_RESULT>(statusInformation); OnRequestError(state, asyncResult); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SECURE_FAILURE: Debug.Assert( statusInformationLength == Marshal.SizeOf <uint>(), "RequestCallback: statusInformationLength must be sizeof(uint)."); // statusInformation contains a flag: WINHTTP_CALLBACK_STATUS_FLAG_* uint flags = 0; unchecked { flags = (uint)Marshal.ReadInt32(statusInformation); } OnRequestSecureFailure(state, flags); return; } }
private static void OnRequestSecureFailure(WinHttpWebSocketState state, uint flags) { Debug.Assert(state != null, "OnRequestSecureFailure: state is null"); var innerException = WinHttpException.CreateExceptionUsingError((int)Interop.WinHttp.ERROR_WINHTTP_SECURE_FAILURE); var exception = new WebSocketException( WebSocketError.Success, SR.net_webstatus_ConnectFailure, innerException); // TODO: handle SSL related exceptions. state.UpdateState(WebSocketState.Closed); // TODO: Create exception from WINHTTP_CALLBACK_STATUS_SECURE_FAILURE flags. state.TcsUpgrade.TrySetException(exception); }
private static void OnWebSocketReadComplete( WinHttpWebSocketState state, Interop.WinHttp.WINHTTP_WEB_SOCKET_STATUS info) { Debug.Assert(state != null, "OnWebSocketReadComplete: state is null"); if (info.eBufferType == Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE) { state.UpdateState(WebSocketState.CloseReceived); } state.BufferType = info.eBufferType; state.BytesTransferred = info.dwBytesTransferred; state.PendingReadOperation = false; state.TcsReceive.TrySetResult(true); }
public static void WinHttpCallback( IntPtr handle, IntPtr context, uint internetStatus, IntPtr statusInformation, uint statusInformationLength) { if (Environment.HasShutdownStarted) { return; } if (context == IntPtr.Zero) { Debug.Assert(internetStatus != Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING); return; } try { WinHttpWebSocketState state = WinHttpWebSocketState.FromIntPtr(context); Debug.Assert(state != null, "WinHttpWebSocketCallback: state should not be null"); if ((state.RequestHandle != null) && (state.RequestHandle.DangerousGetHandle() == handle)) { RequestCallback(handle, state, internetStatus, statusInformation, statusInformationLength); return; } if ((state.WebSocketHandle != null) && (state.WebSocketHandle.DangerousGetHandle() == handle)) { WebSocketCallback(handle, state, internetStatus, statusInformation, statusInformationLength); return; } } catch (Exception ex) { Debug.Fail("Unhandled exception in WinHTTP callback: " + ex); } }
private static void OnRequestHeadersAvailable(WinHttpWebSocketState state) { Debug.Assert(state != null, "OnRequestHeadersAvailable: state is null"); Debug.Assert(state.TcsUpgrade != null, "OnRequestHeadersAvailable: task completion source is null"); state.TcsUpgrade.TrySetResult(true); }
private static void WebSocketCallback( IntPtr handle, WinHttpWebSocketState state, uint internetStatus, IntPtr statusInformation, uint statusInformationLength) { switch (internetStatus) { case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE: OnWebSocketWriteComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_READ_COMPLETE: Debug.Assert( statusInformationLength == Marshal.SizeOf<Interop.WinHttp.WINHTTP_WEB_SOCKET_STATUS>(), "WebSocketCallback: statusInformationLength must be sizeof(WINHTTP_WEB_SOCKET_STATUS)."); var info = Marshal.PtrToStructure<Interop.WinHttp.WINHTTP_WEB_SOCKET_STATUS>(statusInformation); OnWebSocketReadComplete(state, info); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE: OnWebSocketCloseComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE: OnWebSocketShutdownComplete(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING: OnWebSocketHandleClosing(state); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: Debug.Assert( statusInformationLength == Marshal.SizeOf<Interop.WinHttp.WINHTTP_WEB_SOCKET_ASYNC_RESULT>(), "WebSocketCallback: statusInformationLength must be sizeof(WINHTTP_WEB_SOCKET_ASYNC_RESULT)."); var asyncResult = Marshal.PtrToStructure<Interop.WinHttp.WINHTTP_WEB_SOCKET_ASYNC_RESULT>(statusInformation); OnWebSocketError(state, asyncResult); return; case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SECURE_FAILURE: Debug.Assert( statusInformationLength == Marshal.SizeOf<uint>(), "WebSocketCallback: statusInformationLength must be sizeof(uint)."); // statusInformation contains a flag: WINHTTP_CALLBACK_STATUS_FLAG_* uint flags = (uint)statusInformation; OnRequestSecureFailure(state, flags); return; } }