Exit() private method

private Exit ( TraceSource traceSource, object obj, string method, object retObject ) : void
traceSource TraceSource
obj object
method string
retObject object
return void
Example #1
0
 /// <summary>
 /// <para>Closes the underlying FTP response stream, but does not close control connection</para>
 /// </summary>
 public override void Close()
 {
     if (Logging.On)
     {
         Logging.Enter(Logging.Web, this, "Close", "");
     }
     if (HttpProxyMode)
     {
         m_HttpWebResponse.Close();
     }
     else
     {
         Stream stream = m_ResponseStream;
         if (stream != null)
         {
             stream.Close();
         }
     }
     if (Logging.On)
     {
         Logging.Exit(Logging.Web, this, "Close", "");
     }
 }
Example #2
0
        public static IPHostEntry GetHostEntry(IPAddress address)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.Sockets, "DNS", "GetHostEntry", "");
            }
            s_DnsPermission.Demand();
            if (address == null)
            {
                throw new ArgumentNullException("address");
            }
            if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
            {
                throw new ArgumentException(SR.GetString("net_invalid_ip_addr"), "address");
            }
            IPHostEntry hostByAddress = InternalGetHostByAddress(address, true);

            if (Logging.On)
            {
                Logging.Exit(Logging.Sockets, "DNS", "GetHostEntry", hostByAddress);
            }
            return(hostByAddress);
        }
Example #3
0
        public static IPHostEntry GetHostByAddress(IPAddress address)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.Sockets, "DNS", "GetHostByAddress", "");
            }
            //
            // demand Unrestricted DnsPermission for this call
            //
            s_DnsPermission.Demand();

            if (address == null)
            {
                throw new ArgumentNullException("address");
            }

            IPHostEntry ipHostEntry = InternalGetHostByAddress(address, false, true);

            if (Logging.On)
            {
                Logging.Exit(Logging.Sockets, "DNS", "GetHostByAddress", ipHostEntry);
            }
            return(ipHostEntry);
        } // GetHostByAddress
Example #4
0
 internal void Abort()
 {
     if (Logging.On)
     {
         Logging.Enter(Logging.HttpListener, this, "Abort", "");
     }
     CancelRequest(this.RequestQueueHandle, this.m_Request.RequestId);
     try
     {
         this.m_Request.Close();
     }
     finally
     {
         IDisposable disposable = (this.m_User == null) ? null : (this.m_User.Identity as IDisposable);
         if (disposable != null)
         {
             disposable.Dispose();
         }
     }
     if (Logging.On)
     {
         Logging.Exit(Logging.HttpListener, this, "Abort", "");
     }
 }
Example #5
0
        public static IPHostEntry EndResolve(IAsyncResult asyncResult)
        {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndResolve", asyncResult);

            IPHostEntry ipHostEntry;

            try
            {
                ipHostEntry = HostResolutionEndHelper(asyncResult);
            }
            catch (SocketException ex)
            {
                IPAddress address = ((ResolveAsyncResult)asyncResult).address;
                if (address == null)
                    throw; // BeginResolve was called with a HostName, not an IPAddress

                if (Logging.On) Logging.PrintWarning(Logging.Sockets, "DNS", "DNS.EndResolve", ex.Message);

                ipHostEntry = GetUnresolveAnswer(address);
            }

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndResolve", ipHostEntry);
            return ipHostEntry;
        } // EndResolve()
