/// <summary> /// Get markup for a specific campaign /// </summary> /// <param name="campaignContentZip"></param> /// <param name="localization"></param> /// <returns></returns> public CampaignContentMarkup GetCampaignContentMarkup(CampaignContentZIP campaignContentZip, Localization localization) { StaticContentItem zipItem = GetZipItem(campaignContentZip, localization); CampaignContentMarkup campaignContentMarkup; //SiteConfiguration.CacheProvider.TryGet<CampaignContentMarkup>(campaignContentZip.Id, "CampaignContent", out campaignContentMarkup); string cacheKey = GetMarkupCacheKey(campaignContentZip.Id, localization); cachedMarkup.TryGetValue(cacheKey, out campaignContentMarkup); string campaignBaseDir = GetBaseDir(localization, campaignContentZip.Id); if (campaignContentMarkup == null || !Directory.Exists(campaignBaseDir) || Directory.GetFiles(campaignBaseDir).Length == 0) { Log.Info("Extracting campaign " + campaignContentZip.Id + ", last modified = " + zipItem.LastModified); ExtractZip(zipItem, campaignBaseDir, zipItem.LastModified); campaignContentMarkup = GetMarkup(campaignBaseDir); campaignContentMarkup.LastModified = zipItem.LastModified; //SiteConfiguration.CacheProvider.Store<CampaignContentMarkup>(campaignContentZip.Id, "CampaignContent", campaignContentMarkup); cachedMarkup[cacheKey] = campaignContentMarkup; } else if (campaignContentMarkup == null) { campaignContentMarkup = GetMarkup(campaignBaseDir); campaignContentMarkup.LastModified = zipItem.LastModified; cachedMarkup[cacheKey] = campaignContentMarkup; } return(campaignContentMarkup); }
/// <summary> /// Event handler that gets triggered just before the ASP.NET Request Handler gets executed. /// </summary> /// <param name="sender">The <see cref="HttpApplication"/> sending the event.</param> /// <param name="eventArgs">The event arguments.</param> private static void OnPreRequestHandlerExecute(object sender, EventArgs eventArgs) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; HttpRequest request = context.Request; HttpResponse response = context.Response; string urlPath = request.Url.AbsolutePath; DateTime ifModifiedSince = Convert.ToDateTime(request.Headers["If-Modified-Since"]); using (new Tracer(sender, eventArgs, urlPath, ifModifiedSince)) { Localization localization = WebRequestContext.Localization; string staticsRootUrl = SiteConfiguration.GetLocalStaticsUrl(localization.LocalizationId); urlPath = urlPath.StartsWith("/" + staticsRootUrl) ? urlPath.Substring(staticsRootUrl.Length + 1) : urlPath; if (!localization.IsStaticContentUrl(urlPath)) { // Not a static content item; continue the HTTP pipeline. return; } try { using (StaticContentItem staticContentItem = SiteConfiguration.ContentProvider.GetStaticContentItem(urlPath, localization)) { DateTime lastModified = staticContentItem.LastModified; if (lastModified <= ifModifiedSince.AddSeconds(1)) { Log.Debug("Static content item last modified at {0} => Sending HTTP 304 (Not Modified).", lastModified); response.StatusCode = (int)HttpStatusCode.NotModified; response.SuppressContent = true; } else { // Items with a versioned URL can be cached long-term, because the URL will change if needed. bool isVersionedUrl = context.Items.Contains(IsVersionedUrlContextItem); TimeSpan maxAge = isVersionedUrl ? new TimeSpan(7, 0, 0, 0) : new TimeSpan(0, 1, 0, 0); // 1 Week or 1 Hour response.Cache.SetLastModified(lastModified); // Allows the browser to do an If-Modified-Since request next time response.Cache.SetCacheability(HttpCacheability.Public); // Allow caching response.Cache.SetMaxAge(maxAge); response.Cache.SetExpires(DateTime.UtcNow.Add(maxAge)); response.ContentType = staticContentItem.ContentType; staticContentItem.GetContentStream().CopyTo(response.OutputStream); } } } catch (DxaItemNotFoundException ex) { SendNotFoundResponse(ex.Message, response); } catch (Exception ex) { // Other exceptions: log and let ASP.NET handle them Log.Error(ex); throw; } // Terminate the HTTP pipeline. application.CompleteRequest(); } }
[TestMethod, Ignore] // TODO: It seems that DD4T can't deal with internationalized URLs. public void GetStaticContentItem_InternationalizedUrl_Success() { string testStaticContentItemUrlPath = TestFixture.Tsi1278StaticContentItemUrlPath; StaticContentItem staticContentItem = SiteConfiguration.ContentProvider.GetStaticContentItem(testStaticContentItemUrlPath, TestFixture.ParentLocalization); Assert.IsNotNull(staticContentItem, "staticContentItem"); }
/// <summary> /// Event handler that gets triggered just before the ASP.NET Request Handler gets executed. /// </summary> /// <param name="sender">The <see cref="HttpApplication"/> sending the event.</param> /// <param name="eventArgs">The event arguments.</param> private static void OnPreRequestHandlerExecute(object sender, EventArgs eventArgs) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; HttpRequest request = context.Request; HttpResponse response = context.Response; string urlPath = request.Url.AbsolutePath; DateTime ifModifiedSince = Convert.ToDateTime(request.Headers["If-Modified-Since"]); using (new Tracer(sender, eventArgs, urlPath, ifModifiedSince)) { Localization localization = WebRequestContext.Localization; string staticsRootUrl = localization.BinaryCacheFolder.Replace("\\", "/"); urlPath = urlPath.StartsWith("/" + staticsRootUrl) ? urlPath.Substring(staticsRootUrl.Length + 1) : urlPath; if (!localization.IsStaticContentUrl(urlPath)) { // Not a static content item; continue the HTTP pipeline. return; } try { using (StaticContentItem staticContentItem = SiteConfiguration.ContentProvider.GetStaticContentItem(urlPath, localization)) { // Items with a versioned URL can be cached long-term, because the URL will change if needed. bool isVersionedUrl = context.Items.Contains(IsVersionedUrlContextItem); DateTime lastModified = staticContentItem.LastModified; var contentType = staticContentItem.ContentType; SetResponseProperties(new HttpResponseWrapper(response), lastModified, ifModifiedSince, contentType, localization, isVersionedUrl); if (!response.SuppressContent) { staticContentItem.GetContentStream().CopyTo(response.OutputStream); staticContentItem.GetContentStream().Close(); } } } catch (DxaItemNotFoundException ex) { SendNotFoundResponse(ex.Message, response); } catch (Exception ex) { // Other exceptions: log and let ASP.NET handle them Log.Error(ex); throw; } // Terminate the HTTP pipeline. application.CompleteRequest(); } }
public virtual ActionResult Binary(int publicationId, int binaryId) { try { StaticContentItem content = ContentProviderExt.GetStaticContentItem(binaryId, Localization); return(new FileStreamResult(content.GetContentStream(), content.ContentType)); } catch (Exception ex) { return(ServerError(ex)); } }
public virtual ActionResult Binary(int publicationId, int binaryId, params string[] rest) { try { var docsLocalization = new DocsLocalization(publicationId); StaticContentItem content = ContentProviderExt.GetStaticContentItem(binaryId, docsLocalization); return(new FileStreamResult(content.GetContentStream(), content.ContentType)); } catch (Exception ex) { return(ServerError(ex)); } }
public void GetStaticContentItem_InternationalizedUrl_Success() // See TSI-1278 { string testStaticContentItemUrlPath = TestLocalization.GetAbsoluteUrlPath( string.Format(TestFixture.Tsi1278StaticContentItemRelativeUrlPath, TestLocalization.Id) ); using (StaticContentItem testStaticContentItem = TestContentProvider.GetStaticContentItem(testStaticContentItemUrlPath, TestLocalization)) { Assert.IsNotNull(testStaticContentItem, "testStaticContentItem"); Assert.AreEqual("image/jpeg", testStaticContentItem.ContentType, "testStaticContentItem.ContentType"); Stream contentStream = testStaticContentItem.GetContentStream(); Assert.IsNotNull(contentStream, "contentStream"); Assert.AreEqual(192129, contentStream.Length, "contentStream.Length"); } }
/// <summary> /// Event handler that gets triggered just before the ASP.NET Request Handler gets executed. /// </summary> /// <param name="sender">The <see cref="HttpApplication"/> sending the event.</param> /// <param name="eventArgs">The event arguments.</param> private static void OnPreRequestHandlerExecute(object sender, EventArgs eventArgs) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; HttpRequest request = context.Request; HttpResponse response = context.Response; string urlPath = request.Url.AbsolutePath; DateTime ifModifiedSince = Convert.ToDateTime(request.Headers["If-Modified-Since"]); using (new Tracer(sender, eventArgs, urlPath, ifModifiedSince)) { Localization localization = WebRequestContext.Localization; string staticsRootUrl = SiteConfiguration.GetLocalStaticsUrl(localization.LocalizationId); urlPath = urlPath.StartsWith("/" + staticsRootUrl) ? urlPath.Substring(staticsRootUrl.Length + 1) : urlPath; if (!localization.IsStaticContentUrl(urlPath)) { // Not a static content item; continue the HTTP pipeline. return; } try { using (StaticContentItem staticContentItem = SiteConfiguration.ContentProvider.GetStaticContentItem(urlPath, localization)) { DateTime lastModified = staticContentItem.LastModified; if (lastModified < ifModifiedSince) { Log.Debug("Static content item last modified at {0} => Sending HTTP 304 (Not Modified).", lastModified); response.StatusCode = (int)HttpStatusCode.NotModified; response.SuppressContent = true; } else { response.ContentType = staticContentItem.ContentType; staticContentItem.GetContentStream().CopyTo(response.OutputStream); } } } catch (DxaItemNotFoundException ex) { SendNotFoundResponse(ex.Message, response); } // Terminate the HTTP pipeline. application.CompleteRequest(); } }
public virtual void GetStaticContentItem_InternationalizedUrl_Success() // See TSI-1278 { // Since we don't know the URL of the binary upfront, we obtain it from a known Page Model. string testPageUrlPath = TestLocalization.GetAbsoluteUrlPath(TestFixture.Tsi1278PageRelativeUrlPath); PageModel pageModel = TestContentProvider.GetPageModel(testPageUrlPath, TestLocalization, addIncludes: false); Assert.IsNotNull(pageModel, "pageModel"); MediaItem testImage = pageModel.Regions["Main"].Entities[0] as MediaItem; Assert.IsNotNull(testImage, "testImage"); string testStaticContentItemUrlPath = testImage.Url; using (StaticContentItem testStaticContentItem = TestContentProvider.GetStaticContentItem(testStaticContentItemUrlPath, TestLocalization)) { Assert.IsNotNull(testStaticContentItem, "testStaticContentItem"); Assert.AreEqual("image/jpeg", testStaticContentItem.ContentType, "testStaticContentItem.ContentType"); Stream contentStream = testStaticContentItem.GetContentStream(); Assert.IsNotNull(contentStream, "contentStream"); Assert.AreEqual(192129, contentStream.Length, "contentStream.Length"); } }
/// <summary> /// Extract campaign ZIP to specified directory. /// </summary> /// <param name="zipItem"></param> /// <param name="directory"></param> /// <param name="zipLastModified"></param> protected void ExtractZip(StaticContentItem zipItem, String directory, DateTime zipLastModified) { lock (GetLock(directory)) { if (Directory.Exists(directory)) { if (Directory.GetCreationTime(directory) > zipLastModified && Directory.GetFiles(directory).Length > 0) { Log.Info("Campaign assets in directory '" + directory + "' is already up to date. Skipping recreation of campaign assets."); } try { Directory.Delete(directory, true); } catch (Exception e) { Log.Warn("Could not delete cached campaign resources in: " + directory, e); } } if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } try { using (ZipArchive archive = new ZipArchive(zipItem.GetContentStream())) { archive.ExtractToDirectory(directory); } } catch (Exception e) { Log.Warn("Could not unzip campaign resources in: " + directory + ". Will rely on the current content there.", e); } } }