/// <summary> /// Boot-up is completed, this allows you to perform any other boot-up logic required for the application. /// Resolution is frozen so now they can be used to resolve instances. /// </summary> /// <param name="umbracoApplication"> /// The current <see cref="UmbracoApplicationBase"/> /// </param> /// <param name="applicationContext"> /// The Umbraco <see cref="ApplicationContext"/> for the current application. /// </param> protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { // Try and install the package. if (!ZoombracoBootstrapper.Install(umbracoApplication, applicationContext)) { return; } // Register custom routes. RouteBuilder.RegisterRoutes(RouteTable.Routes); // Ensure that the xml formatter does not interfere with API controllers. GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); // Clear out any CDN url requests on new image processing. // This ensures that when we update an image the cached CDN result for rendering is deleted. ImageProcessingModule.OnPostProcessing += (s, e) => { ZoombracoApplicationCache.RemoveItem(e.Context.Request.Unvalidated.RawUrl); }; // Assign indexer for full text searching. UmbracoContentIndexer indexProvider = ExamineManager.Instance.IndexProviderCollection[ZoombracoConstants.Search.IndexerName] as UmbracoContentIndexer; UmbracoExamineSearcher searchProvider = ExamineManager.Instance.SearchProviderCollection[ZoombracoConstants.Search.SearcherName] as UmbracoExamineSearcher; if (indexProvider == null) { throw new ArgumentOutOfRangeException($"{ZoombracoConstants.Search.IndexerName} is missing. Please check the ExamineSettings.config file."); } if (searchProvider == null) { throw new ArgumentOutOfRangeException($"{ZoombracoConstants.Search.SearcherName} is missing. Please check the ExamineSettings.config file."); } UmbracoHelper helper = new UmbracoHelper(UmbracoContext.Current); ContentHelper contentHelper = new ContentHelper(helper); indexProvider.GatheringNodeData += (sender, e) => this.GatheringNodeData(sender, e, helper, contentHelper, applicationContext); // Register the VortoPropertyAttribute as the default property processor so that any property can be made multilingual. Ditto.RegisterDefaultProcessorType <VortoPropertyAttribute>(); }
/// <summary> /// Gets the ImageProcessor Url from the CDN by the crop alias (from the "umbracoFile" property alias) /// on the <see cref="Image"/> item. /// </summary> /// <param name="image">The <see cref="Image"/> this method extends.</param> /// <param name="alias">The crop alias <example>thumbnail</example>.</param> /// <param name="useCropDimensions">Whether to use the the crop dimensions to retrieve the url.</param> /// <param name="useFocalPoint">Whether to use the focal point.</param> /// <param name="quality">The quality of jpeg images.</param> /// <param name="parameters">Any additional querystring parameters we need to add or replace.</param> /// <returns>The <see cref="ImageProcessor.Web"/> Url. </returns> public static string GetCdnCropUrl(this Image image, string alias, bool useCropDimensions = true, bool useFocalPoint = true, int quality = 85, NameValueCollection parameters = null) { if (HttpContext.Current == null) { return(GetCropUrl(image, alias, useCropDimensions, useFocalPoint, quality, parameters)); } // Piece together the full qualified url. We use this to make a head requests that ImageProcessor.Web will intercept and // route to the correct location. We'll cache that for subsequent requests. string domain = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority); string cropUrl = GetCropUrl(image, alias, useCropDimensions, useFocalPoint, quality, parameters); string key = $"{domain}{cropUrl}"; string result = cropUrl; int timeout = ZoombracoConfiguration.Instance.ImageCdnRequestTimeout; // We don't want timeouts or errors causing constant slowdown of the page rendering so we always cache either the CDN or non CDN result. // We do, however log extensively so that we can see why things are going wrong. return((string)ZoombracoApplicationCache.GetOrAddItem( key, () => { HttpWebResponse response = null; try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(key); request.Method = "HEAD"; request.Timeout = timeout; response = (HttpWebResponse)request.GetResponse(); HttpStatusCode responseCode = response.StatusCode; if (responseCode == HttpStatusCode.OK) { result = response.ResponseUri.AbsoluteUri; } } catch (WebException ex) { // If you are testing against localhost then this will happen. if (ex.Response == null) { if (ex.Status == WebExceptionStatus.Timeout) { // Warn but about the timeout. LogHelper.Warn <Image>($"CDN url request for {key} timed out. Consider adjusting the {ZoombracoConstants.Configuration.ImageCdnRequestTimeout} setting in the Web.Config."); } return GetCropUrl(image, alias, useCropDimensions, useFocalPoint, quality, parameters); } // ImageProcessor.Web will handle returning a response from the cache catering for different // error codes from the cache providers. We'll just check for a url. response = (HttpWebResponse)ex.Response; if (response.ResponseUri != null) { result = response.ResponseUri.AbsoluteUri; } else { // Something is terribly wrong here. LogHelper.Error <Image>($"Cannot get CDN url for {key}.", ex); } } finally { response?.Dispose(); } return result; })); }