private async Task <ServiceWorkerDetectionResult> RunCore(Uri uri)
        {
            var(pageHtml, canonicalUri) = await GetPageHtml(uri);

            var htmlDoc = GetDocument(pageHtml);

            // Find the service worker inside the HTML of the page.
            var swUrl = await GetServiceWorkerUrlFromDoc(canonicalUri, htmlDoc) ??
                        await GetServiceWorkerUrlFromScripts(canonicalUri, htmlDoc); // Can't find sw reg in the HTML doc? Search its scripts.

            // If we found a service worker registration, but couldn't find the real name of the service worker,
            // see if we can tease it out from common names.
            // NOTE: we can do this ONLY if we find a registration. Otherwise, we get false positives, e.g. https://msn.com/service-worker.js - even though MSN has no service worker registration.
            if (swUrl == serviceWorkerNameFallback)
            {
                await GetServiceWorkerUrlFromCommonFileNames(canonicalUri); // Still can't find sw reg? Take a guess at some common SW URLs.
            }

            var swUri    = GetAbsoluteUri(canonicalUri, swUrl);
            var swScript = await TryGetScriptContents(swUri, CancellationToken.None) ?? string.Empty;

            return(new ServiceWorkerDetectionResult
            {
                HasPushRegistration = swAnalyzer.CheckPushNotification(swScript),
                HasBackgroundSync = swAnalyzer.CheckBackgroundSync(swScript),
                HasPeriodicBackgroundSync = swAnalyzer.CheckPeriodicSync(swScript),
                NoServiceWorkerFoundDetails = swUrl == null ? "Couldn't find a service worker registration via HTML parsing" : string.Empty,
                Scope = swUrl != null ? canonicalUri : null,
                ServiceWorkerDetectionTimedOut = false,
                Url = swUri
            });
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Runs all service works checks.
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public async Task <ServiceWorkerDetectionResult> Run(Uri uri, bool cacheSuccessfulResults = true)
        {
            try
            {
                // First, see if we can find a service worker.
                using var serviceWorkerDetection = await DetectServiceWorker(uri);

                if (!serviceWorkerDetection.ServiceWorkerDetected)
                {
                    // No service worker? Punt.
                    return(new ServiceWorkerDetectionResult
                    {
                        ServiceWorkerDetectionTimedOut = serviceWorkerDetection.TimedOut,
                        NoServiceWorkerFoundDetails = serviceWorkerDetection.NoServiceWorkerFoundDetails
                    });
                }

                var swScope = await TryGetScope(serviceWorkerDetection.Page, uri);

                var swContents = await TryGetScriptContents(serviceWorkerDetection.Worker.Uri, CancellationToken.None);

                this.logger.LogInformation("Successfully detected service worker for {uri}", uri);
                return(new ServiceWorkerDetectionResult
                {
                    Url = serviceWorkerDetection.Worker.Uri,
                    Scope = swScope,
                    HasPushRegistration = await TryCheckPushRegistration(serviceWorkerDetection.Page, uri) || swCodeAnalyzer.CheckPushNotification(swContents),
                    HasBackgroundSync = swCodeAnalyzer.CheckBackgroundSync(swContents),
                    HasPeriodicBackgroundSync = swCodeAnalyzer.CheckPeriodicSync(swContents)
                });
            }
            catch (Exception error)
            {
                logger.LogError(error, "Error running all checks for {url}", uri);
                var isTimeout = error is TimeoutException || error is Polly.Timeout.TimeoutRejectedException || error.Message.Contains("timeout", StringComparison.OrdinalIgnoreCase);
                return(new ServiceWorkerDetectionResult
                {
                    NoServiceWorkerFoundDetails = "Error during Puppeteer service worker detection. " + error.Message,
                    ServiceWorkerDetectionTimedOut = isTimeout
                });
            }
        }