public void OnActionExecuting(ActionExecutingContext context)
            {
                if (!context.ActionArguments.Any())
                {
                    return;
                }
                var          bundleFile = context.ActionArguments.First().Value as BundleRequestModel;
                ICacheBuster cacheBuster;
                RequestModel file = null;

                if (bundleFile != null)
                {
                    cacheBuster = _cacheBusterResolver.GetCacheBuster(bundleFile.Bundle.GetBundleOptions(_bundleManager, bundleFile.Debug).GetCacheBusterType());
                }
                else
                {
                    //the default for any dynamically (non bundle) file is the default bundle options in production
                    cacheBuster = _cacheBusterResolver.GetCacheBuster(_bundleManager.GetDefaultBundleOptions(false).GetCacheBusterType());
                    file        = context.ActionArguments.First().Value as RequestModel;
                }

                if (file != null)
                {
                    FileResult result;
                    DateTime   lastWrite;
                    if (TryGetCachedCompositeFileResult(_fileSystemHelper, cacheBuster, file.FileKey, file.Compression, file.Mime, out result, out lastWrite))
                    {
                        file.LastFileWriteTime = lastWrite;
                        context.Result         = result;
                    }
                }
            }
Ejemplo n.º 2
0
        private async Task ProcessFileImpl(IWebFile file, BundleOptions bundleOptions, BundleContext bundleContext)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            var extension = Path.GetExtension(file.FilePath);

            var fileWatchEnabled = bundleOptions?.FileWatchOptions.Enabled ?? false;

            Lazy <IFileInfo> fileInfo;
            var cacheBuster = bundleOptions != null
                ? _cacheBusterResolver.GetCacheBuster(bundleOptions.GetCacheBusterType())
                : _cacheBusterResolver.GetCacheBuster(_bundleManager.GetDefaultBundleOptions(false).GetCacheBusterType()); //the default for any dynamically (non bundle) file is the default bundle options in production

            var cacheFile = _fileSystemHelper.GetCacheFilePath(file, fileWatchEnabled, extension, cacheBuster, out fileInfo);

            var exists = File.Exists(cacheFile);

            //check if it's in cache
            if (exists)
            {
                _logger.LogDebug($"File already in cache '{file.FilePath}', type: {file.DependencyType}, cacheFile: {cacheFile}, watching? {fileWatchEnabled}");
            }
            else
            {
                if (file.Pipeline.Processors.Count > 0)
                {
                    _logger.LogDebug($"Processing file '{file.FilePath}', type: {file.DependencyType}, cacheFile: {cacheFile}, watching? {fileWatchEnabled} ...");
                    var contents = await _fileSystemHelper.ReadContentsAsync(fileInfo.Value);

                    var watch = new Stopwatch();
                    watch.Start();
                    //process the file
                    var processed = await file.Pipeline.ProcessAsync(new FileProcessContext(contents, file, bundleContext));

                    watch.Stop();
                    _logger.LogDebug($"Processed file '{file.FilePath}' in {watch.ElapsedMilliseconds}ms");
                    //save it to the cache path
                    await _fileSystemHelper.WriteContentsAsync(cacheFile, processed);
                }
                else
                {
                    // we can just copy the the file as-is to the cache file
                    _fileSystemHelper.CopyFile(fileInfo.Value.PhysicalPath, cacheFile);
                }
            }

            //If file watching is enabled, then watch it - this is regardless of whether the cache file exists or not
            // since after app restart if there's already a cache file, we still want to watch the file set
            if (fileWatchEnabled)
            {
                // watch this file for changes, if the file is already watched this will do nothing
                _fileSystemHelper.Watch(file, fileInfo.Value, bundleOptions, FileModified);
            }
        }
Ejemplo n.º 3
0
        public BundleRequestModel(IUrlManager urlManager, IActionContextAccessor accessor, IRequestHelper requestHelper, IBundleManager bundleManager, CacheBusterResolver cacheBusterResolver)
            : base("bundle", urlManager, accessor, requestHelper)
        {
            //TODO: Pretty sure if we want to control the caching of the file, we'll have to retrieve the bundle definition here
            // In reality we'll need to do that anyways if we want to support load balancing!
            // https://github.com/Shazwazza/Smidge/issues/17


            if (!ParsedPath.Names.Any())
            {
                throw new InvalidOperationException("The bundle route value does not contain a bundle name");
            }

            FileKey = ParsedPath.Names.Single();

            Bundle bundle;

            if (!bundleManager.TryGetValue(FileKey, out bundle))
            {
                throw new InvalidOperationException("No bundle found with key " + FileKey);
            }
            Bundle = bundle;

            CacheBuster = cacheBusterResolver.GetCacheBuster(bundle.GetBundleOptions(bundleManager, Debug).GetCacheBusterType());
        }
