CreateExceptionUsingLastError() public static method

public static CreateExceptionUsingLastError ( ) : WinHttpException
return WinHttpException
Example #1
0
        private async Task <int> ReadAsyncCore(byte[] buffer, int offset, int count, CancellationToken token)
        {
            if (count == 0)
            {
                return(0);
            }

            _state.PinReceiveBuffer(buffer);
            var ctr = token.Register(s => ((WinHttpResponseStream)s).CancelPendingResponseStreamReadOperation(), this);

            _state.AsyncReadInProgress = true;
            try
            {
                lock (_state.Lock)
                {
                    Debug.Assert(!_requestHandle.IsInvalid);
                    if (!Interop.WinHttp.WinHttpQueryDataAvailable(_requestHandle, IntPtr.Zero))
                    {
                        throw new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpQueryDataAvailable)));
                    }
                }

                int bytesAvailable = await _state.LifecycleAwaitable;

                lock (_state.Lock)
                {
                    Debug.Assert(!_requestHandle.IsInvalid);
                    if (!Interop.WinHttp.WinHttpReadData(
                            _requestHandle,
                            Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset),
                            (uint)Math.Min(bytesAvailable, count),
                            IntPtr.Zero))
                    {
                        throw new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpReadData)));
                    }
                }

                return(await _state.LifecycleAwaitable);
            }
            finally
            {
                _state.AsyncReadInProgress = false;
                ctr.Dispose();
            }
        }
Example #2
0
        private Task <bool> InternalWriteEndDataAsync(CancellationToken token)
        {
            _state.TcsInternalWriteDataToRequestStream =
                new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            lock (_state.Lock)
            {
                if (!Interop.WinHttp.WinHttpWriteData(
                        _requestHandle,
                        IntPtr.Zero,
                        0,
                        IntPtr.Zero))
                {
                    _state.TcsInternalWriteDataToRequestStream.TrySetException(
                        new IOException(SR.net_http_io_write, WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpWriteData))));
                }
            }

            return(_state.TcsInternalWriteDataToRequestStream.Task);
        }
Example #3
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset");
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            if ((long)offset + (long)count > (long)buffer.Length)
            {
                throw new ArgumentException("buffer");
            }

            CheckDisposed();

            uint     bytesRead    = 0;
            GCHandle pinnedHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            bool     result       = Interop.WinHttp.WinHttpReadData(
                _requestHandle,
                Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset),
                (uint)count,
                out bytesRead);

            pinnedHandle.Free();
            if (!result)
            {
                throw new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError());
            }

            return((int)bytesRead);
        }
