Пример #1
0
        internal static PreservedAssemblyEntry GetPreservedAssemblyEntry(HttpContext context,
                                                                         string virtualPath, bool fApplicationFile)
        {
            Debug.Trace("PreservedAssemblyEntry", "Checking for " + virtualPath);

            EnsureFirstTimeInit(context);

            string baseVirtualDir = UrlPath.GetDirectory(virtualPath);

            // No batching for global.asax
            if (!fApplicationFile)
            {
                BatchCompileDirectory(context, baseVirtualDir);
            }

            PreservedAssemblyEntry entry = new PreservedAssemblyEntry(context,
                                                                      virtualPath, fApplicationFile);

            // Try to load the entry.  It must exist, and be up to date
            if (!entry.LoadDataFromFile(fApplicationFile))
            {
                return(null);
            }

            return(entry);
        }
Пример #2
0
        private static void CacheResults(HttpContext context, BatchCompilationEntry pce)
        {
            PreservedAssemblyEntry entry = new PreservedAssemblyEntry(context,
                                                                      pce.VirtualPath,
                                                                      false /*fApplicationFile*/, null /*assembly*/, pce.TypeObject, pce.FileDependencies);

            entry.SaveDataToFile(true /*fBatched*/);
        }
Пример #3
0
        private void CacheEntryToDisk(SourceCompilerCachedEntry scce)
        {
            // Always add the main compiled file itself as a source dependency
            AddSourceDependency(_physicalPath);

            PreservedAssemblyEntry entry = new PreservedAssemblyEntry(_context,
                                                                      _virtualPath, false /*fApplicationFile*/, scce._assembly,
                                                                      scce._type, _sourceDependencies);

            entry.SaveDataToFile(false /*fBatched*/);
        }
Пример #4
0
        private SourceCompilerCachedEntry GetCachedEntry()
        {
            // First, try to get it from the in-memory cache
            SourceCompilerCachedEntry scce = (SourceCompilerCachedEntry)_cache.Get(_cacheKey);

            if (scce != null)
            {
                Debug.Trace("Template", "Compiled source code found in cache (" + _virtualPath + "," + scce._assembly.GetName().Name + ")");
                return(scce);
            }

            Debug.Trace("Template", "Compiled source code not found in cache (" + _virtualPath + ")");

            _physicalPath = _context.Request.MapPath(_virtualPath);

            // Before going further, make sure the file at least exists (ASURT 76995)
            Stream str = File.OpenRead(_physicalPath);

            str.Close();

            // Try to get it from the preserved assembly cache
            PreservedAssemblyEntry entry = PreservedAssemblyEntry.GetPreservedAssemblyEntry(
                _context, _virtualPath, false /*fApplicationFile*/);

            // If it's not there, fail
            if (entry == null)
            {
                return(null);
            }


            // We found it.  Cache it in-memory

            _utcStart = DateTime.UtcNow;

            scce           = new SourceCompilerCachedEntry();
            scce._assembly = entry.Assembly;
            scce._type     = entry.ObjectType;

            CacheEntryToMemory(scce);

            // Return it
            return(scce);
        }
Пример #5
0
            internal void BatchCompileDirectory(Object unused)
            {
                _thread = Thread.CurrentThread;

                try {
                    using (new HttpContextWrapper(_context)) {
                        // Set some thread data to remember that this is a batch compilation thread
                        CallContext.SetData(CallContextBatchCompilerSlotName, this);

                        // Do the impersonation
                        _context.Impersonation.Start(true /*forGlobalCode*/, false /*throwOnError*/);

                        Debug.Trace("PreservedAssemblyEntry", "Starting batch compilation of directory " + _baseVirtualDir);
                        try {
                            CodeDomBatchManager.BatchCompile(_baseVirtualDir, _context);
                        }

                        // eat exceptions and fail batch compilation silently
        #if DBG
                        catch (Exception e) {
                            if (e is ThreadAbortException)
                            {
                                Debug.Trace("PreservedAssemblyEntry", "Batch compilation of directory " + _baseVirtualDir + " was aborted.");
                            }
                            else
                            {
                                Debug.Trace("PreservedAssemblyEntry", "Batch compilation of directory " + _baseVirtualDir + " failed.");
                            }

                            Util.DumpExceptionStack(e);
                            return;
                        }
        #else
                        catch (Exception) {
                            return;
                        }
        #endif

                        finally {
                            _context.Impersonation.Stop();

                            CallContext.SetData(CallContextBatchCompilerSlotName, null);

                            if (WasAddedToBackgroundThreadsList)
                            {
                                PreservedAssemblyEntry.RemoveBackgroundBatchCompilation(this);
                            }
                        }
                    }

                    // Batching was performed successfully
                    Debug.Trace("PreservedAssemblyEntry", "Batch compilation of directory " + _baseVirtualDir + " was successful.");
                    _success = true;
                }
                catch (ThreadAbortException) {
                    // to consume thread abort exception (so that the thread pool doesn't know)
                    Thread.ResetAbort();
                }
                catch { throw; } // Prevent Exception Filter Security Issue (ASURT 122826)
                finally {
                    _thread = null;
                    _event.Set();
                }
            }