Example #6
0
 internal void ForceCleanup()
 {
     if (Logging.On)
     {
         Logging.Enter(Logging.Web, "ConnectionPool::ForceCleanup");
     }
     while (this.Count > 0)
     {
         if (!this.Semaphore.WaitOne(0, false))
         {
             break;
         }
         PooledStream pooledStream = (PooledStream)this.m_StackNew.Pop();
         if (pooledStream == null)
         {
             pooledStream = (PooledStream)this.m_StackOld.Pop();
         }
         this.Destroy(pooledStream);
     }
     if (Logging.On)
     {
         Logging.Exit(Logging.Web, "ConnectionPool::ForceCleanup");
     }
 }
        /*++
         *
         *  ResponseStream - Return the response stream.
         *
         *  This property returns the response stream for this response. The
         *  response stream will do de-chunking, etc. as needed.
         *
         *  Input: Nothing. Property is readonly.
         *
         *  Returns: Response stream for response.
         *
         * --*/


        /// <devdoc>
        ///    <para>Gets the stream used for reading the body of the response from the
        ///       server.</para>
        /// </devdoc>
        public override Stream GetResponseStream()
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.Web, this, "GetResponseStream", "");
            }
            CheckDisposed();
            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web, "ContentLength=" + m_ContentLength);
            }

            Stream result;

            if (m_IsWebSocketResponse && m_StatusCode == HttpStatusCode.SwitchingProtocols) // HTTP 101
            {
                if (this.m_WebSocketConnectionStream == null)
                {
                    ConnectStream connectStream = m_ConnectStream as ConnectStream;
                    GlobalLog.Assert(connectStream != null, "HttpWebResponse.m_ConnectStream should always be a ConnectStream in WebSocket cases.");
                    GlobalLog.Assert(connectStream.Connection != null, "HttpWebResponse.m_ConnectStream.Connection should never be null in WebSocket cases.");
                    this.m_WebSocketConnectionStream = new WebSocketConnectionStream(connectStream, this.ConnectionGroupName);
                }
                result = this.m_WebSocketConnectionStream;
            }
            else
            {
                result = m_ConnectStream;
            }

            if (Logging.On)
            {
                Logging.Exit(Logging.Web, this, "GetResponseStream", result);
            }
            return(result);
        }
Example #8
0
        /*++
         *
         *  Create - Create a WebRequest.
         *
         *  This is the main creation routine. We take a Uri object, look
         *  up the Uri in the prefix match table, and invoke the appropriate
         *  handler to create the object. We also have a parameter that
         *  tells us whether or not to use the whole Uri or just the
         *  scheme portion of it.
         *
         *  Input:
         *
         *      RequestUri          - Uri object for request.
         *      UseUriBase          - True if we're only to look at the scheme
         *                              portion of the Uri.
         *
         *  Returns:
         *
         *      Newly created WebRequest.
         * --*/

        private static WebRequest Create(Uri requestUri, bool useUriBase)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.Web, "WebRequest", "Create", requestUri.ToString());
            }

            string LookupUri;
            WebRequestPrefixElement Current = null;
            bool Found = false;

            if (!useUriBase)
            {
                LookupUri = requestUri.AbsoluteUri;
            }
            else
            {
                //
                // schemes are registered as <schemeName>":", so add the separator
                // to the string returned from the Uri object
                //

                LookupUri = requestUri.Scheme + ':';
            }

            int LookupLength = LookupUri.Length;

            // Copy the prefix list so that if it is updated it will
            // not affect us on this thread.

            ArrayList prefixList = PrefixList;

            // Look for the longest matching prefix.

            // Walk down the list of prefixes. The prefixes are kept longest
            // first. When we find a prefix that is shorter or the same size
            // as this Uri, we'll do a compare to see if they match. If they
            // do we'll break out of the loop and call the creator.

            for (int i = 0; i < prefixList.Count; i++)
            {
                Current = (WebRequestPrefixElement)prefixList[i];

                //
                // See if this prefix is short enough.
                //

                if (LookupLength >= Current.Prefix.Length)
                {
                    //
                    // It is. See if these match.
                    //

                    if (String.Compare(Current.Prefix,
                                       0,
                                       LookupUri,
                                       0,
                                       Current.Prefix.Length,
                                       StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        //
                        // These match. Remember that we found it and break
                        // out.
                        //

                        Found = true;
                        break;
                    }
                }
            }

            WebRequest webRequest = null;

            if (Found)
            {
                //
                // We found a match, so just call the creator and return what it
                // does.
                //

                webRequest = Current.Creator.Create(requestUri);
                if (Logging.On)
                {
                    Logging.Exit(Logging.Web, "WebRequest", "Create", webRequest);
                }
                return(webRequest);
            }

            if (Logging.On)
            {
                Logging.Exit(Logging.Web, "WebRequest", "Create", null);
            }

            //
            // Otherwise no match, throw an exception.
            //

            throw new NotSupportedException(SR.GetString(SR.net_unknown_prefix));
        }
