Esempio n. 1
0
        /// <summary>
        /// Processes the message
        /// </summary>
        /// <param name="connectionBase">The connection base</param>
        /// <param name="message">The playerio message</param>
        /// <param name="handled">Whether the message was already handled</param>
        public void Process(ConnectionBase connectionBase, Message message, bool handled)
        {
            UpgradeEvent upgradeEvent = new UpgradeEvent()
            {
                Raw = message
            };

            connectionBase.RaiseServerEvent <UpgradeEvent>(upgradeEvent);
        }
        /// <summary>
        /// Checks the installed version vs the version that is running, and will report either a new install
        /// if no previous version is found, or an upgrade if a lower version is found. If the same version
        /// is found, nothing is reported.
        /// </summary>
        private async Task CheckInstallationStatusAsync()
        {
            await JoinableTaskFactory.SwitchToMainThreadAsync();

            AnalyticsOptions settings = GeneralSettings;

            if (settings.InstalledVersion == null)
            {
                // This is a new installation.
                Debug.WriteLine("New installation detected.");
                EventsReporterWrapper.ReportEvent(NewInstallEvent.Create());
            }
            else if (settings.InstalledVersion != ApplicationVersion)
            {
                // This is an upgrade (or different version installed).
                Debug.WriteLine($"Found new version {settings.InstalledVersion} different than current {ApplicationVersion}");

                if (!Version.TryParse(ApplicationVersion, out Version current))
                {
                    Debug.WriteLine($"Invalid application version: {ApplicationVersion}");
                    return;
                }
                if (!Version.TryParse(settings.InstalledVersion, out Version installed))
                {
                    Debug.WriteLine($"Invalid installed version: {settings.InstalledVersion}");
                    return;
                }

                if (installed < current)
                {
                    Debug.WriteLine($"Upgrade to version {ApplicationVersion} detected.");
                    EventsReporterWrapper.ReportEvent(UpgradeEvent.Create());
                }
            }
            else
            {
                Debug.WriteLine($"Same version {settings.InstalledVersion} detected.");
            }

            // Update the stored settings with the current version.
            settings.InstalledVersion = ApplicationVersion;
            settings.SaveSettingsToStorage();
        }
