diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..f352c3b
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,25 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [1.8.1] - 2022-06-06
+
+### Added
+
+- Update whtml drivers 0.12.1 -> 0.12.4 https://github.com/wkhtmltopdf/wkhtmltopdf/releases/tag/0.12.4 (based on https://github.com/webgio/Rotativa/pull/115)
+- Fix try to kill process when cancellation requested
+
+## [1.8.0] - 2022-06-03
+
+### Added
+
+- Add timeout support https://github.com/webgio/Rotativa/issues/203
+
+### Fixed
+
+- fix when WkhtmlDriver exits with error code https://github.com/webgio/Rotativa/issues/189
+- fix using HttpContext.Current instead passed ControllerContext https://github.com/webgio/Rotativa/pull/178
+
diff --git a/Rotativa.Demo/Controllers/HomeController.cs b/Rotativa.Demo/Controllers/HomeController.cs
index 39f121f..a6fd892 100644
--- a/Rotativa.Demo/Controllers/HomeController.cs
+++ b/Rotativa.Demo/Controllers/HomeController.cs
@@ -160,6 +160,21 @@ public ActionResult ErrorTest()
return new ActionAsPdf("SomethingBad") { FileName = "Test.pdf" };
}
+ public ActionResult HttpStatus500Test()
+ {
+ return new UrlAsPdf("https://httpstat.us/500") { FileName = "Test.pdf" };
+
+ }
+ public ActionResult HttpStatus404Test()
+ {
+ return new UrlAsPdf("https://httpstat.us/404") { FileName = "Test.pdf" };
+ }
+ public ActionResult HttpStatus200Test()
+ {
+ return new UrlAsPdf("https://httpstat.us/200") { FileName = "Test.pdf" };
+
+ }
+
public ActionResult SomethingBad()
{
return Redirect("http://thisdoesntexists");
diff --git a/Rotativa.Demo/Views/Home/Index.cshtml b/Rotativa.Demo/Views/Home/Index.cshtml
index 8000b1f..ecd4d6d 100644
--- a/Rotativa.Demo/Views/Home/Index.cshtml
+++ b/Rotativa.Demo/Views/Home/Index.cshtml
@@ -4,30 +4,33 @@
@ViewBag.Message
-
- - @Html.ActionLink("Home", "Index", new {name = "Giorgio"})
- - @Html.ActionLink("Test", "Test", "Home")
- - @Html.ActionLink("Test Image", "TestImage", "Home")
- - @Html.ActionLink("Test Image Png", "TestImagePng", "Home")
- - @Html.ActionLink("Test URL", "TestUrl", "Home")
- - @Html.ActionLink("Test External URL", "TestExternalUrl", "Home")
- - @Html.ActionLink("Test View", "TestView", "Home")
- - @Html.ActionLink("Test View Image", "TestViewImage", "Home")
- - @Html.ActionLink("Test Save on Server", "TestSaveOnServer", new { fileName = "test.pdf"})
- - @Html.ActionLink("Logged In Test", "AuthorizedTest", "Home")
- - @Html.ActionLink("Logged In Test Image", "AuthorizedTestImage", "Home")
- - @Html.ActionLink("Route Test", "RouteTest", "Home")
- - @Html.ActionLink("Test ViewAsPdf with a model", "TestViewWithModel")
- - @Html.ActionLink("Test ViewAsImage with a model", "TestImageViewWithModel")
- - @Html.ActionLink("Test PartialViewAsPdf with a model", "TestPartialViewWithModel")
- - @Html.ActionLink("Test PartialViewAsImage with a model", "TestImagePartialViewWithModel")
- - @Html.ActionLink("Error Test", "ErrorTest", "Home")
- - @Html.ActionLink("Binary Test", "BinaryTest", "Home")
- - @Html.ActionLink("Ajax Test", "Index", "AjaxTests")
- - @Html.ActionLink("Ajax Image Test", "IndexImage", "AjaxTests")
- - @Html.ActionLink("External CSS Test", "Index", "CssTests")
- - @Html.ActionLink("External CSS Test Image", "IndexImage", "CssTests")
-
+
+ - @Html.ActionLink("Home", "Index", new { name = "Giorgio" })
+ - @Html.ActionLink("Test", "Test", "Home")
+ - @Html.ActionLink("Test Image", "TestImage", "Home")
+ - @Html.ActionLink("Test Image Png", "TestImagePng", "Home")
+ - @Html.ActionLink("Test URL", "TestUrl", "Home")
+ - @Html.ActionLink("Test External URL", "TestExternalUrl", "Home")
+ - @Html.ActionLink("Test View", "TestView", "Home")
+ - @Html.ActionLink("Test View Image", "TestViewImage", "Home")
+ - @Html.ActionLink("Test Save on Server", "TestSaveOnServer", new { fileName = "test.pdf" })
+ - @Html.ActionLink("Logged In Test", "AuthorizedTest", "Home")
+ - @Html.ActionLink("Logged In Test Image", "AuthorizedTestImage", "Home")
+ - @Html.ActionLink("Route Test", "RouteTest", "Home")
+ - @Html.ActionLink("Test ViewAsPdf with a model", "TestViewWithModel")
+ - @Html.ActionLink("Test ViewAsImage with a model", "TestImageViewWithModel")
+ - @Html.ActionLink("Test PartialViewAsPdf with a model", "TestPartialViewWithModel")
+ - @Html.ActionLink("Test PartialViewAsImage with a model", "TestImagePartialViewWithModel")
+ - @Html.ActionLink("Error Test", "ErrorTest", "Home")
+ - @Html.ActionLink("Binary Test", "BinaryTest", "Home")
+ - @Html.ActionLink("Ajax Test", "Index", "AjaxTests")
+ - @Html.ActionLink("Ajax Image Test", "IndexImage", "AjaxTests")
+ - @Html.ActionLink("External CSS Test", "Index", "CssTests")
+ - @Html.ActionLink("External CSS Test Image", "IndexImage", "CssTests")
+ - @Html.ActionLink("HttpStatus 500 Test", "HttpStatus500Test", "Home")
+ - @Html.ActionLink("HttpStatus 404 Test", "HttpStatus404Test", "Home")
+ - @Html.ActionLink("HttpStatus 200 Test", "HttpStatus200Test", "Home")
+
diff --git a/Rotativa.Tests/RotativaTests.cs b/Rotativa.Tests/RotativaTests.cs
index 3442a36..d54194b 100644
--- a/Rotativa.Tests/RotativaTests.cs
+++ b/Rotativa.Tests/RotativaTests.cs
@@ -360,5 +360,40 @@ public void Can_print_image_from_page_with_external_css_file()
image.RawFormat.Should().Be.EqualTo(ImageFormat.Jpeg);
}
}
+
+ [Test]
+ public void HttpError_statuses_does_not_generate_pdf_file()
+ {
+ var testLink = selenium.FindElement(By.LinkText("HttpStatus 200 Test"));
+ var pdfHref = testLink.GetAttribute("href");
+
+ var content = "200 OK";
+ using (var wc = new WebClient())
+ {
+ var pdfResult = wc.DownloadData(new Uri(pdfHref));
+ var pdfTester = new PdfTester();
+ pdfTester.LoadPdf(pdfResult);
+ pdfTester.PdfIsValid.Should().Be.True();
+ pdfTester.PdfContains(content).Should().Be.True();
+ }
+
+ testLink = selenium.FindElement(By.LinkText("HttpStatus 404 Test"));
+ pdfHref = testLink.GetAttribute("href");
+
+
+ using (var wc = new WebClient())
+ {
+ Assert.Throws(typeof(WebException), () => wc.DownloadData(new Uri(pdfHref)));
+ }
+
+ testLink = selenium.FindElement(By.LinkText("HttpStatus 500 Test"));
+ pdfHref = testLink.GetAttribute("href");
+
+
+ using (var wc = new WebClient())
+ {
+ Assert.Throws(typeof(WebException), () => wc.DownloadData(new Uri(pdfHref)));
+ }
+ }
}
}
diff --git a/Rotativa.UnitTests/BinaryTests.cs b/Rotativa.UnitTests/BinaryTests.cs
index c254a98..fe12007 100644
--- a/Rotativa.UnitTests/BinaryTests.cs
+++ b/Rotativa.UnitTests/BinaryTests.cs
@@ -23,20 +23,19 @@ namespace Rotativa.UnitTests
[TestFixture]
public class BinaryTests
{
+ private const string TestUrl = "https://github.com/webgio/Rotativa";
+
[Test]
public void Can_build_the_pdf_binary()
{
- var localPath = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory);
- var solutionDir = localPath.Parent.Parent.Parent.FullName;
- var wkhtmltopdfPath = Path.Combine(solutionDir, "Rotativa", "Rotativa");
- var actionResult = new UrlAsPdf("https://github.com/webgio/Rotativa")
- {
- WkhtmltopdfPath = wkhtmltopdfPath
- };
- var builder = new TestControllerBuilder();
- var controller = new HomeController();
- builder.InitializeController(controller);
- var pdfBinary = actionResult.BuildPdf(controller.ControllerContext);
+ //Arrange
+ var actionResult = CreatePdfActionResult();
+ var controller = CreateTestController();
+
+ //Act
+ var pdfBinary = actionResult.BuildFile(controller.ControllerContext);
+
+ //Assert
var pdfTester = new PdfTester();
pdfTester.LoadPdf(pdfBinary);
pdfTester.PdfIsValid.Should().Be.True();
@@ -44,23 +43,82 @@ public void Can_build_the_pdf_binary()
}
[Test]
- public void Can_build_the_image_binary()
+ public void Failed_to_build_the_pdf_binary_when_timeout_exceed()
{
- var localPath = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory);
- var solutionDir = localPath.Parent.Parent.Parent.FullName;
- var wkhtmltoimagePath = Path.Combine(solutionDir, "Rotativa", "Rotativa");
- var actionResult = new UrlAsImage("https://github.com/webgio/Rotativa")
+ //Arrange
+ var actionResult = CreatePdfActionResult(convertTimeout: 1);
+ var controller = CreateTestController();
+ void TestMethod()
{
- WkhtmlPath = wkhtmltoimagePath
- };
- var builder = new TestControllerBuilder();
- var controller = new HomeController();
- builder.InitializeController(controller);
+ actionResult.BuildFile(controller.ControllerContext);
+ }
+ //Act
+
+ //Assert
+ Assert.Throws(TestMethod);
+
+ }
+
+ [Test]
+ public void Can_build_the_image_binary()
+ {
+ //Arrange
+ var actionResult = CreateImageActionResult();
+ var controller = CreateTestController();
+
+ //Act
var imageBinary = actionResult.BuildFile(controller.ControllerContext);
+ //Assert
var image = Image.FromStream(new MemoryStream(imageBinary));
image.Should().Not.Be.Null();
image.RawFormat.Should().Be.EqualTo(ImageFormat.Jpeg);
}
+
+ [Test]
+ public void Failed_to_build_the_image_binary_when_timeout_exceed()
+ {
+ //Arrange
+ var actionResult = CreateImageActionResult(convertTimeout: 1);
+ var controller = CreateTestController();
+ void TestMethod()
+ {
+ actionResult.BuildFile(controller.ControllerContext);
+ }
+ //Act
+
+ //Assert
+ Assert.Throws(TestMethod);
+ }
+
+ private static AsImageResultBase CreateImageActionResult(string url = TestUrl, int? convertTimeout = null)
+ => new UrlAsImage(url)
+ {
+ WkhtmlPath = GetWkhtmlPath(),
+ ConvertTimeout = convertTimeout,
+ };
+
+ private static AsPdfResultBase CreatePdfActionResult(string url = TestUrl, int? convertTimeout = null)
+ => new UrlAsPdf(url)
+ {
+ WkhtmlPath = GetWkhtmlPath(),
+ ConvertTimeout = convertTimeout,
+ };
+
+ private static string GetWkhtmlPath()
+ {
+ var localPath = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory);
+ var solutionDir = localPath.Parent.Parent.Parent.FullName;
+ var wkhtmlPath = Path.Combine(solutionDir, "Rotativa", "Rotativa");
+ return wkhtmlPath;
+ }
+
+ private static Controller CreateTestController()
+ {
+ var builder = new TestControllerBuilder();
+ var controller = new HomeController();
+ builder.InitializeController(controller);
+ return controller;
+ }
}
}
diff --git a/Rotativa/AsImageResultBase.cs b/Rotativa/AsImageResultBase.cs
index 9ad0830..71bdeca 100644
--- a/Rotativa/AsImageResultBase.cs
+++ b/Rotativa/AsImageResultBase.cs
@@ -56,7 +56,7 @@ public abstract class AsImageResultBase : AsResultBase
protected override byte[] WkhtmlConvert(string switches)
{
- return WkhtmltoimageDriver.Convert(this.WkhtmlPath, switches);
+ return WkhtmltoimageDriver.Convert(this.WkhtmlPath, switches, timeout: ConvertTimeout);
}
protected override string GetContentType()
diff --git a/Rotativa/AsPdfResultBase.cs b/Rotativa/AsPdfResultBase.cs
index f638dbf..f30eb9c 100644
--- a/Rotativa/AsPdfResultBase.cs
+++ b/Rotativa/AsPdfResultBase.cs
@@ -47,7 +47,7 @@ protected AsPdfResultBase()
protected override byte[] WkhtmlConvert(string switches)
{
- return WkhtmltopdfDriver.Convert(this.WkhtmlPath, switches);
+ return WkhtmltopdfDriver.Convert(this.WkhtmlPath, switches, timeout: ConvertTimeout);
}
protected override string GetContentType()
diff --git a/Rotativa/AsResultBase.cs b/Rotativa/AsResultBase.cs
index 0bf12eb..5c1c166 100644
--- a/Rotativa/AsResultBase.cs
+++ b/Rotativa/AsResultBase.cs
@@ -104,6 +104,11 @@ public string CookieName
public ContentDisposition ContentDisposition { get; set; }
+ ///
+ /// Timeout for converting to PDF
+ ///
+ public int? ConvertTimeout { get; set; }
+
protected abstract string GetUrl(ControllerContext context);
///
@@ -185,7 +190,7 @@ public byte[] BuildFile(ControllerContext context)
throw new ArgumentNullException("context");
if (this.WkhtmlPath == string.Empty)
- this.WkhtmlPath = HttpContext.Current.Server.MapPath("~/Rotativa");
+ this.WkhtmlPath = context.HttpContext.Server.MapPath("~/Rotativa");
var fileContent = this.CallTheDriver(context);
diff --git a/Rotativa/Extensions/ControllerContextExtensions.cs b/Rotativa/Extensions/ControllerContextExtensions.cs
index e3e91f8..2992edf 100644
--- a/Rotativa/Extensions/ControllerContextExtensions.cs
+++ b/Rotativa/Extensions/ControllerContextExtensions.cs
@@ -35,7 +35,7 @@ public static string GetHtmlFromView(this ControllerContext context, ViewEngineR
viewResult.View.Render(viewContext, sw);
string html = sw.GetStringBuilder().ToString();
- string baseUrl = string.Format("{0}://{1}", HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Authority);
+ string baseUrl = string.Format("{0}://{1}", context.HttpContext.Request.Url.Scheme, HttpContext.Current.Request.Url.Authority);
html = Regex.Replace(html, "", string.Format("", baseUrl), RegexOptions.IgnoreCase);
return html;
}
diff --git a/Rotativa/Rotativa.nuspec b/Rotativa/Rotativa.nuspec
index 387966c..26b4bed 100644
--- a/Rotativa/Rotativa.nuspec
+++ b/Rotativa/Rotativa.nuspec
@@ -2,7 +2,7 @@
Rotativa
- 1.7.3
+ 1.8.1
Rotativa
Giorgio Bozio
Giorgio Bozio
diff --git a/Rotativa/Rotativa/help-wkhtmltoimage.txt b/Rotativa/Rotativa/help-wkhtmltoimage.txt
index f44e514..357326b 100644
--- a/Rotativa/Rotativa/help-wkhtmltoimage.txt
+++ b/Rotativa/Rotativa/help-wkhtmltoimage.txt
@@ -1,117 +1,33 @@
Name:
- wkhtmltoimage 0.12.2.1 (with patched qt)
+ wkhtmltoimage 0.12.4 (with patched qt)
Synopsis:
wkhtmltoimage [OPTIONS]...