internal RequestQueue(UrlGroup urlGroup, ILogger logger) { _urlGroup = urlGroup; _logger = logger; HttpRequestQueueV2Handle requestQueueHandle = null; var statusCode = HttpApi.HttpCreateRequestQueue( HttpApi.Version, null, null, 0, out requestQueueHandle); if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { throw new HttpSysException((int)statusCode); } // Disabling callbacks when IO operation completes synchronously (returns ErrorCodes.ERROR_SUCCESS) if (HttpSysListener.SkipIOCPCallbackOnSuccess && !UnsafeNclNativeMethods.SetFileCompletionNotificationModes( requestQueueHandle, UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipCompletionPortOnSuccess | UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipSetEventOnHandle)) { throw new HttpSysException(Marshal.GetLastWin32Error()); } Handle = requestQueueHandle; BoundHandle = ThreadPoolBoundHandle.BindHandle(Handle); }
public async Task Server_ConnectExistingQueueName_Success() { string address; var queueName = Guid.NewGuid().ToString(); // First create the queue. HttpRequestQueueV2Handle requestQueueHandle = null; var statusCode = HttpApi.HttpCreateRequestQueue( HttpApi.Version, queueName, null, 0, out requestQueueHandle); Assert.True(statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS); // Now attach to the existing one using (Utilities.CreateHttpServer(out address, httpContext => { return(Task.FromResult(0)); }, options => { options.RequestQueueName = queueName; options.RequestQueueMode = RequestQueueMode.Attach; })) { var psi = new ProcessStartInfo("netsh", "http show servicestate view=requestq") { RedirectStandardOutput = true }; using var process = Process.Start(psi); process.Start(); var netshOutput = await process.StandardOutput.ReadToEndAsync(); Assert.Contains(queueName, netshOutput); } }
internal RequestQueue(UrlGroup urlGroup, string requestQueueName, RequestQueueMode mode, ILogger logger) { _mode = mode; _urlGroup = urlGroup; _logger = logger; var flags = HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.None; Created = true; if (_mode == RequestQueueMode.Attach) { flags = HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.OpenExisting; Created = false; } var statusCode = HttpApi.HttpCreateRequestQueue( HttpApi.Version, requestQueueName, null, flags, out var requestQueueHandle); if (_mode == RequestQueueMode.CreateOrAttach && statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_ALREADY_EXISTS) { // Tried to create, but it already exists so attach to it instead. Created = false; flags = HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.OpenExisting; statusCode = HttpApi.HttpCreateRequestQueue( HttpApi.Version, requestQueueName, null, flags, out requestQueueHandle); } if (flags == HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.OpenExisting && statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_FILE_NOT_FOUND) { throw new HttpSysException((int)statusCode, $"Failed to attach to the given request queue '{requestQueueName}', the queue could not be found."); } else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_NAME) { throw new HttpSysException((int)statusCode, $"The given request queue name '{requestQueueName}' is invalid."); } else if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { throw new HttpSysException((int)statusCode); } // Disabling callbacks when IO operation completes synchronously (returns ErrorCodes.ERROR_SUCCESS) if (HttpSysListener.SkipIOCPCallbackOnSuccess && !UnsafeNclNativeMethods.SetFileCompletionNotificationModes( requestQueueHandle, UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipCompletionPortOnSuccess | UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipSetEventOnHandle)) { requestQueueHandle.Dispose(); throw new HttpSysException(Marshal.GetLastWin32Error()); } Handle = requestQueueHandle; BoundHandle = ThreadPoolBoundHandle.BindHandle(Handle); if (!Created) { _logger.LogInformation(LoggerEventIds.AttachedToQueue, "Attached to an existing request queue '{requestQueueName}', some options do not apply.", requestQueueName); } }