Exemple #1
0
            private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped)
            {
                HttpRequestStream.HttpRequestStreamAsyncResult asyncResult = Overlapped.Unpack(nativeOverlapped).AsyncResult as HttpRequestStream.HttpRequestStreamAsyncResult;
                object result = null;

                try
                {
                    if ((errorCode != 0) && (errorCode != 0x26))
                    {
                        asyncResult.ErrorCode = (int)errorCode;
                        result = new HttpListenerException((int)errorCode);
                    }
                    else
                    {
                        result = numBytes;
                        if (Logging.On)
                        {
                            Logging.Dump(Logging.HttpListener, asyncResult, "Callback", (IntPtr)asyncResult.m_pPinnedBuffer, (int)numBytes);
                        }
                    }
                }
                catch (Exception exception)
                {
                    result = exception;
                }
                asyncResult.InvokeCallback(result);
            }
Exemple #2
0
            private static void IOCompleted(HttpRequestStreamAsyncResult asyncResult, uint errorCode, uint numBytes)
            {
                GlobalLog.Print("HttpRequestStreamAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::Callback() errorCode:0x" + errorCode.ToString("x8") + " numBytes:" + numBytes);
                object result = null;

                try {
                    if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
                    {
                        asyncResult.ErrorCode = (int)errorCode;
                        result = new HttpListenerException((int)errorCode);
                    }
                    else
                    {
                        result = numBytes;
                        if (Logging.On)
                        {
                            Logging.Dump(Logging.HttpListener, asyncResult, "Callback", (IntPtr)asyncResult.m_pPinnedBuffer, (int)numBytes);
                        }
                    }
                    GlobalLog.Print("HttpRequestStreamAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::Callback() calling Complete()");
                }
                catch (Exception e) {
                    result = e;
                }
                asyncResult.InvokeCallback(result);
            }
