/// <summary> /// /// </summary> /// <param name="job"></param> /// <param name="stage"></param> /// <param name="regex"></param> /// <param name="priority"></param> /// <param name="request"></param> /// <returns></returns> public static int Watch(IJob job, PipeLineStages stage, Regex regex, int priority, Func <int, HttpApplication, WatchResponse> request) { Environ environ = null; if (EnvironLock.Write(() => { if (!Environs.TryGetValue(job.Environment.SortOrder, out environ)) { Environs.Add(job.Environment.SortOrder, environ = new Environ(job.Environment)); } })) { return(EnvironLock.Read(() => { return environ.WatchLocks[(int)stage].Write(() => { var watchList = environ.Watchers[(int)stage]; var count = Interlocked.Increment(ref _requestCount); EnvironHasWatches[(int)stage] = true; watchList.Add(new Watcher { Priority = priority, AppId = job.App.Id, Regex = regex, Request = request }); watchList.Sort(new WatchComparer()); return count; }); })); } return(-1); }
// ReSharper disable once UnusedParameter.Local private WatchResponse.Cycles ExecuteResponse(int environmentId, Watcher watch, WatchResponse response, HttpApplication application) { if (response.Transfer == null) { return(response.Cycle); } if (response.Transfer.TransferType == TransferTypes.PlayDead) { application.Context.Response.Close(); return(WatchResponse.Cycles.Stop); } if (!MakeSureAllUrlExceptionsHaveBeenCalculated()) { return(WatchResponse.Cycles.Error); } var urlExeceptionResult = UrlExceptionLock.Read(() => { foreach (var exception in UrlExceptions.Where(x => x.EnvironmentId == environmentId)) { if (exception.Regex != null && (exception.Regex.IsMatch(application.Context.Request.Url.PathAndQuery) || exception.Regex.IsMatch(application.Context.Request.Url.AbsoluteUri))) { return(new Tuple <bool, WatchResponse.Cycles?>(true, WatchResponse.Cycles.Continue)); } if (exception.CalculatedUrl && (exception.CalculatedUrlWithoutSlash.Equals(application.Context.Request.Url.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) || exception.CalculatedUrlWithSlash.Equals(application.Context.Request.Url.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) || exception.CalculatedUrlWithoutSlash.Equals(application.Context.Request.Url.AbsoluteUri, StringComparison.InvariantCultureIgnoreCase) || exception.CalculatedUrlWithSlash.Equals(application.Context.Request.Url.AbsoluteUri, StringComparison.InvariantCultureIgnoreCase))) { return(new Tuple <bool, WatchResponse.Cycles?>(true, WatchResponse.Cycles.Continue)); } } return(new Tuple <bool, WatchResponse.Cycles?>(false, null)); }); if (urlExeceptionResult == null) { return(WatchResponse.Cycles.Error); } if (urlExeceptionResult.Item1 && urlExeceptionResult.Item2 != null) { return((WatchResponse.Cycles)urlExeceptionResult.Item2); } var url = new UmbracoUrlService().Url(response.Transfer.Url); switch (response.Transfer.TransferType) { case TransferTypes.Redirect: application.Context.Response.Redirect(url, true); return(WatchResponse.Cycles.Stop); case TransferTypes.Rewrite: application.Context.RewritePath(url, string.Empty, string.Empty); return(WatchResponse.Cycles.Restart); } return(WatchResponse.Cycles.Error); }
private bool ProcessRequest(PipeLineStages stage, int count, HttpApplication application) { if (EnvironHasWatches[(int)stage] == false) { return(true); } return(EnvironLock.Read(() => { if (!Environs.Any()) { return true; } #if TRACE Debug.WriteLine(stage.ToString() + " : " + application.Request.Url.AbsoluteUri); #endif var uri = application.Context.Request.Url.AbsoluteUri; string uriWithoutDomain = null; foreach (var environ in Environs) { string filePath; if (environ.Value.Domains == null) { if (uriWithoutDomain == null) { uriWithoutDomain = application.Context.Request.Url.LocalPath; } filePath = uriWithoutDomain; } else { var domain = environ.Value.Domains.FirstOrDefault(x => uri.StartsWith(x, StringComparison.InvariantCultureIgnoreCase)); if (domain != null) { filePath = uri.Substring(domain.Length - 1); } else { continue; } } if (environ.Value.WatchLocks[(int)stage].Read <bool?>(() => { var ignores = UrlIgnoresLock.Read(() => { return UrlIgnores.Where(x => x.EnvironmentId == environ.Value.Id && x.Regex.IsMatch(filePath)).Select(x => x.AppId); }); foreach (var watch in environ.Value.Watchers[(int)stage]) { if ((watch.Regex != null && !watch.Regex.IsMatch(filePath)) || ignores.Any(x => x != watch.AppId)) { continue; } #if TRACE var debug = $"{uri}: Watcher({environ.Value.Name}, {watch.AppId}, {watch.Priority}, {watch.Regex}) "; #endif var watchResponse = watch.Request(count, application); if (watchResponse.Transfer != null) { #if TRACE debug += "by transfer then "; #endif watchResponse.Cycle = ExecuteTransfer(environ.Value.Id, watch, watchResponse, application); } switch (watchResponse.Cycle) { case WatchResponse.Cycles.Kill: #if TRACE Debug.WriteLine(debug + "Kill"); #endif application.Response.End(); //application.CompleteRequest(); return true; case WatchResponse.Cycles.Stop: #if TRACE Debug.WriteLine(debug + "Stop"); #endif return true; case WatchResponse.Cycles.Restart: #if TRACE Debug.WriteLine(debug + "Restart"); #endif return false; case WatchResponse.Cycles.Error: #if TRACE Debug.WriteLine(debug + "Error"); #endif application.Context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; application.CompleteRequest(); break; #if TRACE default: Debug.WriteLine(debug + "Continue"); break; #endif // If WatchCycle.Continue we do nothing } } return true; }) == false) { return false; } if (!environ.Value.ContinueProcessing) { break; } } return true; })); }
/// <summary> /// Gets the job for a given id /// </summary> /// <param name="id">The desired Id</param> /// <returns></returns> public IJob Job(int id) { return(JobLock.Read(() => Jobs.Value[id].DeepCopy())); }
// ReSharper disable once UnusedParameter.Local private WatchResponse.Cycles ExecuteTransfer(int environmentId, Watcher watch, WatchResponse response, HttpApplication application) { if (response.Transfer.TransferType == TransferTypes.PlayDead) { application.Context.Response.Close(); return(WatchResponse.Cycles.Stop); } if (!ExceptionsProcess()) { return(WatchResponse.Cycles.Error); } if (UrlExceptionLock.Read(() => { var requestUrl = application.Context.Request.Url; foreach (var exception in UrlExceptions.Where(x => x.EnvironmentId == environmentId)) { if (exception.Regex != null && (exception.Regex.IsMatch(requestUrl.PathAndQuery) || exception.Regex.IsMatch(requestUrl.AbsoluteUri))) { return(true); } if (exception.CalculatedUrl && (exception.CalculatedUrlWithoutSlash.Equals(requestUrl.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) || exception.CalculatedUrlWithSlash.Equals(requestUrl.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) || exception.CalculatedUrlWithoutSlash.Equals(requestUrl.AbsoluteUri, StringComparison.InvariantCultureIgnoreCase) || exception.CalculatedUrlWithSlash.Equals(requestUrl.AbsoluteUri, StringComparison.InvariantCultureIgnoreCase))) { return(true); } } return(false); })) { return(WatchResponse.Cycles.Continue); } var urlService = new UmbracoUrlService(); var url = urlService.Url(response.Transfer.Url); switch (response.Transfer.TransferType) { case TransferTypes.Redirect: application.Context.Response.Redirect(url, true); return(WatchResponse.Cycles.Stop); case TransferTypes.TransferRequest: application.Server.TransferRequest(url, true); return(WatchResponse.Cycles.Stop); case TransferTypes.TransmitFile: // Request is for a css etc. file, transmit the file and set correct mime type var mimeType = MimeMapping.GetMimeMapping(url); application.Response.ContentType = mimeType; application.Response.TransmitFile(application.Server.MapPath(url)); return(WatchResponse.Cycles.Kill); case TransferTypes.Rewrite: if (urlService.IsUmbracoUrl(response.Transfer.Url)) { RewritePage(application, url); return(WatchResponse.Cycles.Kill); } application.Context.RewritePath(url); return(WatchResponse.Cycles.Restart); } return(WatchResponse.Cycles.Error); }