private static void OnRequestError(WinHttpRequestState state, Interop.WinHttp.WINHTTP_ASYNC_RESULT asyncResult)
        {
            Debug.Assert(state != null, "OnRequestError: state is null");

            if (NetEventSource.Log.IsEnabled())
            {
                WinHttpTraceHelper.TraceAsyncError(state, asyncResult);
            }

            Exception innerException = WinHttpException.CreateExceptionUsingError(unchecked ((int)asyncResult.dwError), "WINHTTP_CALLBACK_STATUS_REQUEST_ERROR");

            switch (unchecked ((uint)asyncResult.dwResult.ToInt32()))
            {
            case Interop.WinHttp.API_SEND_REQUEST:
                state.LifecycleAwaitable.SetException(innerException);
                break;

            case Interop.WinHttp.API_RECEIVE_RESPONSE:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_RESEND_REQUEST)
                {
                    state.RetryRequest = true;
                    state.LifecycleAwaitable.SetResult(0);
                }
                else if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED)
                {
                    // WinHttp will automatically drop any client SSL certificates that we
                    // have pre-set into the request handle including the NULL certificate
                    // (which means we have no certs to send). For security reasons, we don't
                    // allow the certificate to be re-applied. But we need to tell WinHttp
                    // explicitly that we don't have any certificate to send.
                    Debug.Assert(state.RequestHandle != null, "OnRequestError: state.RequestHandle is null");
                    WinHttpHandler.SetNoClientCertificate(state.RequestHandle);
                    state.RetryRequest = true;
                    state.LifecycleAwaitable.SetResult(0);
                }
                else if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    state.LifecycleAwaitable.SetCanceled(state.CancellationToken);
                }
                else
                {
                    state.LifecycleAwaitable.SetException(innerException);
                }
                break;

            case Interop.WinHttp.API_QUERY_DATA_AVAILABLE:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        NetEventSource.Error(state, "QUERY_DATA_AVAILABLE - ERROR_WINHTTP_OPERATION_CANCELLED");
                    }
                    state.LifecycleAwaitable.SetCanceled();
                }
                else
                {
                    state.LifecycleAwaitable.SetException(
                        new IOException(SR.net_http_io_read, innerException));
                }
                break;

            case Interop.WinHttp.API_READ_DATA:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        NetEventSource.Error(state, "API_READ_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
                    }
                    state.LifecycleAwaitable.SetCanceled();
                }
                else
                {
                    state.LifecycleAwaitable.SetException(new IOException(SR.net_http_io_read, innerException));
                }
                break;

            case Interop.WinHttp.API_WRITE_DATA:
                Debug.Assert(state.TcsInternalWriteDataToRequestStream != null);
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        NetEventSource.Error(state, "API_WRITE_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
                    }
                    state.TcsInternalWriteDataToRequestStream.TrySetCanceled();
                }
                else
                {
                    state.TcsInternalWriteDataToRequestStream.TrySetException(
                        new IOException(SR.net_http_io_write, innerException));
                }
                break;

            default:
                Debug.Fail(
                    "OnRequestError: Result (" + asyncResult.dwResult + ") is not expected.",
                    "Error code: " + asyncResult.dwError + " (" + innerException.Message + ")");
                break;
            }
        }
        private static void OnRequestError(WinHttpRequestState state, Interop.WinHttp.WINHTTP_ASYNC_RESULT asyncResult)
        {
            WinHttpTraceHelper.TraceAsyncError("OnRequestError", asyncResult);

            Debug.Assert(state != null, "OnRequestError: state is null");

            Debug.Assert((unchecked ((int)asyncResult.dwError) != Interop.WinHttp.ERROR_INSUFFICIENT_BUFFER &&
                          unchecked ((int)asyncResult.dwError) != unchecked ((int)0x80090321)), // SEC_E_BUFFER_TOO_SMALL
                         $"Unexpected async error in WinHttpRequestCallback: {unchecked((int)asyncResult.dwError)}, WinHttp API: {unchecked((uint)asyncResult.dwResult.ToInt32())}");

            Exception innerException = WinHttpException.CreateExceptionUsingError(unchecked ((int)asyncResult.dwError));

            switch (unchecked ((uint)asyncResult.dwResult.ToInt32()))
            {
            case Interop.WinHttp.API_SEND_REQUEST:
                state.LifecycleAwaitable.SetException(innerException);
                break;

            case Interop.WinHttp.API_RECEIVE_RESPONSE:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_RESEND_REQUEST)
                {
                    state.RetryRequest = true;
                    state.LifecycleAwaitable.SetResult(0);
                }
                else if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED)
                {
                    // WinHttp will automatically drop any client SSL certificates that we
                    // have pre-set into the request handle including the NULL certificate
                    // (which means we have no certs to send). For security reasons, we don't
                    // allow the certificate to be re-applied. But we need to tell WinHttp
                    // explicitly that we don't have any certificate to send.
                    Debug.Assert(state.RequestHandle != null, "OnRequestError: state.RequestHandle is null");
                    WinHttpHandler.SetNoClientCertificate(state.RequestHandle);
                    state.RetryRequest = true;
                    state.LifecycleAwaitable.SetResult(0);
                }
                else if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    state.LifecycleAwaitable.SetCanceled(state.CancellationToken);
                }
                else
                {
                    state.LifecycleAwaitable.SetException(innerException);
                }
                break;

            case Interop.WinHttp.API_QUERY_DATA_AVAILABLE:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    // TODO: Issue #2165. We need to pass in the cancellation token from the
                    // user's ReadAsync() call into the TrySetCanceled().
                    WinHttpTraceHelper.Trace("RequestCallback: QUERY_DATA_AVAILABLE - ERROR_WINHTTP_OPERATION_CANCELLED");
                    state.LifecycleAwaitable.SetCanceled();
                }
                else
                {
                    state.LifecycleAwaitable.SetException(
                        new IOException(SR.net_http_io_read, innerException));
                }
                break;

            case Interop.WinHttp.API_READ_DATA:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    // TODO: Issue #2165. We need to pass in the cancellation token from the
                    // user's ReadAsync() call into the TrySetCanceled().
                    WinHttpTraceHelper.Trace("RequestCallback: API_READ_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
                    state.LifecycleAwaitable.SetCanceled();
                }
                else
                {
                    state.LifecycleAwaitable.SetException(new IOException(SR.net_http_io_read, innerException));
                }
                break;

            case Interop.WinHttp.API_WRITE_DATA:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    // TODO: Issue #2165. We need to pass in the cancellation token from the
                    // user's WriteAsync() call into the TrySetCanceled().
                    WinHttpTraceHelper.Trace("RequestCallback: API_WRITE_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
                    state.TcsInternalWriteDataToRequestStream.TrySetCanceled();
                }
                else
                {
                    state.TcsInternalWriteDataToRequestStream.TrySetException(
                        new IOException(SR.net_http_io_write, innerException));
                }
                break;

            default:
                Debug.Fail(
                    "OnRequestError: Result (" + asyncResult.dwResult + ") is not expected.",
                    "Error code: " + asyncResult.dwError + " (" + innerException.Message + ")");
                break;
            }
        }