Example #9
0
        internal static IPHostEntry InternalGetHostByName(string hostName, bool includeIPv6) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostByName", hostName);
            IPHostEntry ipHostEntry = null;

            GlobalLog.Print("Dns.GetHostByName: " + hostName);

            if (hostName.Length > MaxHostName // If 255 chars, the last one must be a dot.
                || hostName.Length == MaxHostName && hostName[MaxHostName-1] != '.') { 
                throw new ArgumentOutOfRangeException("hostName", SR.GetString(SR.net_toolong, 
                    "hostName", MaxHostName.ToString(NumberFormatInfo.CurrentInfo)));
            }

            //
            // IPv6 Changes: IPv6 requires the use of getaddrinfo() rather
            //               than the traditional IPv4 gethostbyaddr() / gethostbyname().
            //               getaddrinfo() is also protocol independant in that it will also
            //               resolve IPv4 names / addresses. As a result, it is the preferred
            //               resolution mechanism on platforms that support it (Windows 5.1+).
            //               If getaddrinfo() is unsupported, IPv6 resolution does not work.
            //
            // Consider    : If IPv6 is disabled, we could detect IPv6 addresses
            //               and throw an unsupported platform exception.
            //
            // Note        : Whilst getaddrinfo is available on WinXP+, we only
            //               use it if IPv6 is enabled (platform is part of that
            //               decision). This is done to minimize the number of
            //               possible tests that are needed.
            //
            if ( Socket.LegacySupportsIPv6 || includeIPv6) {
                //
                // IPv6 enabled: use getaddrinfo() to obtain DNS information.
                //
                ipHostEntry = Dns.GetAddrInfo(hostName);
            }
            else {
                //
                // IPv6 disabled: use gethostbyname() to obtain DNS information.
                //
                IntPtr nativePointer =
                    UnsafeNclNativeMethods.OSSOCK.gethostbyname(
                        hostName);

                if (nativePointer == IntPtr.Zero) {
                    // This is for compatiblity with NT4/Win2k
                    // Need to do this first since if we wait the last error code might be overwritten.
                    SocketException socketException = new SocketException();

                    //This block supresses "unknown error" on NT4 when input is
                    //arbitrary IP address. It simulates same result as on Win2K.
                    // For Everett compat, we allow this to parse and return IPv6 even when it's disabled.
                    IPAddress address;
                    if (IPAddress.TryParse(hostName, out address))
                    {
                        ipHostEntry = GetUnresolveAnswer(address);
                        if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByName", ipHostEntry);
                        return ipHostEntry;
                    }

                    throw socketException;
                }
                ipHostEntry = NativeToHostEntry(nativePointer);
            }

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByName", ipHostEntry);
            return ipHostEntry;

        } // GetHostByName
