Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PDFKit (wkhtmltopdf) Broken Pipe, OS X and Rails 3

I'm using PDFKit (which uses wkhtmltopdf) in an attempt to render a view as pdf within a Rails 3 app.

PDFKit renders with Errno::EPIPE (Broken pipe) pointing to send_data(kit.to_pdf, :filename => "generated.pdf", :type => 'application/pdf') in my controller show action:

# Controller
def show
  respond_to do |format|
    format.html { render }
    format.pdf do
      html = render_to_string(:layout => false , :action => "show.html.haml")
      kit = PDFKit.new(html)
      send_data(kit.to_pdf, :filename => "invoice.pdf", :type => 'application/pdf')
      return # to avoid double render call
    end
  end
end

# Gemfile
...
gem 'pdfkit'
gem 'wkhtmltopdf'
...

I know wkhtmltopdf is not the source of this error as wkhtmltopdf public/404.html tmp/404.pdf from within Rails.root works as expected.

I'm using an example from jonathanspies.com after using the middleware failed in the same manner.

# config/application.rb
require 'pdfkit'
config.middleware.use PDFKit::Middleware

After trying it in a fresh Rails 3 app, I get the following error:

command failed: "~/.rvm/gems/ree-1.8.7-2011.01@blog/bin/wkhtmltopdf" "--page-size" "Letter" "--margin-right" "0.75in" "--margin-top" "0.75in" "--margin-bottom" "0.75in" "--encoding" "UTF-8" "--margin-left" "0.75in" "--quiet" "-" "-"

Running the command manually and usage screen is displayed, looking at the --quiet option it is easy to see its supposed to be --quit

Change /lib/pdfkit/pdfkit.rb:35 to the following and everything works as expected (with middleware too).

args << '--quit'

So, once again, I've solved my problem in the act of writing the question to get help (always pays to include detail). I submitted a pull request which corrects the spelling mistake (always a silly mistake which gets unnoticed). Hope nobody minds me posting anyways.

like image 877
jvatic Avatar asked Apr 10 '11 23:04

jvatic


2 Answers

Regarding changing the quiet argument to quit.

This change is only valid if you are using the wkhtmltopdf gem which uses a very old version of the wkhtmltopdf binary.

With the wkhtmltopdf gem

10:32:15 wkhtml >     wkhtmltopdf --version
wkhtmltopdf 0.8.3 using wkhtmltopdf patched qt
Copyright (C) 2008,2009 Jakob Truelsen,
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Jakob Truelsen
Patches by Mário Silva and Emmanuel Bouthenot

10:32:16 wkhtml >     wkhtmltopdf --help | grep quit
  -q, --quit                      Be less verbose.
10:32:16 wkhtml >     wkhtmltopdf --help | grep quite
10:32:19 wkhtml > 

With the latest binary I have installed

10:33:40 tmp > wkhtmltopdf --version
Name:
  wkhtmltopdf 0.9.9

License:
  Copyright (C) 2008,2009 Wkhtmltopdf Authors.



  License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
  This is free software: you are free to change and redistribute it. There is NO
  WARRANTY, to the extent permitted by law.

Authors:
  Written by Jakob Truelsen. Patches by Mário Silva, Benoit Garret and Emmanuel
  Bouthenot.

10:33:50 tmp > wkhtmltopdf --help | grep quit
10:34:02 tmp > wkhtmltopdf --help | grep quiet
  -q, --quiet                         Be less verbose
10:34:07 tmp > 

The spelling mistake exists in the old binary that comes with the wkhtmltopdf gem. I would suggest you monkey patch pdfkit with an initialize or something based on if you included the wkhtmltopdf gem or not.

I would also accept a pull request that made pdfkit aware of the version of wkthtmltopdf it was running against and conditionally switched that argument.

like image 144
Michael Deering Avatar answered Nov 17 '22 16:11

Michael Deering


Change /lib/pdfkit/pdfkit.rb:35 to the following and everything works as expected (with middleware too).

args << '--quit'
like image 2
jvatic Avatar answered Nov 17 '22 16:11

jvatic