Beispiel #1
0
        public override int EndRead(IAsyncResult asyncResult)
#endif
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }
            RequestStreamAsyncResult castedAsyncResult = asyncResult as RequestStreamAsyncResult;

            if (castedAsyncResult == null || castedAsyncResult.RequestStream != this)
            {
                throw new ArgumentException(Resources.Exception_WrongIAsyncResult, "asyncResult");
            }
            if (castedAsyncResult.EndCalled)
            {
                throw new InvalidOperationException(Resources.Exception_EndCalledMultipleTimes);
            }
            castedAsyncResult.EndCalled = true;
            // wait & then check for errors
            // Throws on failure
            int dataRead = castedAsyncResult.Task.Result;

            // TODO: Verbose log #dataRead.
            return(dataRead);
        }
 private static void IOCompleted(RequestStreamAsyncResult asyncResult, uint errorCode, uint numBytes)
 {
     try
     {
         if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
         {
             asyncResult.Fail(new IOException(string.Empty, new WebListenerException((int)errorCode)));
         }
         else
         {
             // TODO: Verbose log dump data read
             asyncResult.Complete((int)numBytes, errorCode);
         }
     }
     catch (Exception e)
     {
         asyncResult.Fail(e);
     }
 }
Beispiel #3
0
        public override unsafe Task <int> ReadAsync(byte[] buffer, int offset, int size, CancellationToken cancellationToken)
        {
            ValidateReadBuffer(buffer, offset, size);
            if (_closed)
            {
                return(Task.FromResult <int>(0));
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return(Helpers.CanceledTask <int>());
            }
            // TODO: Verbose log parameters

            RequestStreamAsyncResult asyncResult = null;

            uint dataRead = 0;

            if (_dataChunkIndex != -1)
            {
                dataRead = UnsafeNclNativeMethods.HttpApi.GetChunks(_requestContext.Request.RequestBuffer, _requestContext.Request.OriginalBlobAddress, ref _dataChunkIndex, ref _dataChunkOffset, buffer, offset, size);
                if (_dataChunkIndex != -1 && dataRead == size)
                {
                    UpdateAfterRead(UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS, dataRead);
                    // TODO: Verbose log #dataRead
                    return(Task.FromResult <int>((int)dataRead));
                }
            }

            if (_dataChunkIndex == -1 && dataRead < size)
            {
                uint statusCode = 0;
                offset += (int)dataRead;
                size   -= (int)dataRead;

                // the http.sys team recommends that we limit the size to 128kb
                if (size > MaxReadSize)
                {
                    size = MaxReadSize;
                }

                var cancellationRegistration = default(CancellationTokenRegistration);
                if (cancellationToken.CanBeCanceled)
                {
                    cancellationRegistration = cancellationToken.Register(RequestContext.AbortDelegate, _requestContext);
                }

                asyncResult = new RequestStreamAsyncResult(this, null, null, buffer, offset, dataRead, cancellationRegistration);
                uint bytesReturned;

                try
                {
                    uint flags = 0;

                    statusCode =
                        UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody(
                            _requestContext.RequestQueueHandle,
                            _requestContext.RequestId,
                            flags,
                            asyncResult.PinnedBuffer,
                            (uint)size,
                            out bytesReturned,
                            asyncResult.NativeOverlapped);
                }
                catch (Exception e)
                {
                    asyncResult.Dispose();
                    Abort();
                    LogHelper.LogException(_requestContext.Logger, "ReadAsync", e);
                    throw;
                }

                if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
                {
                    asyncResult.Dispose();
                    if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
                    {
                        uint totalRead = dataRead + bytesReturned;
                        UpdateAfterRead(statusCode, totalRead);
                        // TODO: Verbose log totalRead
                        return(Task.FromResult <int>((int)totalRead));
                    }
                    else
                    {
                        Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode));
                        LogHelper.LogException(_requestContext.Logger, "ReadAsync", exception);
                        Abort();
                        throw exception;
                    }
                }
                else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
                         WebListener.SkipIOCPCallbackOnSuccess)
                {
                    // IO operation completed synchronously - callback won't be called to signal completion.
                    asyncResult.Dispose();
                    uint totalRead = dataRead + bytesReturned;
                    UpdateAfterRead(statusCode, totalRead);
                    // TODO: Verbose log
                    return(Task.FromResult <int>((int)totalRead));
                }
            }
            return(asyncResult.Task);
        }
Beispiel #4
0
        public override unsafe IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
#endif
        {
            ValidateReadBuffer(buffer, offset, size);
            if (_closed)
            {
                RequestStreamAsyncResult result = new RequestStreamAsyncResult(this, state, callback);
                result.Complete(0);
                return(result);
            }
            // TODO: Verbose log parameters

            RequestStreamAsyncResult asyncResult = null;

            uint dataRead = 0;

            if (_dataChunkIndex != -1)
            {
                dataRead = UnsafeNclNativeMethods.HttpApi.GetChunks(_requestContext.Request.RequestBuffer, _requestContext.Request.OriginalBlobAddress, ref _dataChunkIndex, ref _dataChunkOffset, buffer, offset, size);
                if (_dataChunkIndex != -1 && dataRead == size)
                {
                    asyncResult = new RequestStreamAsyncResult(this, state, callback, buffer, offset, 0);
                    asyncResult.Complete((int)dataRead);
                }
            }

            if (_dataChunkIndex == -1 && dataRead < size)
            {
                uint statusCode = 0;
                offset += (int)dataRead;
                size   -= (int)dataRead;

                // the http.sys team recommends that we limit the size to 128kb
                if (size > MaxReadSize)
                {
                    size = MaxReadSize;
                }

                asyncResult = new RequestStreamAsyncResult(this, state, callback, buffer, offset, dataRead);
                uint bytesReturned;

                try
                {
                    uint flags = 0;

                    statusCode =
                        UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody(
                            _requestContext.RequestQueueHandle,
                            _requestContext.RequestId,
                            flags,
                            asyncResult.PinnedBuffer,
                            (uint)size,
                            out bytesReturned,
                            asyncResult.NativeOverlapped);
                }
                catch (Exception e)
                {
                    LogHelper.LogException(_requestContext.Logger, "BeginRead", e);
                    asyncResult.Dispose();
                    throw;
                }

                if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
                {
                    asyncResult.Dispose();
                    if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
                    {
                        asyncResult = new RequestStreamAsyncResult(this, state, callback, dataRead);
                        asyncResult.Complete((int)bytesReturned);
                    }
                    else
                    {
                        Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode));
                        LogHelper.LogException(_requestContext.Logger, "BeginRead", exception);
                        Abort();
                        throw exception;
                    }
                }
                else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
                         WebListener.SkipIOCPCallbackOnSuccess)
                {
                    // IO operation completed synchronously - callback won't be called to signal completion.
                    asyncResult.IOCompleted(statusCode, bytesReturned);
                }
            }
            return(asyncResult);
        }