Ejemplo n.º 4
0
        public CompositeFileModel(IHasher hasher, IUrlManager urlManager, IActionContextAccessor accessor, IRequestHelper requestHelper, IBundleManager bundleManager, CacheBusterResolver cacheBusterResolver)
            : base("file", urlManager, accessor, requestHelper)
        {
            //Creates a single hash of the full url (which can include many files)
            FileKey = hasher.Hash(string.Join(".", ParsedPath.Names));

            CacheBuster = cacheBusterResolver.GetCacheBuster(bundleManager.GetDefaultBundleOptions(false).GetCacheBusterType());
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Generates the URLs for a given bundle
        /// </summary>
        /// <param name="bundleName"></param>
        /// <param name="fileExt"></param>
        /// <param name="debug"></param>
        /// <returns></returns>
        private IEnumerable <string> GenerateBundleUrlsAsync(string bundleName, string fileExt, bool debug)
        {
            //TODO: We should cache this, but problem is how do we do that with file watchers enabled? We'd still have to lookup the bundleOptions
            // or maybe we just cache when file watchers are not enabled - probably the way to do it

            var bundle = _bundleManager.GetBundle(bundleName);

            if (bundle == null)
            {
                throw new BundleNotFoundException(bundleName);
            }

            if (bundle.Files.Count == 0)
            {
                return(Enumerable.Empty <string>());
            }

            var result = new List <string>();

            //get the bundle options from the bundle if they have been set otherwise with the defaults
            var bundleOptions = bundle.GetBundleOptions(_bundleManager, debug);

            //if not processing as composite files, then just use their native file paths
            if (!bundleOptions.ProcessAsCompositeFile)
            {
                var files = _fileSetGenerator.GetOrderedFileSet(bundle,
                                                                _processorFactory.CreateDefault(
                                                                    //the file type in the bundle will always be the same
                                                                    bundle.Files[0].DependencyType));
                result.AddRange(files.Select(d => d.FilePath));
                return(result);
            }

            var cacheBuster = _cacheBusterResolver.GetCacheBuster(bundleOptions.GetCacheBusterType());

            var url = _urlManager.GetUrl(bundleName, fileExt, debug, cacheBuster);

            if (!string.IsNullOrWhiteSpace(url))
            {
                result.Add(url);
            }

            return(result);
        }
Ejemplo n.º 6
0
        private async Task ProcessFileImpl(IWebFile file, BundleOptions bundleOptions, BundleContext bundleContext)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            var extension = Path.GetExtension(file.FilePath);

            var fileWatchEnabled = bundleOptions?.FileWatchOptions.Enabled ?? false;

            Lazy <IFileInfo> fileInfo;
            var cacheBuster = bundleOptions != null
                ? _cacheBusterResolver.GetCacheBuster(bundleOptions.GetCacheBusterType())
                : _cacheBusterResolver.GetCacheBuster(_bundleManager.GetDefaultBundleOptions(false).GetCacheBusterType()); //the default for any dynamically (non bundle) file is the default bundle options in production

            var cacheFile = _fileSystemHelper.GetCacheFilePath(file, fileWatchEnabled, extension, cacheBuster, out fileInfo);

            //check if it's in cache
            if (!File.Exists(cacheFile))
            {
                var contents = await _fileSystemHelper.ReadContentsAsync(fileInfo.Value);

                //process the file
                var processed = await file.Pipeline.ProcessAsync(new FileProcessContext(contents, file, bundleContext));

                //save it to the cache path
                await _fileSystemHelper.WriteContentsAsync(cacheFile, processed);
            }

            //If file watching is enabled, then watch it - this is regardless of whether the cache file exists or not
            // since after app restart if there's already a cache file, we still want to watch the file set
            if (fileWatchEnabled)
            {
                // watch this file for changes, if the file is already watched this will do nothing
                _fileSystemHelper.Watch(file, fileInfo.Value, bundleOptions, FileModified);
            }
        }
Ejemplo n.º 7
0
        private static void FileWatchOptions_FileModified(IBundleManager bundleManager, CacheBusterResolver cacheBusterResolver, string bundleName, Bundle bundle, bool debug, FileWatchEventArgs e)
        {
            var cacheBuster = cacheBusterResolver.GetCacheBuster(bundle.GetBundleOptions(bundleManager, debug).GetCacheBusterType());

            //this file is part of this bundle, so the persisted processed/combined/compressed  will need to be
            // invalidated/deleted/renamed
            foreach (var compressionType in new[] { CompressionType.deflate, CompressionType.gzip, CompressionType.none })
            {
                var compFilePath = e.FileSystemHelper.GetCurrentCompositeFilePath(cacheBuster, compressionType, bundleName);
                if (File.Exists(compFilePath))
                {
                    File.Delete(compFilePath);
                }
            }
        }