internal uint QueueBeginGetContext()
{
uint statusCode = Interop.HttpApi.ERROR_SUCCESS;
while (true)
{
if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Calling Interop.HttpApi.HttpReceiveHttpRequest RequestId: {_requestContext.RequestBlob->RequestId}Buffer:0x {((IntPtr)_requestContext.RequestBlob).ToString("x")} Size: {_requestContext.Size}");
uint bytesTransferred = 0;
HttpListener listener = (HttpListener)AsyncObject;
statusCode = Interop.HttpApi.HttpReceiveHttpRequest(
listener.RequestQueueHandle,
_requestContext.RequestBlob->RequestId,
(uint)Interop.HttpApi.HTTP_FLAGS.HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY,
_requestContext.RequestBlob,
_requestContext.Size,
&bytesTransferred,
_requestContext.NativeOverlapped);
if (NetEventSource.IsEnabled) NetEventSource.Info(this, "Call to Interop.HttpApi.HttpReceiveHttpRequest returned:" + statusCode);
if (statusCode == Interop.HttpApi.ERROR_INVALID_PARAMETER && _requestContext.RequestBlob->RequestId != 0)
{
// we might get this if somebody stole our RequestId,
// set RequestId to 0 and start all over again with the buffer we just allocated
_requestContext.RequestBlob->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
_requestContext.Reset(listener.RequestQueueBoundHandle, _requestContext.RequestBlob->RequestId, bytesTransferred);
continue;
}
else if (statusCode == Interop.HttpApi.ERROR_SUCCESS &&
HttpListener.SkipIOCPCallbackOnSuccess)
{
// IO operation completed synchronously - callback won't be called to signal completion.
IOCompleted(this, statusCode, bytesTransferred);
}
break;
}
return statusCode;
}