Example #10
0
        protected override void Dispose(bool disposing)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.HttpListener, this, "Close", "");
            }

            try {
                if (disposing)
                {
                    GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Close() m_Closed:" + m_Closed);
                    if (m_Closed)
                    {
                        if (Logging.On)
                        {
                            Logging.Exit(Logging.HttpListener, this, "Close", "");
                        }
                        return;
                    }
                    m_Closed = true;
                    UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags = ComputeLeftToWrite();
                    if (m_LeftToWrite > 0 && !m_InOpaqueMode)
                    {
                        throw new InvalidOperationException(SR.GetString(SR.net_io_notenoughbyteswritten));
                    }
                    bool sentHeaders = m_HttpContext.Response.SentHeaders;
                    if (sentHeaders && m_LeftToWrite == 0)
                    {
                        if (Logging.On)
                        {
                            Logging.Exit(Logging.HttpListener, this, "Close", "");
                        }
                        return;
                    }

                    uint statusCode = 0;
                    if ((m_HttpContext.Response.BoundaryType == BoundaryType.Chunked || m_HttpContext.Response.BoundaryType == BoundaryType.None) && (String.Compare(m_HttpContext.Request.HttpMethod, "HEAD", StringComparison.OrdinalIgnoreCase) != 0))
                    {
                        if (m_HttpContext.Response.BoundaryType == BoundaryType.None)
                        {
                            flags |= UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT;
                        }
                        fixed(void *pBuffer = NclConstants.ChunkTerminator)
                        {
                            UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK *pDataChunk = null;
                            if (m_HttpContext.Response.BoundaryType == BoundaryType.Chunked)
                            {
                                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;
                                dataChunk.BufferLength  = (uint)NclConstants.ChunkTerminator.Length;
                                pDataChunk = &dataChunk;
                            }
                            if (!sentHeaders)
                            {
                                statusCode = m_HttpContext.Response.SendHeaders(pDataChunk, null, flags, false);
                            }
                            else
                            {
                                GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Close() calling UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody");

                                statusCode =
                                    UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody(
                                        m_HttpContext.RequestQueueHandle,
                                        m_HttpContext.RequestId,
                                        (uint)flags,
                                        pDataChunk != null ? (ushort)1 : (ushort)0,
                                        pDataChunk,
                                        null,
                                        SafeLocalFree.Zero,
                                        0,
                                        null,
                                        null);

                                GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Close() call to UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody returned:" + statusCode);
                                if (m_HttpContext.Listener.IgnoreWriteExceptions)
                                {
                                    GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Close() suppressing error");
                                    statusCode = UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (!sentHeaders)
                        {
                            statusCode = m_HttpContext.Response.SendHeaders(null, null, flags, false);
                        }
                    }
                    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, "Close", exception);
                        }
                        m_HttpContext.Abort();
                        throw exception;
                    }
                    m_LeftToWrite = 0;
                }
            }
            finally {
                base.Dispose(disposing);
            }
            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "Dispose", "");
            }
        }
Example #11
0
        protected override unsafe void Dispose(bool disposing)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.HttpListener, this, "Close", "");
            }
            try
            {
                if (!disposing)
                {
                    goto Label_023F;
                }
                if (this.m_Closed)
                {
                    if (Logging.On)
                    {
                        Logging.Exit(Logging.HttpListener, this, "Close", "");
                    }
                    return;
                }
                this.m_Closed = true;
                UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags = this.ComputeLeftToWrite();
                if (this.m_LeftToWrite > 0L)
                {
                    throw new InvalidOperationException(SR.GetString("net_io_notenoughbyteswritten"));
                }
                bool sentHeaders = this.m_HttpContext.Response.SentHeaders;
                if (sentHeaders && (this.m_LeftToWrite == 0L))
                {
                    if (Logging.On)
                    {
                        Logging.Exit(Logging.HttpListener, this, "Close", "");
                    }
                    return;
                }
                uint num = 0;
                if (((this.m_HttpContext.Response.BoundaryType == BoundaryType.Chunked) || (this.m_HttpContext.Response.BoundaryType == BoundaryType.None)) && (string.Compare(this.m_HttpContext.Request.HttpMethod, "HEAD", StringComparison.OrdinalIgnoreCase) != 0))
                {
                    if (this.m_HttpContext.Response.BoundaryType == BoundaryType.None)
                    {
                        flags |= UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_INITIALIZE_SERVER;
                    }
                    try
                    {
                        byte[] buffer;
                        if (((buffer = NclConstants.ChunkTerminator) == null) || (buffer.Length == 0))
                        {
                            ptrRef = null;
                            goto Label_0132;
                        }
                        fixed(IntPtr *ptrRef = buffer)
                        {
                            UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK *http_data_chunkPtr;
Label_0132:
                            http_data_chunkPtr = null;
                            if (this.m_HttpContext.Response.BoundaryType == BoundaryType.Chunked)
                            {
                                UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK http_data_chunk = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK {
                                    DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory,
                                    pBuffer       = (byte *)ptrRef,
                                    BufferLength  = (uint)NclConstants.ChunkTerminator.Length
                                };
                                http_data_chunkPtr = &http_data_chunk;
                            }
                            if (!sentHeaders)
                            {
                                num = this.m_HttpContext.Response.SendHeaders(http_data_chunkPtr, null, flags);
                            }
                            else
                            {
                                num = UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody(this.m_HttpContext.RequestQueueHandle, this.m_HttpContext.RequestId, (uint)flags, (http_data_chunkPtr != null) ? ((ushort)1) : ((ushort)0), http_data_chunkPtr, null, SafeLocalFree.Zero, 0, null, null);
                                if (this.m_HttpContext.Listener.IgnoreWriteExceptions)
                                {
                                    num = 0;
                                }
                            }
                            goto Label_01F6;
                        }
                    }
                    finally
                    {
                        ptrRef = null;
                    }
                }
                if (!sentHeaders)
                {
                    num = this.m_HttpContext.Response.SendHeaders(null, null, flags);
                }
Label_01F6:
                switch (num)
                {
                case 0:
                case 0x26:
                    break;

                default:
                {
                    Exception e = new HttpListenerException((int)num);
                    if (Logging.On)
                    {
                        Logging.Exception(Logging.HttpListener, this, "Close", e);
                    }
                    this.m_HttpContext.Abort();
                    throw e;
                }
                }
                this.m_LeftToWrite = 0L;
            }
            finally
            {
                base.Dispose(disposing);
            }