Exemple #3
0
        private static void IOCompleted(HttpResponseStreamAsyncResult asyncResult, uint errorCode, uint numBytes)
        {
            GlobalLog.Print("HttpResponseStreamAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::Callback() errorCode:0x" + errorCode.ToString("x8") + " numBytes:" + numBytes);
            object result = null;

            try {
                if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
                {
                    asyncResult.ErrorCode = (int)errorCode;
                    result = new HttpListenerException((int)errorCode);
                }
                else
                {
                    // if we sent headers and body together, numBytes will be the total, but we need to only account for the data
                    // result = numBytes;
                    if (asyncResult.m_DataChunks == null)
                    {
                        result = (uint)0;
                        if (Logging.On)
                        {
                            Logging.Dump(Logging.HttpListener, asyncResult, "Callback", IntPtr.Zero, 0);
                        }
                    }
                    else
                    {
                        result = asyncResult.m_DataChunks.Length == 1 ? asyncResult.m_DataChunks[0].BufferLength : 0;
                        if (Logging.On)
                        {
                            for (int i = 0; i < asyncResult.m_DataChunks.Length; i++)
                            {
                                Logging.Dump(Logging.HttpListener, asyncResult, "Callback", (IntPtr)asyncResult.m_DataChunks[0].pBuffer, (int)asyncResult.m_DataChunks[0].BufferLength);
                            }
                        }
                    }
                }
                GlobalLog.Print("HttpResponseStreamAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::Callback() calling Complete()");
            }
            catch (Exception e) {
                result = e;
            }
            asyncResult.InvokeCallback(result);
        }
        private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped)
        {
            HttpResponseStreamAsyncResult asyncResult = Overlapped.Unpack(nativeOverlapped).AsyncResult as HttpResponseStreamAsyncResult;
            object result = null;

            try
            {
                if ((errorCode != 0) && (errorCode != 0x26))
                {
                    asyncResult.ErrorCode = (int)errorCode;
                    result = new HttpListenerException((int)errorCode);
                }
                else if (asyncResult.m_DataChunks == null)
                {
                    result = 0;
                    if (Logging.On)
                    {
                        Logging.Dump(Logging.HttpListener, asyncResult, "Callback", IntPtr.Zero, 0);
                    }
                }
                else
                {
                    result = (asyncResult.m_DataChunks.Length == 1) ? ((object)asyncResult.m_DataChunks[0].BufferLength) : ((object)0);
                    if (Logging.On)
                    {
                        for (int i = 0; i < asyncResult.m_DataChunks.Length; i++)
                        {
                            Logging.Dump(Logging.HttpListener, asyncResult, "Callback", (IntPtr)asyncResult.m_DataChunks[0].pBuffer, (int)asyncResult.m_DataChunks[0].BufferLength);
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                result = exception;
            }
            asyncResult.InvokeCallback(result);
        }
Exemple #5
0
        public override void Write(byte[] buffer, int offset, int size)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.HttpListener, this, "Write", "");
            }
            GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Write() buffer.Length:" + buffer.Length + " size:" + size + " offset:" + offset);
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0 || offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (size < 0 || size > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException("size");
            }
            UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags = ComputeLeftToWrite();
            if (m_Closed || (size == 0 && m_LeftToWrite != 0))
            {
                if (Logging.On)
                {
                    Logging.Exit(Logging.HttpListener, this, "Write", "");
                }
                return;
            }
            if (m_LeftToWrite >= 0 && size > m_LeftToWrite)
            {
                throw new ProtocolViolationException(SR.GetString(SR.net_entitytoobig));
            }

            uint          statusCode;
            uint          dataToWrite     = (uint)size;
            SafeLocalFree bufferAsIntPtr  = null;
            IntPtr        pBufferAsIntPtr = IntPtr.Zero;
            bool          sentHeaders     = m_HttpContext.Response.SentHeaders;

            try {
                if (size == 0)
                {
                    statusCode = m_HttpContext.Response.SendHeaders(null, null, flags, false);
                }
                else
                {
                    fixed(byte *pDataBuffer = buffer)
                    {
                        byte *pBuffer = pDataBuffer;

                        if (m_HttpContext.Response.BoundaryType == BoundaryType.Chunked)
                        {
                            //


                            string chunkHeader = size.ToString("x", CultureInfo.InvariantCulture);
                            dataToWrite     = dataToWrite + (uint)(chunkHeader.Length + 4);
                            bufferAsIntPtr  = SafeLocalFree.LocalAlloc((int)dataToWrite);
                            pBufferAsIntPtr = bufferAsIntPtr.DangerousGetHandle();
                            for (int i = 0; i < chunkHeader.Length; i++)
                            {
                                Marshal.WriteByte(pBufferAsIntPtr, i, (byte)chunkHeader[i]);
                            }
                            Marshal.WriteInt16(pBufferAsIntPtr, chunkHeader.Length, 0x0A0D);
                            Marshal.Copy(buffer, offset, IntPtrHelper.Add(pBufferAsIntPtr, chunkHeader.Length + 2), size);
                            Marshal.WriteInt16(pBufferAsIntPtr, (int)(dataToWrite - 2), 0x0A0D);
                            pBuffer = (byte *)pBufferAsIntPtr;
                            offset  = 0;
                        }
                        UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK dataChunk = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK();
                        dataChunk.DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                        dataChunk.pBuffer       = (byte *)(pBuffer + offset);
                        dataChunk.BufferLength  = dataToWrite;

                        flags |= m_LeftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
                        if (!sentHeaders)
                        {
                            statusCode = m_HttpContext.Response.SendHeaders(&dataChunk, null, flags, false);
                        }
                        else
                        {
                            GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Write() calling UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody");

                            statusCode =
                                UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody(
                                    m_HttpContext.RequestQueueHandle,
                                    m_HttpContext.RequestId,
                                    (uint)flags,
                                    1,
                                    &dataChunk,
                                    null,
                                    SafeLocalFree.Zero,
                                    0,
                                    null,
                                    null);

                            GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Write() call to UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody returned:" + statusCode);
                            if (m_HttpContext.Listener.IgnoreWriteExceptions)
                            {
                                GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Write() suppressing error");
                                statusCode = UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS;
                            }
                        }
                    }
                }
            }
            finally {
                if (bufferAsIntPtr != null)
                {
                    // free unmanaged buffer
                    bufferAsIntPtr.Close();
                }
            }

            if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
            {
                Exception exception = new HttpListenerException((int)statusCode);
                if (Logging.On)
                {
                    Logging.Exception(Logging.HttpListener, this, "Write", exception);
                }
                m_Closed = true;
                m_HttpContext.Abort();
                throw exception;
            }
            UpdateAfterWrite(dataToWrite);
            if (Logging.On)
            {
                Logging.Dump(Logging.HttpListener, this, "Write", buffer, offset, (int)dataToWrite);
            }
            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "Write", "");
            }
        }
