protected override void Initialize() { if (_aspNetHost == null) { lock (_lockObj) { if (_aspNetHost == null) { SandboxHelper.ExecuteInFullTrust( () => { var aspNetRootFolder = WorkerConfiguration.Current.AspNetRootFolder; if (!aspNetRootFolder.EndsWith("\\")) { aspNetRootFolder += "\\"; } CopySiteRoot(aspNetRootFolder); string virtualFolder = "/MvcPageAction/" + WorkerConfiguration.Current.ID + "/"; _aspNetHost = new AspNetHost(aspNetRootFolder, virtualFolder); try { _aspNetHost.Start(); } catch (Exception ex) { ex.ToString(); throw; } HostingEnvironment.RegisterVirtualPathProvider(new FakeVirtualPathProvider()); // we just do empty request to not existing file, so Asp.Net would initialize Http Application in full trust, and next request can be processed in sandbox StringWriter writer = new StringWriter(); SimpleWorkerRequest worker = new SimpleWorkerRequest("static/Warmup.aspx", null, writer); HttpRuntime.ProcessRequest(worker); writer.Flush(); string html = writer.ToString(); html.ToString(); }); } } } base.Initialize(); }
/// <summary> /// Init worker configuration in the new AppDomain /// </summary> public void InitWorkerSettings(Guid?workerId, string sandboxFolder, Type codeHelperType) { try { _sandboxFolder = sandboxFolder; SandboxHelper.ExecuteInFullTrust( () => { WorkerConfiguration.SetConfiguration(sandboxFolder, workerId); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; }); _codeHelperType = codeHelperType; ServicePointManager.DefaultConnectionLimit = 1; HttpWebRequest.DefaultMaximumResponseHeadersLength = 0; Initialize(); } catch { throw; } }
private void CodeHelper_RequestedConsoleInput(object sender, EventArgs eventArgs) { SandboxHelper.ExecuteInFullTrust(() => _executingThread.Abort(new ConsoleInputRequest())); }
public RunResult Run(RunOptsBase opts) { RunResult result = null; if (!CheckCodeBlock(opts, ref result)) { return(result); } // we should copy it before running, becuase it can be changed during execution var sandboxFolder = _sandboxFolder; var codeHelper = SandboxHelper.ExecuteInFullTrust(() => (CodeHelper)Activator.CreateInstance(_codeHelperType)); codeHelper.NuGetDllReferences = opts.NuGetDllReferences; codeHelper.StartingExecution += this.CodeHelper_StartingExecution; codeHelper.FinishedExecution += this.CodeHelper_FinishedExecution; codeHelper.RequestedConsoleInput += this.CodeHelper_RequestedConsoleInput; _executingThread = new Thread( () => { try { _runAt = DateTime.Now; result = this.ExecuteCodeBlock(opts, codeHelper); } finally { // in theory in can be null at this point if something bad happened.... if (result == null) { result = new RunResult() { FailureType = RunResultFailureType.FatalError, IsSuccess = false }; } result.Stats = SandboxHelper.ExecuteInFullTrust(() => GatherStatistics()); _compilationCompleted.Set(); } }); _executingThread.Start(); var monitoringTask = Task.Factory.StartNew(MonitorHealth, _tokenSource.Token); // wait for compilation. Just to be sure we have 15 seconds timeout _compilationCompleted.WaitOne(TimeSpan.FromSeconds(15)); // if something happened during compilation, then we fire _compilationCompleted on exit, and result will be filled, so we just need to return it if (result != null) { return(result); } // it will use some time for compilation // it can hungs for some unmanaged call like Console.ReadKey(), so we wait with timeout // we might need to rewrite it to ManualEvent that will be fired when CodeHelper starts execution _executingThread.Join(WorkerConfiguration.Current.ExecutionLimitTimeoutMs * 2); _tokenSource.Cancel(); // we can't move it to new method, as it can be executed via reflection SandboxHelper.ExecuteInFullTrust( () => { try { if (Directory.Exists(sandboxFolder)) { foreach (var file in Directory.EnumerateFiles(sandboxFolder, "*", SearchOption.AllDirectories)) { File.Delete(file); } } } catch { if (result != null) { result.SandboxUnloadReason = SandboxUnloadReason.ClearDirFailed; } } }); return(result); }