Label_023F:
            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "Dispose", "");
            }
        }
Example #12
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);
        }
Example #13
0
        public override unsafe IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.HttpListener, this, "BeginRead", "");
            }
            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, "BeginRead", "");
                }
                HttpRequestStreamAsyncResult result = new HttpRequestStreamAsyncResult(this, state, callback);
                result.InvokeCallback(0);
                return(result);
            }
            HttpRequestStreamAsyncResult result2 = null;
            uint num = 0;

            if (this.m_DataChunkIndex != -1)
            {
                num = 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) && (num == size))
                {
                    result2 = new HttpRequestStreamAsyncResult(this, state, callback, buffer, offset, (uint)size, 0);
                    result2.InvokeCallback(num);
                }
            }
            if ((this.m_DataChunkIndex == -1) && (num < size))
            {
                uint num2 = 0;
                offset += (int)num;
                size   -= (int)num;
                if (size > 0x20000)
                {
                    size = 0x20000;
                }
                result2 = new HttpRequestStreamAsyncResult(this, state, callback, buffer, offset, (uint)size, num);
                try
                {
                    byte[] buffer2 = buffer;
                    if (buffer2 != null)
                    {
                        int length = buffer2.Length;
                    }
                    this.m_HttpContext.EnsureBoundHandle();
                    num2 = UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody(this.m_HttpContext.RequestQueueHandle, this.m_HttpContext.RequestId, 1, result2.m_pPinnedBuffer, (uint)size, null, result2.m_pOverlapped);
                }
                catch (Exception exception)
                {
                    if (Logging.On)
                    {
                        Logging.Exception(Logging.HttpListener, this, "BeginRead", exception);
                    }
                    result2.InternalCleanup();
                    throw;
                }
                switch (num2)
                {
                case 0:
                case 0x3e5:
                    goto Label_0217;
                }
                if (num2 == 0x26)
                {
                    result2.m_pOverlapped.InternalLow = IntPtr.Zero;
                }
                result2.InternalCleanup();
                if (num2 != 0x26)
                {
                    Exception e = new HttpListenerException((int)num2);
                    if (Logging.On)
                    {
                        Logging.Exception(Logging.HttpListener, this, "BeginRead", e);
                    }
                    result2.InternalCleanup();
                    throw e;
                }
                result2 = new HttpRequestStreamAsyncResult(this, state, callback, num);
                result2.InvokeCallback(0);
            }
Label_0217:
            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "BeginRead", "");
            }
            return(result2);
        }
Example #14
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);
        }
Example #15
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;
            }
        }
