public HttpListenerContext GetContext() { if (NetEventSource.IsEnabled) NetEventSource.Enter(this); SyncRequestContext memoryBlob = null; HttpListenerContext httpContext = null; bool stoleBlob = false; try { CheckDisposed(); if (_state == State.Stopped) { throw new InvalidOperationException(SR.Format(SR.net_listener_mustcall, "Start()")); } if (_uriPrefixes.Count == 0) { throw new InvalidOperationException(SR.Format(SR.net_listener_mustcall, "AddPrefix()")); } uint statusCode = Interop.HttpApi.ERROR_SUCCESS; uint size = 4096; ulong requestId = 0; memoryBlob = new SyncRequestContext((int)size); for (;;) { for (;;) { if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Calling Interop.HttpApi.HttpReceiveHttpRequest RequestId: {requestId}"); uint bytesTransferred = 0; statusCode = Interop.HttpApi.HttpReceiveHttpRequest( _requestQueueHandle, requestId, (uint)Interop.HttpApi.HTTP_FLAGS.HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY, memoryBlob.RequestBlob, size, &bytesTransferred, null); if (NetEventSource.IsEnabled) NetEventSource.Info(this, "Call to Interop.HttpApi.HttpReceiveHttpRequest returned:" + statusCode); if (statusCode == Interop.HttpApi.ERROR_INVALID_PARAMETER && requestId != 0) { // we might get this if somebody stole our RequestId, // we need to start all over again but we can reuse the buffer we just allocated requestId = 0; continue; } else if (statusCode == Interop.HttpApi.ERROR_MORE_DATA) { // the buffer was not big enough to fit the headers, we need // to read the RequestId returned, allocate a new buffer of the required size size = bytesTransferred; requestId = memoryBlob.RequestBlob->RequestId; memoryBlob.Reset(checked((int)size)); continue; } break; } if (statusCode != Interop.HttpApi.ERROR_SUCCESS) { // someother bad error, return values are: // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED throw new HttpListenerException((int)statusCode); } if (ValidateRequest(memoryBlob)) { // We need to hook up our authentication handling code here. httpContext = HandleAuthentication(memoryBlob, out stoleBlob); } if (stoleBlob) { // The request has been handed to the user, which means this code can't reuse the blob. Reset it here. memoryBlob = null; stoleBlob = false; } if (NetEventSource.IsEnabled) NetEventSource.Info(this, ":HandleAuthentication() returned httpContext" + httpContext); // if the request survived authentication, return it to the user if (httpContext != null) { return httpContext; } // HandleAuthentication may have cleaned this up. if (memoryBlob == null) { memoryBlob = new SyncRequestContext(checked((int)size)); } requestId = 0; } } catch (Exception exception) { if (NetEventSource.IsEnabled) NetEventSource.Error(this, $"{exception}"); throw; } finally { if (memoryBlob != null && !stoleBlob) { memoryBlob.ReleasePins(); memoryBlob.Close(); } if (NetEventSource.IsEnabled) NetEventSource.Exit(this, "RequestTraceIdentifier: " + (httpContext != null ? httpContext.Request.RequestTraceIdentifier.ToString() : "<null>")); } }
public unsafe HttpListenerContext GetContext() { HttpListenerContext context3; if (Logging.On) { Logging.Enter(Logging.HttpListener, this, "GetContext", ""); } SyncRequestContext memoryBlob = null; HttpListenerContext objectValue = null; bool stoleBlob = false; try { uint num4; this.CheckDisposed(); if (this.m_State == null) { throw new InvalidOperationException(SR.GetString("net_listener_mustcall", new object[] { "Start()" })); } if (this.m_UriPrefixes.Count == 0) { throw new InvalidOperationException(SR.GetString("net_listener_mustcall", new object[] { "AddPrefix()" })); } uint num = 0; uint requestBufferLength = 0x1000; ulong requestId = 0L; memoryBlob = new SyncRequestContext((int) requestBufferLength); Label_009A: num4 = 0; num = UnsafeNclNativeMethods.HttpApi.HttpReceiveHttpRequest(this.m_RequestQueueHandle, requestId, 1, memoryBlob.RequestBlob, requestBufferLength, &num4, null); if ((num == 0x57) && (requestId != 0L)) { requestId = 0L; goto Label_009A; } if (num == 0xea) { requestBufferLength = num4; requestId = memoryBlob.RequestBlob.RequestId; memoryBlob.Reset((int) requestBufferLength); goto Label_009A; } if (num != 0) { throw new HttpListenerException((int) num); } objectValue = this.HandleAuthentication(memoryBlob, out stoleBlob); if (stoleBlob) { memoryBlob = null; stoleBlob = false; } if (objectValue != null) { context3 = objectValue; } else { if (memoryBlob == null) { memoryBlob = new SyncRequestContext((int) requestBufferLength); } requestId = 0L; goto Label_009A; } } catch (Exception exception) { if (Logging.On) { Logging.Exception(Logging.HttpListener, this, "GetContext", exception); } throw; } finally { if ((memoryBlob != null) && !stoleBlob) { memoryBlob.ReleasePins(); memoryBlob.Close(); } if (Logging.On) { Logging.Exit(Logging.HttpListener, this, "GetContext", "HttpListenerContext#" + ValidationHelper.HashString(objectValue) + " RequestTraceIdentifier#" + ((objectValue != null) ? objectValue.Request.RequestTraceIdentifier.ToString() : "<null>")); } } return context3; }