Пример #1
0
        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);
                    }
                }
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
 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;
 }
Пример #4
0
        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;
            }
        }
Пример #5
0
 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);
         }
     }
 }
Пример #6
0
 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;
     }
 }
Пример #7
0
 internal void SetUrlGroupSecurity(UrlGroup urlGroup)
 {
     Debug.Assert(_urlGroup == null, "SetUrlGroupSecurity called more than once.");
     _urlGroup = urlGroup;
     SetUrlGroupSecurity();
 }
Пример #8
0
 internal void SetUrlGroupTimeouts(UrlGroup urlGroup)
 {
     _urlGroup = urlGroup;
     SetUrlGroupTimeouts(_timeouts, _minSendBytesPerSecond);
 }
Пример #9
0
        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);
            }
        }
Пример #10
0
 internal RequestQueue(UrlGroup urlGroup, string requestQueueName, RequestQueueMode mode, ILogger logger)
     : this(urlGroup, requestQueueName, mode, logger, false)
 {
 }