Example #16
0
        public override unsafe IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
        {
            uint num;

            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, "BeginWrite", "");
                }
                HttpResponseStreamAsyncResult result = new HttpResponseStreamAsyncResult(this, state, callback);
                result.InvokeCallback(0);
                return(result);
            }
            if ((this.m_LeftToWrite >= 0L) && (size > this.m_LeftToWrite))
            {
                throw new ProtocolViolationException(SR.GetString("net_entitytoobig"));
            }
            flags |= (this.m_LeftToWrite == size) ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
            bool sentHeaders = this.m_HttpContext.Response.SentHeaders;
            HttpResponseStreamAsyncResult asyncResult = new HttpResponseStreamAsyncResult(this, state, callback, buffer, offset, size, this.m_HttpContext.Response.BoundaryType == BoundaryType.Chunked, sentHeaders);

            try
            {
                if (!sentHeaders)
                {
                    num = this.m_HttpContext.Response.SendHeaders(null, asyncResult, flags);
                }
                else
                {
                    this.m_HttpContext.EnsureBoundHandle();
                    num = UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody(this.m_HttpContext.RequestQueueHandle, this.m_HttpContext.RequestId, (uint)flags, asyncResult.dataChunkCount, asyncResult.pDataChunks, null, SafeLocalFree.Zero, 0, asyncResult.m_pOverlapped, null);
                }
            }
            catch (Exception exception)
            {
                if (Logging.On)
                {
                    Logging.Exception(Logging.HttpListener, this, "BeginWrite", exception);
                }
                asyncResult.InternalCleanup();
                this.m_HttpContext.Abort();
                throw;
            }
            switch (num)
            {
            case 0:
            case 0x3e5:
                break;

            default:
                asyncResult.InternalCleanup();
                if (!this.m_HttpContext.Listener.IgnoreWriteExceptions || !sentHeaders)
                {
                    Exception e = new HttpListenerException((int)num);
                    if (Logging.On)
                    {
                        Logging.Exception(Logging.HttpListener, this, "BeginWrite", e);
                    }
                    this.m_HttpContext.Abort();
                    throw e;
                }
                break;
            }
            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "BeginWrite", "");
            }
            return(asyncResult);
        }