Example #3
0
        private static void OnRequestError(WinHttpRequestState state, Interop.WinHttp.WINHTTP_ASYNC_RESULT asyncResult)
        {
            WinHttpTraceHelper.TraceAsyncError("OnRequestError", asyncResult);

            Debug.Assert(state != null, "OnRequestError: state is null");

            var innerException = WinHttpException.CreateExceptionUsingError((int)asyncResult.dwError).InitializeStackTrace();

            switch ((uint)asyncResult.dwResult.ToInt32())
            {
            case Interop.WinHttp.API_SEND_REQUEST:
                state.TcsSendRequest.TrySetException(innerException);
                break;

            case Interop.WinHttp.API_RECEIVE_RESPONSE:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_RESEND_REQUEST)
                {
                    state.RetryRequest = true;
                    state.TcsReceiveResponseHeaders.TrySetResult(false);
                }
                else if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED)
                {
                    // WinHttp will automatically drop any client SSL certificates that we
                    // have pre-set into the request handle including the NULL certificate
                    // (which means we have no certs to send). For security reasons, we don't
                    // allow the certificate to be re-applied. But we need to tell WinHttp
                    // explicitly that we don't have any certificate to send.
                    Debug.Assert(state.RequestHandle != null, "OnRequestError: state.RequestHandle is null");
                    WinHttpHandler.SetNoClientCertificate(state.RequestHandle);
                    state.RetryRequest = true;
                    state.TcsReceiveResponseHeaders.TrySetResult(false);
                }
                else if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    state.TcsReceiveResponseHeaders.TrySetCanceled(state.CancellationToken);
                }
                else
                {
                    state.TcsReceiveResponseHeaders.TrySetException(innerException);
                }
                break;

            case Interop.WinHttp.API_QUERY_DATA_AVAILABLE:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    // TODO: Issue #2165. We need to pass in the cancellation token from the
                    // user's ReadAsync() call into the TrySetCanceled().
                    Debug.WriteLine("RequestCallback: QUERY_DATA_AVAILABLE - ERROR_WINHTTP_OPERATION_CANCELLED");
                    state.TcsQueryDataAvailable.TrySetCanceled();
                }
                else
                {
                    state.TcsQueryDataAvailable.TrySetException(
                        new IOException(SR.net_http_io_read, innerException));
                }
                break;

            case Interop.WinHttp.API_READ_DATA:
                state.DisposeCtrReadFromResponseStream();

                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    // TODO: Issue #2165. We need to pass in the cancellation token from the
                    // user's ReadAsync() call into the TrySetCanceled().
                    Debug.WriteLine("RequestCallback: API_READ_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
                    state.TcsReadFromResponseStream.TrySetCanceled();
                }
                else
                {
                    state.TcsReadFromResponseStream.TrySetException(
                        new IOException(SR.net_http_io_read, innerException));
                }
                break;

            case Interop.WinHttp.API_WRITE_DATA:
                if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
                {
                    // TODO: Issue #2165. We need to pass in the cancellation token from the
                    // user's WriteAsync() call into the TrySetCanceled().
                    Debug.WriteLine("RequestCallback: API_WRITE_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
                    state.TcsInternalWriteDataToRequestStream.TrySetCanceled();
                }
                else
                {
                    state.TcsInternalWriteDataToRequestStream.TrySetException(
                        new IOException(SR.net_http_io_write, innerException));
                }
                break;

            default:
                Debug.Fail(
                    "OnRequestError: Result (" + asyncResult.dwResult + ") is not expected.",
                    "Error code: " + asyncResult.dwError + " (" + innerException.Message + ")");
                break;
            }
        }