Description
Microsoft.AspNetCore.All Version 2.1.2
Microsoft.AspNetCore.NodeServices Version 2.1.1
Microsoft.NETCore.App Version 2.1.2
TargetFramework netcoreapp2.1
I'm doing something like this (generate a PDF file from HTML in node services, and them return the file to the user):
https://code.msdn.microsoft.com/How-to-export-HTML-to-PDF-c5afd0ce
I'm using the following plugin on node file:
https://github.com/westy92/html-pdf-chrome
No problem generating some small report's, but when the operation take longer than 2 minutes, the request fail and I got the following exception:
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.IO.IOException: The server returned an invalid or unrecognized response.
at System.Net.Http.HttpConnection.FillAsync()
at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance.InvokeExportAsync[T](NodeInvocationInfo invocationInfo, CancellationToken cancellationToken)
at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.InvokeExportAsync[T](CancellationToken cancellationToken, String moduleName, String exportNameOrNull, Object[] args)
at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.InvokeExportWithPossibleRetryAsync[T](String moduleName, String exportedFunctionName, Object[] args, Boolean allowRetry, CancellationToken cancellationToken)
at TestPdf.Controllers.HomeController.About(INodeServices nodeServices) in C:\Users\matheus.avi\Documents\Visual Studio 2017\Projects\TestPdf\TestPdf\Controllers\HomeController.cs:line 59
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at System.Threading.Tasks.ValueTask`1.get_Result()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
But the operation still's running and success is logged in the console.
Also if I configure it to generate a local File, the file is generated.
Startup.cs
services.AddNodeServices(options =>
{
options.InvocationTimeoutMilliseconds = 600000;
options.NodeInstanceOutputLogger = _logger;
options.WatchFileExtensions = new string[] { };
});
pdf2.js
module.exports = function (callback, html, header, footer) {
const htmlPdf = require('html-pdf-chrome');
const options = {
port: 9222,
printOptions: {
displayHeaderFooter: true,
headerTemplate: header,
footerTemplate: footer,
marginTop: 1.1,
marginBottom: 1,
marginLeft: 0,
marginRight: 0,
},
timeout: 600000
};
console.log('Create pdf');
htmlPdf.create(html, options)
.then(function (pdf) {
console.log('pdf created');
callback(null, JSON.parse(JSON.stringify(pdf.toBuffer())).data);
})
.catch(function (e) {
console.log('Error generating pdf');
console.log(e);
callback(e, null);
});
};
HomeController.cs
public async Task<IActionResult> About([FromServices] INodeServices nodeServices)
{
HttpClient hc = new HttpClient();
hc.Timeout = TimeSpan.FromMinutes(10);
var htmlContent = await hc.GetStringAsync($"http://{Request.Host}/report.html");
var headerContent = await hc.GetStringAsync($"http://{Request.Host}/header.html");
var footerContent = await hc.GetStringAsync($"http://{Request.Host}/footer.html");
var result = await nodeServices.InvokeAsync<byte[]>("./pdf2", htmlContent, headerContent, footerContent);
HttpContext.Response.ContentType = "application/pdf";
HttpContext.Response.Headers.Add("x-filename", "report.pdf");
HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "x-filename");
HttpContext.Response.Body.Write(result, 0, result.Length);
return new ContentResult();
}