Esempio n. 3
0
        /// <summary>
        /// Checks the installed version vs the version that is running, and will report either a new install
        /// if no previous version is found, or an upgrade if a lower version is found. If the same version
        /// is found, nothing is reported.
        /// </summary>
        private void CheckInstallationStatus()
        {
            var settings = AnalyticsSettings;

            if (settings.InstalledVersion == null)
            {
                // This is a new installation.
                Debug.WriteLine("New installation detected.");
                EventsReporterWrapper.ReportEvent(NewInstallEvent.Create());
            }
            else if (settings.InstalledVersion != ApplicationVersion)
            {
                // This is an upgrade (or different version installed).
                Debug.WriteLine($"Found new version {settings.InstalledVersion} different than current {ApplicationVersion}");

                Version current, installed;
                if (!Version.TryParse(ApplicationVersion, out current))
                {
                    Debug.WriteLine($"Invalid application version: {ApplicationVersion}");
                    return;
                }
                if (!Version.TryParse(settings.InstalledVersion, out installed))
                {
                    Debug.WriteLine($"Invalid installed version: {settings.InstalledVersion}");
                    return;
                }

                if (installed < current)
                {
                    Debug.WriteLine($"Upgrade to version {ApplicationVersion} detected.");
                    EventsReporterWrapper.ReportEvent(UpgradeEvent.Create());
                }
            }
            else
            {
                Debug.WriteLine($"Same version {settings.InstalledVersion} detected.");
            }

            // Update the stored settings with the current version.
            settings.InstalledVersion = ApplicationVersion;
            settings.SaveSettingsToStorage();
        }
        bool Upgrade(IChannelHandlerContext ctx, IFullHttpRequest request)
        {
            // Select the best protocol based on those requested in the UPGRADE header.
            IList <ICharSequence> requestedProtocols = SplitHeader(request.Headers.Get(HttpHeaderNames.Upgrade, null));
            int           numRequestedProtocols      = requestedProtocols.Count;
            IUpgradeCodec upgradeCodec    = null;
            ICharSequence upgradeProtocol = null;

            for (int i = 0; i < numRequestedProtocols; i++)
            {
                ICharSequence p = requestedProtocols[i];
                IUpgradeCodec c = this.upgradeCodecFactory.NewUpgradeCodec(p);
                if (c != null)
                {
                    upgradeProtocol = p;
                    upgradeCodec    = c;
                    break;
                }
            }

            if (upgradeCodec == null)
            {
                // None of the requested protocols are supported, don't upgrade.
                return(false);
            }

            // Make sure the CONNECTION header is present.
            if (!request.Headers.TryGet(HttpHeaderNames.Connection, out ICharSequence connectionHeader))
            {
                return(false);
            }

            // Make sure the CONNECTION header contains UPGRADE as well as all protocol-specific headers.
            ICollection <AsciiString> requiredHeaders = upgradeCodec.RequiredUpgradeHeaders;
            IList <ICharSequence>     values          = SplitHeader(connectionHeader);

            if (!AsciiString.ContainsContentEqualsIgnoreCase(values, HttpHeaderNames.Upgrade) ||
                !AsciiString.ContainsAllContentEqualsIgnoreCase(values, requiredHeaders))
            {
                return(false);
            }

            // Ensure that all required protocol-specific headers are found in the request.
            foreach (AsciiString requiredHeader in requiredHeaders)
            {
                if (!request.Headers.Contains(requiredHeader))
                {
                    return(false);
                }
            }

            // Prepare and send the upgrade response. Wait for this write to complete before upgrading,
            // since we need the old codec in-place to properly encode the response.
            IFullHttpResponse upgradeResponse = CreateUpgradeResponse(upgradeProtocol);

            if (!upgradeCodec.PrepareUpgradeResponse(ctx, request, upgradeResponse.Headers))
            {
                return(false);
            }

            // Create the user event to be fired once the upgrade completes.
            var upgradeEvent = new UpgradeEvent(upgradeProtocol, request);

            IUpgradeCodec finalUpgradeCodec = upgradeCodec;

            ctx.WriteAndFlushAsync(upgradeResponse).ContinueWith(t =>
            {
                try
                {
                    if (t.Status == TaskStatus.RanToCompletion)
                    {
                        // Perform the upgrade to the new protocol.
                        this.sourceCodec.UpgradeFrom(ctx);
                        finalUpgradeCodec.UpgradeTo(ctx, request);

                        // Notify that the upgrade has occurred. Retain the event to offset
                        // the release() in the finally block.
                        ctx.FireUserEventTriggered(upgradeEvent.Retain());

                        // Remove this handler from the pipeline.
                        ctx.Channel.Pipeline.Remove(this);
                    }
                    else
                    {
                        ctx.Channel.CloseAsync();
                    }
                }
                finally
                {
                    // Release the event if the upgrade event wasn't fired.
                    upgradeEvent.Release();
                }
            }, TaskContinuationOptions.ExecuteSynchronously);
            return(true);
        }
        /// <summary>
        /// Attempts to upgrade to the protocol(s) identified by the <see cref="HttpHeaderNames.Upgrade"/> header (if provided
        /// in the request).
        /// </summary>
        /// <param name="ctx">the context for this handler.</param>
        /// <param name="request">the HTTP request.</param>
        /// <returns><c>true</c> if the upgrade occurred, otherwise <c>false</c>.</returns>
        bool Upgrade(IChannelHandlerContext ctx, IFullHttpRequest request)
        {
            // Select the best protocol based on those requested in the UPGRADE header.
            var           requestedProtocols    = SplitHeader(request.Headers.Get(HttpHeaderNames.Upgrade, null));
            int           numRequestedProtocols = requestedProtocols.Count;
            IUpgradeCodec upgradeCodec          = null;
            ICharSequence upgradeProtocol       = null;

            for (int i = 0; i < numRequestedProtocols; i++)
            {
                ICharSequence p = requestedProtocols[i];
                IUpgradeCodec c = this.upgradeCodecFactory.NewUpgradeCodec(p);
                if (c is object)
                {
                    upgradeProtocol = p;
                    upgradeCodec    = c;
                    break;
                }
            }

            if (upgradeCodec is null)
            {
                // None of the requested protocols are supported, don't upgrade.
                return(false);
            }

            // Make sure the CONNECTION header is present.
            var connectionHeaderValues = request.Headers.GetAll(HttpHeaderNames.Connection);

            if (connectionHeaderValues is null)
            {
                return(false);
            }

            var concatenatedConnectionValue = StringBuilderManager.Allocate(connectionHeaderValues.Count * 10);

            for (var idx = 0; idx < connectionHeaderValues.Count; idx++)
            {
                var connectionHeaderValue = connectionHeaderValues[idx];
                _ = concatenatedConnectionValue
                    .Append(connectionHeaderValue.ToString())
                    .Append(StringUtil.Comma);
            }
            concatenatedConnectionValue.Length -= 1;

            // Make sure the CONNECTION header contains UPGRADE as well as all protocol-specific headers.
            var requiredHeaders = upgradeCodec.RequiredUpgradeHeaders;
            var values          = SplitHeader(StringBuilderManager.ReturnAndFree(concatenatedConnectionValue).AsSpan());

            if (!AsciiString.ContainsContentEqualsIgnoreCase(values, HttpHeaderNames.Upgrade) ||
                !AsciiString.ContainsAllContentEqualsIgnoreCase(values, requiredHeaders))
            {
                return(false);
            }

            // Ensure that all required protocol-specific headers are found in the request.
            for (int idx = 0; idx < requiredHeaders.Count; idx++)
            {
                if (!request.Headers.Contains(requiredHeaders[idx]))
                {
                    return(false);
                }
            }

            // Prepare and send the upgrade response. Wait for this write to complete before upgrading,
            // since we need the old codec in-place to properly encode the response.
            IFullHttpResponse upgradeResponse = CreateUpgradeResponse(upgradeProtocol);

            if (!upgradeCodec.PrepareUpgradeResponse(ctx, request, upgradeResponse.Headers))
            {
                return(false);
            }

            // Create the user event to be fired once the upgrade completes.
            var upgradeEvent = new UpgradeEvent(upgradeProtocol, request);

            // After writing the upgrade response we immediately prepare the
            // pipeline for the next protocol to avoid a race between completion
            // of the write future and receiving data before the pipeline is
            // restructured.
            try
            {
                var writeComplete = ctx.WriteAndFlushAsync(upgradeResponse);

                // Perform the upgrade to the new protocol.
                this.sourceCodec.UpgradeFrom(ctx);
                upgradeCodec.UpgradeTo(ctx, request);

                // Remove this handler from the pipeline.
                _ = ctx.Pipeline.Remove(this);

                // Notify that the upgrade has occurred. Retain the event to offset
                // the release() in the finally block.
                _ = ctx.FireUserEventTriggered(upgradeEvent.Retain());

                // Add the listener last to avoid firing upgrade logic after
                // the channel is already closed since the listener may fire
                // immediately if the write failed eagerly.
                _ = writeComplete.ContinueWith(CloseOnFailureAction, ctx, TaskContinuationOptions.ExecuteSynchronously);
            }
            finally
            {
                // Release the event if the upgrade event wasn't fired.
                _ = upgradeEvent.Release();
            }
            return(true);
        }