Exemple #6
0
        public override unsafe int Read([In, Out] byte[] buffer, int offset, int size)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.HttpListener, this, "Read", "");
            }
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if ((offset < 0) || (offset > buffer.Length))
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if ((size < 0) || (size > (buffer.Length - offset)))
            {
                throw new ArgumentOutOfRangeException("size");
            }
            if ((size == 0) || this.m_Closed)
            {
                if (Logging.On)
                {
                    Logging.Exit(Logging.HttpListener, this, "Read", "dataRead:0");
                }
                return(0);
            }
            uint dataRead = 0;

            if (this.m_DataChunkIndex != -1)
            {
                dataRead = UnsafeNclNativeMethods.HttpApi.GetChunks(this.m_HttpContext.Request.RequestBuffer, this.m_HttpContext.Request.OriginalBlobAddress, ref this.m_DataChunkIndex, ref this.m_DataChunkOffset, buffer, offset, size);
            }
            if ((this.m_DataChunkIndex == -1) && (dataRead < size))
            {
                uint statusCode     = 0;
                uint pBytesReturned = 0;
                offset += (int)dataRead;
                size   -= (int)dataRead;
                if (size > 0x20000)
                {
                    size = 0x20000;
                }

                fixed(byte *numRef = buffer)
                {
                    statusCode = UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody(this.m_HttpContext.RequestQueueHandle, this.m_HttpContext.RequestId, 1, (void *)(numRef + offset), (uint)size, &pBytesReturned, null);
                    dataRead  += pBytesReturned;
                }

                switch (statusCode)
                {
                case 0:
                case 0x26:
                    this.UpdateAfterRead(statusCode, dataRead);
                    break;

                default:
                {
                    Exception e = new HttpListenerException((int)statusCode);
                    if (Logging.On)
                    {
                        Logging.Exception(Logging.HttpListener, this, "Read", e);
                    }
                    throw e;
                }
                }
            }
            if (Logging.On)
            {
                Logging.Dump(Logging.HttpListener, this, "Read", buffer, offset, (int)dataRead);
            }
            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "Read", "dataRead:" + dataRead);
            }
            return((int)dataRead);
        }
Exemple #7
0
        public override unsafe void Write(byte[] buffer, int offset, int size)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.HttpListener, this, "Write", "");
            }
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if ((offset < 0) || (offset > buffer.Length))
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if ((size < 0) || (size > (buffer.Length - offset)))
            {
                throw new ArgumentOutOfRangeException("size");
            }
            UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags = this.ComputeLeftToWrite();
            if (this.m_Closed || ((size == 0) && (this.m_LeftToWrite != 0L)))
            {
                if (Logging.On)
                {
                    Logging.Exit(Logging.HttpListener, this, "Write", "");
                }
            }
            else
            {
                uint num;
                if ((this.m_LeftToWrite >= 0L) && (size > this.m_LeftToWrite))
                {
                    throw new ProtocolViolationException(SR.GetString("net_entitytoobig"));
                }
                uint          dataWritten = (uint)size;
                SafeLocalFree free        = null;
                IntPtr        zero        = IntPtr.Zero;
                bool          sentHeaders = this.m_HttpContext.Response.SentHeaders;
                try
                {
                    if (size == 0)
                    {
                        num = this.m_HttpContext.Response.SendHeaders(null, null, flags);
                    }
                    else
                    {
                        try
                        {
                            byte[] buffer2;
                            if (((buffer2 = buffer) == null) || (buffer2.Length == 0))
                            {
                                numRef = null;
                                goto Label_0109;
                            }
                            fixed(byte *numRef = buffer2)
                            {
                                byte *numPtr;

Label_0109:
                                numPtr = numRef;
                                if (this.m_HttpContext.Response.BoundaryType == BoundaryType.Chunked)
                                {
                                    string str = size.ToString("x", CultureInfo.InvariantCulture);
                                    dataWritten += (uint)(str.Length + 4);
                                    free         = SafeLocalFree.LocalAlloc((int)dataWritten);
                                    zero         = free.DangerousGetHandle();
                                    for (int i = 0; i < str.Length; i++)
                                    {
                                        Marshal.WriteByte(zero, i, (byte)str[i]);
                                    }
                                    Marshal.WriteInt16(zero, str.Length, (short)0xa0d);
                                    Marshal.Copy(buffer, offset, IntPtrHelper.Add(zero, str.Length + 2), size);
                                    Marshal.WriteInt16(zero, ((int)dataWritten) - 2, (short)0xa0d);
                                    numPtr = (byte *)zero;
                                    offset = 0;
                                }
                                UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK pDataChunk = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK {
                                    DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory,
                                    pBuffer       = numPtr + offset,
                                    BufferLength  = dataWritten
                                };
                                flags |= (this.m_LeftToWrite == size) ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
                                if (!sentHeaders)
                                {
                                    num = this.m_HttpContext.Response.SendHeaders(&pDataChunk, null, flags);
                                }
                                else
                                {
                                    num = UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody(this.m_HttpContext.RequestQueueHandle, this.m_HttpContext.RequestId, (uint)flags, 1, &pDataChunk, null, SafeLocalFree.Zero, 0, null, null);
                                    if (this.m_HttpContext.Listener.IgnoreWriteExceptions)
                                    {
                                        num = 0;
                                    }
                                }
                            }
                        }
                        finally
                        {
                            numRef = null;
                        }
                    }
                }
                finally
                {
                    if (free != null)
                    {
                        free.Close();
                    }
                }
                switch (num)
                {
                case 0:
                case 0x26:
                    this.UpdateAfterWrite(dataWritten);
                    if (Logging.On)
                    {
                        Logging.Dump(Logging.HttpListener, this, "Write", buffer, offset, (int)dataWritten);
                    }
                    if (Logging.On)
                    {
                        Logging.Exit(Logging.HttpListener, this, "Write", "");
                    }
                    return;
                }
                Exception e = new HttpListenerException((int)num);
                if (Logging.On)
                {
                    Logging.Exception(Logging.HttpListener, this, "Write", e);
                }
                this.m_HttpContext.Abort();
                throw e;
            }
        }
