internal void RegisterAllPrefixes(UrlGroup urlGroup) { lock (_prefixes) { _urlGroup = urlGroup; // go through the uri list and register for each one of them // Call ToList to avoid modification when enumerating. foreach (var pair in _prefixes.ToList()) { var urlPrefix = pair.Value; if (urlPrefix.PortValue == 0) { if (urlPrefix.IsHttps) { throw new InvalidOperationException("Cannot bind to port 0 with https."); } FindHttpPortUnsynchronized(pair.Key, urlPrefix); } else { // We'll get this index back on each request and use it to look up the prefix to calculate PathBase. _urlGroup.RegisterPrefix(pair.Value.FullPrefix, pair.Key); } } } }
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); }
internal DelegationRule(UrlGroup sourceQueueUrlGroup, string queueName, string urlPrefix, ILogger logger) { _sourceQueueUrlGroup = sourceQueueUrlGroup; _logger = logger; QueueName = queueName; UrlPrefix = urlPrefix; Queue = new RequestQueue(queueName, UrlPrefix, _logger, receiver: true); _urlGroup = Queue.UrlGroup; }
public HttpSysListener(HttpSysOptions options, ILoggerFactory loggerFactory) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (loggerFactory == null) { throw new ArgumentNullException(nameof(loggerFactory)); } if (!HttpApi.Supported) { throw new PlatformNotSupportedException(); } Debug.Assert(HttpApi.ApiVersion == HttpApiTypes.HTTP_API_VERSION.Version20, "Invalid Http api version"); Options = options; Logger = loggerFactory.CreateLogger <HttpSysListener>(); _state = State.Stopped; _internalLock = new object(); // V2 initialization sequence: // 1. Create server session // 2. Create url group // 3. Create request queue // 4. Add urls to url group - Done in Start() // 5. Attach request queue to url group - Done in Start() try { _serverSession = new ServerSession(); _urlGroup = new UrlGroup(_serverSession, Logger); _requestQueue = new RequestQueue(_urlGroup, options.RequestQueueName, options.RequestQueueMode, Logger); _disconnectListener = new DisconnectListener(_requestQueue, Logger); } catch (Exception exception) { // If Url group or request queue creation failed, close server session before throwing. _requestQueue?.Dispose(); _urlGroup?.Dispose(); _serverSession?.Dispose(); Log.HttpSysListenerCtorError(Logger, exception); throw; } }
internal void RegisterAllPrefixes(UrlGroup urlGroup) { lock (_prefixes) { _urlGroup = urlGroup; // go through the uri list and register for each one of them foreach (var pair in _prefixes) { // We'll get this index back on each request and use it to look up the prefix to calculate PathBase. _urlGroup.RegisterPrefix(pair.Value.FullPrefix, pair.Key); } } }
internal RequestQueue(string requestQueueName, string urlPrefix, ILogger logger, bool receiver) : this(urlGroup : null, requestQueueName, RequestQueueMode.Attach, logger, receiver) { try { UrlGroup = new UrlGroup(this, UrlPrefix.Create(urlPrefix)); } catch { Dispose(); throw; } }
internal void SetUrlGroupSecurity(UrlGroup urlGroup) { Debug.Assert(_urlGroup == null, "SetUrlGroupSecurity called more than once."); _urlGroup = urlGroup; SetUrlGroupSecurity(); }
internal void SetUrlGroupTimeouts(UrlGroup urlGroup) { _urlGroup = urlGroup; SetUrlGroupTimeouts(_timeouts, _minSendBytesPerSecond); }
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); } }
internal RequestQueue(UrlGroup urlGroup, string requestQueueName, RequestQueueMode mode, ILogger logger) : this(urlGroup, requestQueueName, mode, logger, false) { }