Пример #6
0
        private SourceCompilerCachedEntry CompileAndCache()
        {
            BaseCompiler.GenerateCompilerParameters(_compilParams);

            // Get the set of config assemblies for our context
            IDictionary configAssemblies = CompilationConfiguration.GetAssembliesFromContext(_context);

            if (_assemblies == null)
            {
                _assemblies = new Hashtable();
            }

            // Add all the assemblies from the config object to the hashtable
            // This guarantees uniqueness
            if (configAssemblies != null)
            {
                foreach (Assembly asm in configAssemblies.Values)
                {
                    _assemblies[asm] = null;
                }
            }

            // And the assembly of the application object (global.asax)
            _assemblies[HttpApplicationFactory.ApplicationType.Assembly] = null;

            // Now add all the passed in assemblies to the compilParams
            foreach (Assembly asm in _assemblies.Keys)
            {
                _compilParams.ReferencedAssemblies.Add(Util.GetAssemblyCodeBase(asm));
            }

            // Instantiate the Compiler
            CodeDomProvider codeProvider = (CodeDomProvider)HttpRuntime.CreatePublicInstance(_compilerType);
            ICodeCompiler   compiler     = codeProvider.CreateCompiler();
            CompilerResults results;

            // Compile the source file or string into an assembly

            try {
                _utcStart = DateTime.UtcNow;

                // If we have a source file, read it as a string and compile it.  This way,
                // the compiler never needs to read the original file, avoiding permission
                // issues (see ASURT 112718)
                if (_sourceString == null)
                {
                    _sourceString = Util.StringFromFile(_physicalPath, _context);

                    // Put in some context so that the file can be debugged.
                    _linePragma = new CodeLinePragma(_physicalPath, 1);
                }

                CodeSnippetCompileUnit snippetCompileUnit = new CodeSnippetCompileUnit(_sourceString);
                snippetCompileUnit.LinePragma = _linePragma;
                results = compiler.CompileAssemblyFromDom(_compilParams, snippetCompileUnit);
            }
            catch (Exception e) {
                throw new HttpUnhandledException(HttpRuntime.FormatResourceString(SR.CompilationUnhandledException, codeProvider.GetType().FullName), e);
            }

            BaseCompiler.ThrowIfCompilerErrors(results, codeProvider,
                                               null, _physicalPath, _sourceString);

            SourceCompilerCachedEntry scce = new SourceCompilerCachedEntry();

            // Load the assembly
            scce._assembly = results.CompiledAssembly;

            // If we have a type name, load the type from the assembly
            if (_typeName != null)
            {
                scce._type = scce._assembly.GetType(_typeName);

                // If the type could not be loaded, delete the assembly and rethrow
                if (scce._type == null)
                {
                    PreservedAssemblyEntry.RemoveOutOfDateAssembly(scce._assembly.GetName().Name);

                    // Remember why we failed
                    _typeNotFoundInAssembly = true;

                    throw new HttpException(
                              HttpRuntime.FormatResourceString(SR.Could_not_create_type, _typeName));
                }
            }

            CacheEntryToDisk(scce);
            CacheEntryToMemory(scce);

            return(scce);
        }