Example #4
0
        private Task <bool> InternalWriteDataAsync(byte[] buffer, int offset, int count, CancellationToken token)
        {
            Debug.Assert(count >= 0);

            if (count == 0)
            {
                return(Task.FromResult <bool>(true));
            }

            // TODO (Issue 2505): replace with PinnableBufferCache.
            if (!_cachedSendPinnedBuffer.IsAllocated || _cachedSendPinnedBuffer.Target != buffer)
            {
                if (_cachedSendPinnedBuffer.IsAllocated)
                {
                    _cachedSendPinnedBuffer.Free();
                }

                _cachedSendPinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            }

            _state.TcsInternalWriteDataToRequestStream =
                new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            lock (_state.Lock)
            {
                if (!Interop.WinHttp.WinHttpWriteData(
                        _state.RequestHandle,
                        Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset),
                        (uint)count,
                        IntPtr.Zero))
                {
                    _state.TcsInternalWriteDataToRequestStream.TrySetException(
                        new IOException(SR.net_http_io_write, WinHttpException.CreateExceptionUsingLastError()));
                }
            }

            // TODO: Issue #2165. Register callback on cancellation token to cancel WinHTTP operation.

            return(_state.TcsInternalWriteDataToRequestStream.Task);
        }
        public override Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            if (count > buffer.Length - offset)
            {
                throw new ArgumentException(nameof(buffer));
            }

            if (token.IsCancellationRequested)
            {
                return(Task.FromCanceled <int>(token));
            }

            CheckDisposed();

            if (_state.TcsReadFromResponseStream != null && !_state.TcsReadFromResponseStream.Task.IsCompleted)
            {
                throw new InvalidOperationException(SR.net_http_no_concurrent_io_allowed);
            }

            // TODO (Issue 2505): replace with PinnableBufferCache.
            if (!_cachedReceivePinnedBuffer.IsAllocated || _cachedReceivePinnedBuffer.Target != buffer)
            {
                if (_cachedReceivePinnedBuffer.IsAllocated)
                {
                    _cachedReceivePinnedBuffer.Free();
                }

                _cachedReceivePinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            }

            _state.TcsReadFromResponseStream =
                new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously);

            _state.TcsQueryDataAvailable =
                new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously);
            _state.TcsQueryDataAvailable.Task.ContinueWith((previousTask) =>
            {
                if (previousTask.IsFaulted)
                {
                    _state.TcsReadFromResponseStream.TrySetException(previousTask.Exception.InnerException);
                }
                else if (previousTask.IsCanceled || token.IsCancellationRequested)
                {
                    _state.TcsReadFromResponseStream.TrySetCanceled(token);
                }
                else
                {
                    int bytesToRead;
                    int bytesAvailable = previousTask.Result;
                    if (bytesAvailable > count)
                    {
                        bytesToRead = count;
                    }
                    else
                    {
                        bytesToRead = bytesAvailable;
                    }

                    lock (_state.Lock)
                    {
                        if (!Interop.WinHttp.WinHttpReadData(
                                _state.RequestHandle,
                                Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset),
                                (uint)bytesToRead,
                                IntPtr.Zero))
                        {
                            _state.TcsReadFromResponseStream.TrySetException(
                                new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError()));
                        }
                    }
                }
            },
                                                           CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);

            // TODO: Issue #2165. Register callback on cancellation token to cancel WinHTTP operation.

            lock (_state.Lock)
            {
                if (!Interop.WinHttp.WinHttpQueryDataAvailable(_state.RequestHandle, IntPtr.Zero))
                {
                    _state.TcsReadFromResponseStream.TrySetException(
                        new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError()));
                }
            }

            return(_state.TcsReadFromResponseStream.Task);
        }