Exemple #8
0
        public override int Read([In, Out] byte[] buffer, int offset, int size)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.HttpListener, this, "Read", "");
            }
            GlobalLog.Print("HttpRequestStream#" + ValidationHelper.HashString(this) + "::Read() size:" + size + " offset:" + offset);
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0 || offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (size < 0 || size > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException("size");
            }
            if (size == 0 || m_Closed)
            {
                if (Logging.On)
                {
                    Logging.Exit(Logging.HttpListener, this, "Read", "dataRead:0");
                }
                return(0);
            }

            uint dataRead = 0;

            if (m_DataChunkIndex != -1)
            {
                dataRead = UnsafeNclNativeMethods.HttpApi.GetChunks(m_HttpContext.Request.RequestBuffer, m_HttpContext.Request.OriginalBlobAddress, ref m_DataChunkIndex, ref m_DataChunkOffset, buffer, offset, size);
            }

            if (m_DataChunkIndex == -1 && dataRead < size)
            {
                GlobalLog.Print("HttpRequestStream#" + ValidationHelper.HashString(this) + "::Read() size:" + size + " offset:" + offset);
                uint statusCode    = 0;
                uint extraDataRead = 0;
                offset += (int)dataRead;
                size   -= (int)dataRead;

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

                fixed(byte *pBuffer = buffer)
                {
                    // issue unmanaged blocking call
                    GlobalLog.Print("HttpRequestStream#" + ValidationHelper.HashString(this) + "::Read() calling UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody");

                    uint flags = 0;

                    if (!m_InOpaqueMode)
                    {
                        flags = (uint)UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY;
                    }

                    statusCode =
                        UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody(
                            m_HttpContext.RequestQueueHandle,
                            m_HttpContext.RequestId,
                            flags,
                            (void *)(pBuffer + offset),
                            (uint)size,
                            out extraDataRead,
                            null);

                    dataRead += extraDataRead;
                    GlobalLog.Print("HttpRequestStream#" + ValidationHelper.HashString(this) + "::Read() call to UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody returned:" + statusCode + " dataRead:" + dataRead);
                }

                if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
                {
                    Exception exception = new HttpListenerException((int)statusCode);
                    if (Logging.On)
                    {
                        Logging.Exception(Logging.HttpListener, this, "Read", exception);
                    }
                    throw exception;
                }
                UpdateAfterRead(statusCode, dataRead);
            }
            if (Logging.On)
            {
                Logging.Dump(Logging.HttpListener, this, "Read", buffer, offset, (int)dataRead);
            }
            GlobalLog.Print("HttpRequestStream#" + ValidationHelper.HashString(this) + "::Read() returning dataRead:" + dataRead);
            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "Read", "dataRead:" + dataRead);
            }
            return((int)dataRead);
        }