From 113e2470627629cb4555d83715d37ba814ca4031 Mon Sep 17 00:00:00 2001 From: Joshua Pinter <joshuapinter@gmail.com> Date: Wed, 21 Oct 2020 16:21:47 -0600 Subject: [PATCH] Add `wicked_pdf_url_base64`. Using URLs to reference images can cause a lot of problems with wkhtmltopdf, particularly when used in the header and footer. It produces errors such as "Too many open files" as well as buffer/stack overflows. A good solution to this is providing the image encoded as base64. This helper method takes a URL of an image, opens the URL, reads the image data and encodes it to base64. If the URL does not have a successful response (`response.is_a?(Net::HTTPSuccess) == false`), it will log a warning and return `nil`. We could optionally make this raise but that should be a project-wide change. TODO: - [ ] Better placement (since this is not technically part of the asset pipeline)? - [ ] Better naming? - [ ] Tests. --- lib/wicked_pdf/wicked_pdf_helper/assets.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/wicked_pdf/wicked_pdf_helper/assets.rb b/lib/wicked_pdf/wicked_pdf_helper/assets.rb index 6692fe1d..58b0e6a6 100644 --- a/lib/wicked_pdf/wicked_pdf_helper/assets.rb +++ b/lib/wicked_pdf/wicked_pdf_helper/assets.rb @@ -15,6 +15,20 @@ def wicked_pdf_asset_base64(path) "data:#{asset.content_type};base64,#{Rack::Utils.escape(base64)}" end + # Using `image_tag` with URLs when generating PDFs (specifically large PDFs with lots of pages) can cause buffer/stack overflows. + # + def wicked_pdf_url_base64(url) + response = Net::HTTP.get_response(URI(url)) + + if response.is_a?(Net::HTTPSuccess) + base64 = Base64.encode64(response.body).gsub(/\s+/, '') + "data:#{response.content_type};base64,#{Rack::Utils.escape(base64)}" + else + Rails.logger.warn("[wicked_pdf] #{response.code} #{response.message}: #{url}") + nil + end + end + def wicked_pdf_stylesheet_link_tag(*sources) stylesheet_contents = sources.collect do |source| source = WickedPdfHelper.add_extension(source, 'css')