/// <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", ""); } }
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); }
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
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", ""); } }
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()
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); }
/*++ * * 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)); }
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
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", ""); } }
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", ""); } }
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); }
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); }
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); }
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; } }
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); }
//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); }
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); }
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", ""); } }
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); }