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);
     }
 }
Esempio n. 2
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);
        }