Example #6
0
        public override Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset");
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            if (count > buffer.Length - offset)
            {
                throw new ArgumentException("buffer");
            }

            if (token.IsCancellationRequested)
            {
                return(Task.FromCanceled <int>(token));
            }

            CheckDisposed();

            if (_state.TcsReadFromResponseStream != null && !_state.TcsReadFromResponseStream.Task.IsCompleted)
            {
                throw new InvalidOperationException(SR.net_http_no_concurrent_io_allowed);
            }

            // TODO (Issue 2505): replace with PinnableBufferCache.
            if (!_cachedReceivePinnedBuffer.IsAllocated || _cachedReceivePinnedBuffer.Target != buffer)
            {
                if (_cachedReceivePinnedBuffer.IsAllocated)
                {
                    _cachedReceivePinnedBuffer.Free();
                }

                _cachedReceivePinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            }

            _state.TcsReadFromResponseStream = new TaskCompletionSource <int>();

            lock (_state.Lock)
            {
                if (!Interop.WinHttp.WinHttpReadData(
                        _state.RequestHandle,
                        Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset),
                        (uint)count,
                        IntPtr.Zero))
                {
                    _state.TcsReadFromResponseStream.TrySetException(
                        new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError()));
                }
            }

            // TODO: Issue #2165. Register callback on cancellation token to cancel WinHTTP operation.

            return(_state.TcsReadFromResponseStream.Task);
        }
        public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            if (count > buffer.Length - offset)
            {
                throw new ArgumentException(SR.net_http_buffer_insufficient_length, nameof(buffer));
            }

            if (token.IsCancellationRequested)
            {
                return Task.FromCanceled<int>(token);
            }

            CheckDisposed();

            if (_state.TcsReadFromResponseStream != null && !_state.TcsReadFromResponseStream.Task.IsCompleted)
            {
                throw new InvalidOperationException(SR.net_http_no_concurrent_io_allowed);
            }

            _state.PinReceiveBuffer(buffer);

            _state.TcsReadFromResponseStream =
                new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);

            _state.TcsQueryDataAvailable =
                new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
            _state.TcsQueryDataAvailable.Task.ContinueWith((previousTask) => 
                {
                    if (previousTask.IsFaulted)
                    {
                        _state.DisposeCtrReadFromResponseStream();
                        _state.TcsReadFromResponseStream.TrySetException(previousTask.Exception.InnerException);
                    }
                    else if (previousTask.IsCanceled || token.IsCancellationRequested)
                    {
                        _state.DisposeCtrReadFromResponseStream();
                        _state.TcsReadFromResponseStream.TrySetCanceled(token);
                    }
                    else
                    {
                        int bytesToRead;
                        int bytesAvailable = previousTask.Result;
                        if (bytesAvailable > count)
                        {
                            bytesToRead = count;
                        }
                        else
                        {
                            bytesToRead = bytesAvailable;
                        }
                        
                        lock (_state.Lock)
                        {
                            Debug.Assert(!_requestHandle.IsInvalid);
                            if (!Interop.WinHttp.WinHttpReadData(
                                _requestHandle,
                                Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset),
                                (uint)bytesToRead,
                                IntPtr.Zero))
                            {
                                _state.DisposeCtrReadFromResponseStream();
                                _state.TcsReadFromResponseStream.TrySetException(
                                    new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError().InitializeStackTrace()));
                            }
                        }
                    }
                }, 
                CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);

            // Register callback on cancellation token to cancel any pending WinHTTP operation.
            if (token.CanBeCanceled)
            {
                WinHttpTraceHelper.Trace("WinHttpResponseStream.ReadAsync: registering for cancellation token request");
                _state.CtrReadFromResponseStream =
                    token.Register(s => ((WinHttpResponseStream)s).CancelPendingResponseStreamReadOperation(), this);
            }
            else
            {
                WinHttpTraceHelper.Trace("WinHttpResponseStream.ReadAsync: received no cancellation token");
            }

            lock (_state.Lock)
            {
                Debug.Assert(!_requestHandle.IsInvalid);
                if (!Interop.WinHttp.WinHttpQueryDataAvailable(_requestHandle, IntPtr.Zero))
                {
                    _state.DisposeCtrReadFromResponseStream();
                    _state.TcsReadFromResponseStream.TrySetException(
                        new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError().InitializeStackTrace()));
                }
            }

            return _state.TcsReadFromResponseStream.Task;
        }
        private async Task CopyToAsyncCore(Stream destination, byte[] buffer, CancellationToken cancellationToken)
        {
            _state.PinReceiveBuffer(buffer);
            CancellationTokenRegistration ctr = cancellationToken.Register(s => ((WinHttpResponseStream)s).CancelPendingResponseStreamReadOperation(), this);

            _state.AsyncReadInProgress = true;
            try
            {
                // Loop until there's no more data to be read
                while (true)
                {
                    // Query for data available
                    lock (_state.Lock)
                    {
                        if (!Interop.WinHttp.WinHttpQueryDataAvailable(_requestHandle, IntPtr.Zero))
                        {
                            throw new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpQueryDataAvailable)));
                        }
                    }
                    int bytesAvailable = await _state.LifecycleAwaitable;
                    if (bytesAvailable == 0)
                    {
                        ReadResponseTrailers();
                        break;
                    }
                    Debug.Assert(bytesAvailable > 0);

                    // Read the available data
                    cancellationToken.ThrowIfCancellationRequested();
                    lock (_state.Lock)
                    {
                        if (!Interop.WinHttp.WinHttpReadData(_requestHandle, Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0), (uint)Math.Min(bytesAvailable, buffer.Length), IntPtr.Zero))
                        {
                            throw new IOException(SR.net_http_io_read, WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpReadData)));
                        }
                    }
                    int bytesRead = await _state.LifecycleAwaitable;
                    if (bytesRead == 0)
                    {
                        ReadResponseTrailers();
                        break;
                    }
                    Debug.Assert(bytesRead > 0);

                    // Write that data out to the output stream
#if NETSTANDARD2_1
                    await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
#else
                    await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
#endif
                }
            }
            finally
            {
                _state.AsyncReadInProgress = false;
                ctr.Dispose();
                ArrayPool <byte> .Shared.Return(buffer);
            }

            // Leaving buffer pinned as it is in ReadAsync.  It'll get unpinned when another read
            // request is made with a different buffer or when the state is cleared.
        }