Example #17
0
        //Caution, this will return ipv6 addresses if the OS supports it.  This shouldn't be called by the public apis.
        internal static IPHostEntry InternalResolveFast(string hostName, int timeout, out bool timedOut)
        {
            GlobalLog.Assert(hostName != null, "hostName == null");
            GlobalLog.Print("Dns.InternalResolveFase: " + hostName);

            //
            // the differences between this method and the previous InternalResolve() are:
            //
            // 1) we don't throw any exceptions
            // 2) we don't do a reverse lookup for address strings, we just use them
            //
            // IPv6 Changes: It is not practical to embed the code for GetAddrInfo here, instead
            //               we call it and catch any exceptions.
            //
            // Timeout: Supports a timeout by offloading work to another thread if necessary.
            //

            // We can't abort a DNS lookup so if we think might need to, run it on another thread.
            // According to MSDN the max time is 17 seconds.  Use 18 and say 20.
            // Also: MSDN describes how one lookup can result in a string of queries.  It's unclear whether
            // those would be run in series, extending the possible time this will take, or whether it will always
            // give up after 17 seconds.  For now assume that 17 seconds is the absolute max.
            bool mightTimeOut = 18000 >= (uint)timeout && timeout != Timeout.Infinite;

            timedOut = false;

            if (hostName.Length > 0 && hostName.Length <= MaxHostName)
            {
                // IP Address?
                IPAddress address;
                if (TryParseAsIP(hostName, out address))
                {
                    IPHostEntry ipHostEntry = new IPHostEntry();
                    ipHostEntry.HostName    = address.ToString();
                    ipHostEntry.Aliases     = new string[0];
                    ipHostEntry.AddressList = new IPAddress[] { address };

                    GlobalLog.Print("Dns::InternalResolveFast() returned address:" + address.ToString());
                    return(ipHostEntry);
                }

                // Looks like a hostname (or failed address parsing)
                if (Socket.OSSupportsIPv6)
                {
                    try
                    {
                        // we will no longer offload to a thread, due to the consequence of having a threadpool thread
                        //block on another threadpool thread.  In addition, even w/ the DNS server functioning, we run
                        // the risk of having too many of these queued up, causing requests to fail w/ an unable to resolve
                        //exception.

                        //I'm leaving the code commented out to possibly reuse in our async case.

                        // if (!mightTimeOut)
                        // {
                        return(GetAddrInfo(hostName));
                        // }

                        /* else
                         * {
                         *   AsyncDnsContext dnsContext = new AsyncDnsContext(hostName);
                         *   dnsContext.Offload(new WaitCallback(OffloadedGetAddrInfo));
                         *   return (IPHostEntry) dnsContext.Wait(timeout, out timedOut);
                         * }
                         */
                    }
                    catch (Exception e)
                    {
                        GlobalLog.Print("Dns::InternalResolveFast() GetAddrInfo() threw: " + e.Message);
                    }
                }
                else
                {
                    //
                    // we duplicate the code in GetHostByName() to avoid
                    // having to catch the thrown exception
                    //
                    IntPtr nativePointer;
                    //if (!mightTimeOut)
                    //{
                    nativePointer = UnsafeNclNativeMethods.OSSOCK.gethostbyname(hostName);
                    //}

                    /*
                     * else
                     * {
                     *  AsyncDnsContext dnsContext = new AsyncDnsContext(hostName);
                     *  dnsContext.Offload(new WaitCallback(OffloadedGetHostByName));
                     *  object result = dnsContext.Wait(timeout, out timedOut);
                     *  nativePointer = result == null ? IntPtr.Zero : (IntPtr) result;
                     * }
                     */
                    if (nativePointer != IntPtr.Zero)
                    {
                        GlobalLog.Print("Dns::InternalResolveFast() gethostbyname() returned nativePointer:" + nativePointer.ToString());
                        return(NativeToHostEntry(nativePointer));
                    }
                }
            }

            GlobalLog.Print("Dns::InternalResolveFast() returning null");
            if (Logging.On)
            {
                Logging.Exit(Logging.Sockets, "DNS", "InternalResolveFast", null);
            }
            return(null);
        }
Example #18
0
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
        {
            GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::BeginWrite() 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, "BeginWrite", "");
                }
                HttpResponseStreamAsyncResult result = new HttpResponseStreamAsyncResult(this, state, callback);
                result.InvokeCallback((uint)0);
                return(result);
            }
            if (m_LeftToWrite >= 0 && size > m_LeftToWrite)
            {
                throw new ProtocolViolationException(SR.GetString(SR.net_entitytoobig));
            }

            uint statusCode;
            uint bytesSent = 0;

            flags |= m_LeftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
            bool sentHeaders = m_HttpContext.Response.SentHeaders;
            HttpResponseStreamAsyncResult asyncResult = new HttpResponseStreamAsyncResult(this, state, callback, buffer, offset, size, m_HttpContext.Response.BoundaryType == BoundaryType.Chunked, sentHeaders);

            // Update m_LeftToWrite now so we can queue up additional BeginWrite's without waiting for EndWrite.
            UpdateAfterWrite((uint)((m_HttpContext.Response.BoundaryType == BoundaryType.Chunked) ? 0 : size));

            try {
                if (!sentHeaders)
                {
                    statusCode = m_HttpContext.Response.SendHeaders(null, asyncResult, flags, false);
                }
                else
                {
                    GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::BeginWrite() calling UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody");

                    m_HttpContext.EnsureBoundHandle();
                    statusCode =
                        UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody(
                            m_HttpContext.RequestQueueHandle,
                            m_HttpContext.RequestId,
                            (uint)flags,
                            asyncResult.dataChunkCount,
                            asyncResult.pDataChunks,
                            &bytesSent,
                            SafeLocalFree.Zero,
                            0,
                            asyncResult.m_pOverlapped,
                            null);

                    GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::BeginWrite() call to UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody returned:" + statusCode);
                }
            }
            catch (Exception e) {
                if (Logging.On)
                {
                    Logging.Exception(Logging.HttpListener, this, "BeginWrite", e);
                }
                asyncResult.InternalCleanup();
                m_Closed = true;
                m_HttpContext.Abort();
                throw;
            }

            if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
            {
                asyncResult.InternalCleanup();
                if (m_HttpContext.Listener.IgnoreWriteExceptions && sentHeaders)
                {
                    GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::BeginWrite() suppressing error");
                }
                else
                {
                    Exception exception = new HttpListenerException((int)statusCode);
                    if (Logging.On)
                    {
                        Logging.Exception(Logging.HttpListener, this, "BeginWrite", exception);
                    }
                    m_Closed = true;
                    m_HttpContext.Abort();
                    throw exception;
                }
            }

            if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && HttpListener.SkipIOCPCallbackOnSuccess)
            {
                // IO operation completed synchronously - callback won't be called to signal completion.
                asyncResult.IOCompleted(statusCode, bytesSent);
            }

            // Last write, cache it for special cancelation handling.
            if ((flags & UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA) == 0)
            {
                m_LastWrite = asyncResult;
            }

            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "BeginWrite", "");
            }
            return(asyncResult);
        }
Example #19
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", "");
            }
        }
Example #20
0
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.HttpListener, this, "BeginRead", "");
            }
            GlobalLog.Print("HttpRequestStream#" + ValidationHelper.HashString(this) + "::BeginRead() 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");
            }
            if (size == 0 || m_Closed)
            {
                if (Logging.On)
                {
                    Logging.Exit(Logging.HttpListener, this, "BeginRead", "");
                }
                HttpRequestStreamAsyncResult result = new HttpRequestStreamAsyncResult(this, state, callback);
                result.InvokeCallback((uint)0);
                return(result);
            }

            HttpRequestStreamAsyncResult asyncResult = null;

            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)
                {
                    asyncResult = new HttpRequestStreamAsyncResult(this, state, callback, buffer, offset, (uint)size, 0);
                    asyncResult.InvokeCallback(dataRead);
                }
            }

            if (m_DataChunkIndex == -1 && dataRead < size)
            {
                GlobalLog.Print("HttpRequestStream#" + ValidationHelper.HashString(this) + "::BeginRead() size:" + size + " offset:" + offset);
                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 HttpRequestStreamAsyncResult(this, state, callback, buffer, offset, (uint)size, dataRead);
                uint bytesReturned;

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

                        m_HttpContext.EnsureBoundHandle();
                        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,
                                asyncResult.m_pPinnedBuffer,
                                (uint)size,
                                out bytesReturned,
                                asyncResult.m_pOverlapped);

                        GlobalLog.Print("HttpRequestStream#" + ValidationHelper.HashString(this) + "::BeginRead() call to UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody returned:" + statusCode + " dataRead:" + dataRead);
                    }
                }
                catch (Exception e) {
                    if (Logging.On)
                    {
                        Logging.Exception(Logging.HttpListener, this, "BeginRead", e);
                    }
                    asyncResult.InternalCleanup();
                    throw;
                }

                if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
                {
                    asyncResult.InternalCleanup();
                    if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
                    {
                        asyncResult = new HttpRequestStreamAsyncResult(this, state, callback, dataRead);
                        asyncResult.InvokeCallback((uint)0);
                    }
                    else
                    {
                        Exception exception = new HttpListenerException((int)statusCode);
                        if (Logging.On)
                        {
                            Logging.Exception(Logging.HttpListener, this, "BeginRead", exception);
                        }
                        asyncResult.InternalCleanup();
                        throw exception;
                    }
                }
                else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
                         HttpListener.SkipIOCPCallbackOnSuccess)
                {
                    // IO operation completed synchronously - callback won't be called to signal completion.
                    asyncResult.IOCompleted(statusCode, bytesReturned);
                }
            }
            if (Logging.On)
            {
                Logging.Exit(Logging.HttpListener, this, "BeginRead", "");
            }
            return(asyncResult);
        }