htmlToPdf 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +39 -0
- data/.github/workflows/release.yml +39 -0
- data/.gitignore +9 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +48 -0
- data/Gemfile.lock +313 -5
- data/README.md +100 -19
- data/Rakefile +4 -0
- data/config.ru +9 -0
- data/docs/architecture.md +99 -0
- data/docs/contributing.md +60 -0
- data/docs/rails-integration.md +111 -0
- data/docs/security.md +81 -0
- data/htmlToPdf.gemspec +18 -4
- data/lib/htmlToPdf/browser_pool.rb +50 -0
- data/lib/htmlToPdf/configuration.rb +30 -5
- data/lib/htmlToPdf/print_options.rb +122 -0
- data/lib/htmlToPdf/version.rb +1 -1
- data/lib/htmlToPdf.rb +67 -60
- data/spec/htmlToPdf/browser_pool_spec.rb +89 -0
- data/spec/htmlToPdf/configuration_spec.rb +51 -0
- data/spec/htmlToPdf/print_options_spec.rb +154 -0
- data/spec/integration/controller_spec.rb +75 -0
- data/spec/internal/app/controllers/application_controller.rb +3 -0
- data/spec/internal/app/controllers/booms_controller.rb +16 -0
- data/spec/internal/app/controllers/widgets_controller.rb +25 -0
- data/spec/internal/app/views/layouts/application.html.erb +4 -0
- data/spec/internal/app/views/layouts/pdf.html.erb +4 -0
- data/spec/internal/app/views/widgets/show.html.erb +2 -0
- data/spec/internal/config/routes.rb +6 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/spec_helper.rb +31 -0
- metadata +187 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c827ae590775d110de569263bc2d4fe04fe424abe2eadbf2d34ccf5f4bbefff
|
|
4
|
+
data.tar.gz: 90ea2e0f7dd5d5b9fefcc441677997480dc5f27d0d02e2852c2be47e7ba9a3e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f998e37dcef376f0459b4be1afaafcb20abdb0705f56bf6ca0d6d3e951f0b65aee8f2a0f5dca82d5ddce140ca2fa32561f01ad1a779563b2a86c778e28a8f86
|
|
7
|
+
data.tar.gz: 4e1b9d09c1cbedd080d10b68e9954cda8ff37c4e0dd2e0b28836eb17ca6b3d76e7baa833f775930e5d50788cb733b193e87066f0b70fb5077c96d4e984c9d8d6
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
# required_ruby_version in htmlToPdf.gemspec is >= 3.1 — test across
|
|
16
|
+
# that whole supported range, not just whatever's newest.
|
|
17
|
+
ruby-version: ["3.1", "3.2", "3.3", "3.4"]
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- uses: ruby/setup-ruby@v1
|
|
22
|
+
with:
|
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
24
|
+
bundler-cache: true
|
|
25
|
+
|
|
26
|
+
# ubuntu-latest ships google-chrome-stable already; the spec suite
|
|
27
|
+
# exercises real headless Chrome through ferrum, plus pdftotext to
|
|
28
|
+
# assert on rendered PDF content.
|
|
29
|
+
- name: Install poppler-utils (pdftotext)
|
|
30
|
+
run: sudo apt-get update && sudo apt-get install -y poppler-utils
|
|
31
|
+
|
|
32
|
+
- name: Syntax-check every Ruby file
|
|
33
|
+
run: find lib spec -name '*.rb' | xargs -n1 ruby -c
|
|
34
|
+
|
|
35
|
+
- name: Run test suite
|
|
36
|
+
run: bundle exec rake spec
|
|
37
|
+
|
|
38
|
+
- name: Build the gem (packaging sanity check)
|
|
39
|
+
run: gem build htmlToPdf.gemspec
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
id-token: write # required for RubyGems Trusted Publishing (OIDC) — no stored API key
|
|
16
|
+
contents: read
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- uses: ruby/setup-ruby@v1
|
|
21
|
+
with:
|
|
22
|
+
ruby-version: "3.3"
|
|
23
|
+
bundler-cache: true
|
|
24
|
+
|
|
25
|
+
- name: Install poppler-utils (pdftotext)
|
|
26
|
+
run: sudo apt-get update && sudo apt-get install -y poppler-utils
|
|
27
|
+
|
|
28
|
+
# Same gate CI already ran on the commit this tag points to, run again
|
|
29
|
+
# here as a last check before anything actually gets published.
|
|
30
|
+
- name: Run test suite
|
|
31
|
+
run: bundle exec rake spec
|
|
32
|
+
|
|
33
|
+
# Builds htmlToPdf.gemspec and pushes to rubygems.org via OIDC trusted
|
|
34
|
+
# publishing — see README's "Releasing" section for the one-time setup
|
|
35
|
+
# this depends on (linking this repo + this exact workflow file to the
|
|
36
|
+
# htmlToPdf gem on rubygems.org). No RUBYGEMS_API_KEY secret needed or
|
|
37
|
+
# used anywhere in this workflow.
|
|
38
|
+
- name: Publish to RubyGems
|
|
39
|
+
uses: rubygems/release-gem@v1
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. Format loosely follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
+
|
|
6
|
+
## [3.0.0] - 2026-10-05
|
|
7
|
+
|
|
8
|
+
- **Breaking: replaced the wkhtmltopdf binary dependency with a pooled headless Chrome instance**,
|
|
9
|
+
driven over the DevTools protocol via the [ferrum](https://github.com/rubycdp/ferrum) gem.
|
|
10
|
+
wkhtmltopdf is an unmaintained, years-out-of-date WebKit build with no flexbox/Grid support;
|
|
11
|
+
headless Chrome is the same engine your users already browse the app with. One `Ferrum::Browser`
|
|
12
|
+
process is kept alive per Ruby process instead of spawning a binary per request — see
|
|
13
|
+
[Architecture](docs/architecture.md#browserpool). `config.wkhtmltopdf_path` is gone, replaced by
|
|
14
|
+
`config.browser_options` (passed straight to `Ferrum::Browser.new`).
|
|
15
|
+
- **Breaking: `pdf_options[:wkhtmltopdf_options]` is gone, replaced by `pdf_options[:print_options]`**
|
|
16
|
+
— Chrome's print-to-PDF parameters (`landscape`, `format`, `margin_*`, `scale`,
|
|
17
|
+
`display_header_footer`/`header_template`/`footer_template`, `page_ranges`,
|
|
18
|
+
`prefer_css_page_size`, plus `javascript_delay` as the gem's own convenience) instead of literal
|
|
19
|
+
wkhtmltopdf CLI flags. The old `orientation`/`page_size` flag names are no longer recognized —
|
|
20
|
+
use `landscape`/`format`. See the README's options table.
|
|
21
|
+
- **Breaking: wire-up changed from `before_action :html_to_pdf` to `include HtmlToPdf` +
|
|
22
|
+
`around_action :html_to_pdf`**, and the gem no longer auto-includes itself into every
|
|
23
|
+
`ActionController::Base` subclass in the host app. This fixes two real bugs found while testing
|
|
24
|
+
the previous design against an actual Rails app rather than a stub: every PDF request raised
|
|
25
|
+
`AbstractController::DoubleRenderError` (Rails' `response=` setter is documented to mark the
|
|
26
|
+
response as already-rendered the instant it's assigned; the old shadow-controller design copied
|
|
27
|
+
that flag onto the real controller), and any `before_action` declared after `html_to_pdf` never
|
|
28
|
+
ran before the view was captured. See
|
|
29
|
+
[The DoubleRenderError trap](https://ramlaxmanyadav.github.io/htmlToPdf/rails-double-render-pdf.html)
|
|
30
|
+
for the full story and [Rails integration](docs/rails-integration.md) for the new wiring.
|
|
31
|
+
- **Security: `header_template`/`footer_template` are now filtered out of request-supplied
|
|
32
|
+
`print_options` by default** — unlike every other print option, they're raw HTML Chrome renders
|
|
33
|
+
as-is, which made them an SSRF vector (`<img src="http://internal-host/...">`) on any action that
|
|
34
|
+
forwards `pdf_options` from request params. Only honored from `config.default_options` unless
|
|
35
|
+
`config.allow_request_templates = true` is set explicitly. See [Security](docs/security.md).
|
|
36
|
+
- **Security: `javascript_delay` is now capped** at `config.max_javascript_delay_ms` (default 10
|
|
37
|
+
seconds) — previously an uncapped value let one caller stall the shared browser pool for every
|
|
38
|
+
other in-flight PDF render in the same process.
|
|
39
|
+
- Fixed: a per-request browser context leaked on every single render (the context Chrome creates
|
|
40
|
+
for isolation was never disposed unless `create_page` was called with its own block).
|
|
41
|
+
- Fixed: a gem-wide default `:format`/margin in `config.default_options` could silently clobber an
|
|
42
|
+
explicit per-request `paper_width`/`paper_height`/`:padding` instead of being overridden by it.
|
|
43
|
+
- Added: an automated test suite (RSpec + [combustion](https://github.com/pat/combustion) for a
|
|
44
|
+
real-Rails-dispatch integration spec) and CI across Ruby 3.1–3.4 on every push/PR.
|
|
45
|
+
|
|
46
|
+
## [2.0.0] and earlier
|
|
47
|
+
|
|
48
|
+
Rendered via the wkhtmltopdf binary; see git history prior to 3.0.0 for details.
|
data/Gemfile.lock
CHANGED
|
@@ -1,24 +1,332 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
htmlToPdf (
|
|
4
|
+
htmlToPdf (3.0.0)
|
|
5
|
+
activesupport (>= 7.0, < 9)
|
|
6
|
+
ferrum (>= 0.13, < 1.0)
|
|
5
7
|
|
|
6
8
|
GEM
|
|
7
9
|
remote: https://rubygems.org/
|
|
8
10
|
specs:
|
|
11
|
+
action_text-trix (2.1.19)
|
|
12
|
+
railties
|
|
13
|
+
actioncable (8.1.4)
|
|
14
|
+
actionpack (= 8.1.4)
|
|
15
|
+
activesupport (= 8.1.4)
|
|
16
|
+
nio4r (~> 2.0)
|
|
17
|
+
websocket-driver (>= 0.6.1)
|
|
18
|
+
zeitwerk (~> 2.6)
|
|
19
|
+
actionmailbox (8.1.4)
|
|
20
|
+
actionpack (= 8.1.4)
|
|
21
|
+
activejob (= 8.1.4)
|
|
22
|
+
activerecord (= 8.1.4)
|
|
23
|
+
activestorage (= 8.1.4)
|
|
24
|
+
activesupport (= 8.1.4)
|
|
25
|
+
mail (>= 2.8.0)
|
|
26
|
+
actionmailer (8.1.4)
|
|
27
|
+
actionpack (= 8.1.4)
|
|
28
|
+
actionview (= 8.1.4)
|
|
29
|
+
activejob (= 8.1.4)
|
|
30
|
+
activesupport (= 8.1.4)
|
|
31
|
+
mail (>= 2.8.0)
|
|
32
|
+
rails-dom-testing (~> 2.2)
|
|
33
|
+
actionpack (8.1.4)
|
|
34
|
+
actionview (= 8.1.4)
|
|
35
|
+
activesupport (= 8.1.4)
|
|
36
|
+
nokogiri (>= 1.8.5)
|
|
37
|
+
rack (>= 2.2.4)
|
|
38
|
+
rack-session (>= 1.0.1)
|
|
39
|
+
rack-test (>= 0.6.3)
|
|
40
|
+
rails-dom-testing (~> 2.2)
|
|
41
|
+
rails-html-sanitizer (~> 1.6)
|
|
42
|
+
useragent (~> 0.16)
|
|
43
|
+
actiontext (8.1.4)
|
|
44
|
+
action_text-trix (~> 2.1.15)
|
|
45
|
+
actionpack (= 8.1.4)
|
|
46
|
+
activerecord (= 8.1.4)
|
|
47
|
+
activestorage (= 8.1.4)
|
|
48
|
+
activesupport (= 8.1.4)
|
|
49
|
+
globalid (>= 0.6.0)
|
|
50
|
+
nokogiri (>= 1.8.5)
|
|
51
|
+
actionview (8.1.4)
|
|
52
|
+
activesupport (= 8.1.4)
|
|
53
|
+
builder (~> 3.1)
|
|
54
|
+
erubi (~> 1.11)
|
|
55
|
+
rails-dom-testing (~> 2.2)
|
|
56
|
+
rails-html-sanitizer (~> 1.6)
|
|
57
|
+
activejob (8.1.4)
|
|
58
|
+
activesupport (= 8.1.4)
|
|
59
|
+
globalid (>= 0.3.6)
|
|
60
|
+
activemodel (8.1.4)
|
|
61
|
+
activesupport (= 8.1.4)
|
|
62
|
+
activerecord (8.1.4)
|
|
63
|
+
activemodel (= 8.1.4)
|
|
64
|
+
activesupport (= 8.1.4)
|
|
65
|
+
timeout (>= 0.4.0)
|
|
66
|
+
activestorage (8.1.4)
|
|
67
|
+
actionpack (= 8.1.4)
|
|
68
|
+
activejob (= 8.1.4)
|
|
69
|
+
activerecord (= 8.1.4)
|
|
70
|
+
activesupport (= 8.1.4)
|
|
71
|
+
marcel (~> 1.0)
|
|
72
|
+
activesupport (8.1.4)
|
|
73
|
+
base64
|
|
74
|
+
bigdecimal
|
|
75
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
76
|
+
connection_pool (>= 2.2.5)
|
|
77
|
+
drb
|
|
78
|
+
i18n (>= 1.6, < 2)
|
|
79
|
+
json
|
|
80
|
+
logger (>= 1.4.2)
|
|
81
|
+
minitest (>= 5.1)
|
|
82
|
+
securerandom (>= 0.3)
|
|
83
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
84
|
+
uri (>= 0.13.1)
|
|
85
|
+
addressable (2.9.0)
|
|
86
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
87
|
+
base64 (0.3.0)
|
|
88
|
+
bigdecimal (4.1.3)
|
|
89
|
+
builder (3.3.0)
|
|
90
|
+
combustion (1.5.0)
|
|
91
|
+
activesupport (>= 3.0.0)
|
|
92
|
+
railties (>= 3.0.0)
|
|
93
|
+
thor (>= 0.14.6)
|
|
94
|
+
concurrent-ruby (1.3.8)
|
|
95
|
+
connection_pool (3.0.2)
|
|
96
|
+
crass (1.0.7)
|
|
97
|
+
date (3.5.1)
|
|
98
|
+
diff-lcs (1.6.2)
|
|
99
|
+
drb (2.2.3)
|
|
100
|
+
erb (6.0.7)
|
|
101
|
+
erubi (1.13.1)
|
|
102
|
+
ferrum (0.18.0)
|
|
103
|
+
addressable (~> 2.5)
|
|
104
|
+
base64 (~> 0.2)
|
|
105
|
+
concurrent-ruby (~> 1.1)
|
|
106
|
+
websocket-driver (~> 0.7)
|
|
107
|
+
globalid (1.4.0)
|
|
108
|
+
activesupport (>= 6.1)
|
|
109
|
+
i18n (1.15.2)
|
|
110
|
+
concurrent-ruby (~> 1.0)
|
|
111
|
+
io-console (0.9.4)
|
|
112
|
+
irb (1.18.0)
|
|
113
|
+
pp (>= 0.6.0)
|
|
114
|
+
prism (>= 1.3.0)
|
|
115
|
+
rdoc (>= 4.0.0)
|
|
116
|
+
reline (>= 0.4.2)
|
|
117
|
+
json (3.0.2)
|
|
118
|
+
logger (1.7.0)
|
|
119
|
+
loofah (2.25.2)
|
|
120
|
+
crass (~> 1.0.2)
|
|
121
|
+
nokogiri (>= 1.12.0)
|
|
122
|
+
mail (2.9.1)
|
|
123
|
+
logger
|
|
124
|
+
mini_mime (>= 0.1.1)
|
|
125
|
+
net-imap
|
|
126
|
+
net-pop
|
|
127
|
+
net-smtp
|
|
128
|
+
marcel (1.2.1)
|
|
129
|
+
mini_mime (1.1.5)
|
|
130
|
+
minitest (6.0.6)
|
|
131
|
+
drb (~> 2.0)
|
|
132
|
+
prism (~> 1.5)
|
|
133
|
+
net-imap (0.6.7)
|
|
134
|
+
date
|
|
135
|
+
net-protocol
|
|
136
|
+
net-pop (0.1.2)
|
|
137
|
+
net-protocol
|
|
138
|
+
net-protocol (0.4.0)
|
|
139
|
+
timeout
|
|
140
|
+
net-smtp (0.5.2)
|
|
141
|
+
net-protocol
|
|
142
|
+
nio4r (2.7.5)
|
|
143
|
+
nokogiri (1.19.4-arm64-darwin)
|
|
144
|
+
racc (~> 1.4)
|
|
145
|
+
pp (0.6.4)
|
|
146
|
+
prettyprint
|
|
147
|
+
prettyprint (0.2.0)
|
|
148
|
+
prism (1.9.0)
|
|
149
|
+
public_suffix (7.0.5)
|
|
150
|
+
puma (6.6.1)
|
|
151
|
+
nio4r (~> 2.0)
|
|
152
|
+
racc (1.8.1)
|
|
153
|
+
rack (3.2.7)
|
|
154
|
+
rack-session (2.1.2)
|
|
155
|
+
base64 (>= 0.1.0)
|
|
156
|
+
rack (>= 3.0.0)
|
|
157
|
+
rack-test (2.2.0)
|
|
158
|
+
rack (>= 1.3)
|
|
159
|
+
rackup (2.3.1)
|
|
160
|
+
rack (>= 3)
|
|
161
|
+
rails (8.1.4)
|
|
162
|
+
actioncable (= 8.1.4)
|
|
163
|
+
actionmailbox (= 8.1.4)
|
|
164
|
+
actionmailer (= 8.1.4)
|
|
165
|
+
actionpack (= 8.1.4)
|
|
166
|
+
actiontext (= 8.1.4)
|
|
167
|
+
actionview (= 8.1.4)
|
|
168
|
+
activejob (= 8.1.4)
|
|
169
|
+
activemodel (= 8.1.4)
|
|
170
|
+
activerecord (= 8.1.4)
|
|
171
|
+
activestorage (= 8.1.4)
|
|
172
|
+
activesupport (= 8.1.4)
|
|
173
|
+
bundler (>= 1.15.0)
|
|
174
|
+
railties (= 8.1.4)
|
|
175
|
+
rails-dom-testing (2.3.0)
|
|
176
|
+
activesupport (>= 5.0.0)
|
|
177
|
+
minitest
|
|
178
|
+
nokogiri (>= 1.6)
|
|
179
|
+
rails-html-sanitizer (1.7.1)
|
|
180
|
+
loofah (~> 2.25, >= 2.25.2)
|
|
181
|
+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
182
|
+
railties (8.1.4)
|
|
183
|
+
actionpack (= 8.1.4)
|
|
184
|
+
activesupport (= 8.1.4)
|
|
185
|
+
irb (~> 1.13)
|
|
186
|
+
rackup (>= 1.0.0)
|
|
187
|
+
rake (>= 12.2)
|
|
188
|
+
thor (~> 1.0, >= 1.2.2)
|
|
189
|
+
tsort (>= 0.2)
|
|
190
|
+
zeitwerk (~> 2.6)
|
|
9
191
|
rake (13.4.2)
|
|
192
|
+
rbs (4.2.0)
|
|
193
|
+
logger
|
|
194
|
+
prism (>= 1.6.0)
|
|
195
|
+
tsort
|
|
196
|
+
rdoc (8.1.0)
|
|
197
|
+
erb
|
|
198
|
+
prism (>= 1.6.0)
|
|
199
|
+
rbs (>= 4.0.0)
|
|
200
|
+
tsort
|
|
201
|
+
reline (0.7.0)
|
|
202
|
+
io-console (~> 0.5)
|
|
203
|
+
rspec (3.13.2)
|
|
204
|
+
rspec-core (~> 3.13.0)
|
|
205
|
+
rspec-expectations (~> 3.13.0)
|
|
206
|
+
rspec-mocks (~> 3.13.0)
|
|
207
|
+
rspec-core (3.13.6)
|
|
208
|
+
rspec-support (~> 3.13.0)
|
|
209
|
+
rspec-expectations (3.13.5)
|
|
210
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
211
|
+
rspec-support (~> 3.13.0)
|
|
212
|
+
rspec-mocks (3.13.8)
|
|
213
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
214
|
+
rspec-support (~> 3.13.0)
|
|
215
|
+
rspec-rails (7.1.1)
|
|
216
|
+
actionpack (>= 7.0)
|
|
217
|
+
activesupport (>= 7.0)
|
|
218
|
+
railties (>= 7.0)
|
|
219
|
+
rspec-core (~> 3.13)
|
|
220
|
+
rspec-expectations (~> 3.13)
|
|
221
|
+
rspec-mocks (~> 3.13)
|
|
222
|
+
rspec-support (~> 3.13)
|
|
223
|
+
rspec-support (3.13.7)
|
|
224
|
+
securerandom (0.4.1)
|
|
225
|
+
thor (1.5.0)
|
|
226
|
+
timeout (0.6.1)
|
|
227
|
+
tsort (0.2.0)
|
|
228
|
+
tzinfo (2.0.6)
|
|
229
|
+
concurrent-ruby (~> 1.0)
|
|
230
|
+
uri (1.1.1)
|
|
231
|
+
useragent (0.16.11)
|
|
232
|
+
websocket-driver (0.8.2)
|
|
233
|
+
base64
|
|
234
|
+
websocket-extensions (>= 0.1.0)
|
|
235
|
+
websocket-extensions (0.1.5)
|
|
236
|
+
zeitwerk (2.8.3)
|
|
10
237
|
|
|
11
238
|
PLATFORMS
|
|
12
|
-
|
|
239
|
+
arm64-darwin-25
|
|
13
240
|
|
|
14
241
|
DEPENDENCIES
|
|
15
|
-
bundler (>= 2.4)
|
|
242
|
+
bundler (>= 2.4, < 5)
|
|
243
|
+
combustion (~> 1.5)
|
|
16
244
|
htmlToPdf!
|
|
17
|
-
|
|
245
|
+
puma (>= 5.0, < 7)
|
|
246
|
+
rails (>= 7.0, < 9)
|
|
247
|
+
rake (>= 13.0, < 14)
|
|
248
|
+
rspec (~> 3.13)
|
|
249
|
+
rspec-rails (~> 7.0)
|
|
18
250
|
|
|
19
251
|
CHECKSUMS
|
|
20
|
-
|
|
252
|
+
action_text-trix (2.1.19) sha256=7012f59421009cf284aa651294896414d653a61a2417c9b8714c8476d2f74009
|
|
253
|
+
actioncable (8.1.4) sha256=cfcd72f8c861e01ccdc96d772ad8c5ad6ed0ea7c571aef81a794b6027eaa7f11
|
|
254
|
+
actionmailbox (8.1.4) sha256=9c4525e577ebb671ce558f3ea78b8a634f64e56a0e6e8d105b28b873793a06eb
|
|
255
|
+
actionmailer (8.1.4) sha256=f82d95d6762ae46ea38f221d3363639266af4f8e56d50e2bd367558674baf093
|
|
256
|
+
actionpack (8.1.4) sha256=245493cc51be195a7645e6fc184880fa7e5b32ff1a08e053ee31f58c76e30ea4
|
|
257
|
+
actiontext (8.1.4) sha256=33ee99bea7da6af911fc7d98b17013a8e1ec62aa01b20b20e9a5366f40dbf644
|
|
258
|
+
actionview (8.1.4) sha256=eff1efd07c4d969abad288322b423bcb67fdbab5e324c91ca37352b80f226076
|
|
259
|
+
activejob (8.1.4) sha256=4ed5b2ed8d4cc5c8f5f09becfef8346f202a4884eee0c8c73cae5ac378824099
|
|
260
|
+
activemodel (8.1.4) sha256=9a0906c127bd118aa5f06157db12b8f750da83dccee72db2f658547a0ae7a0e8
|
|
261
|
+
activerecord (8.1.4) sha256=3b4957ea7f246c9231bd7faa909312eac03a9101aaf87977b6c52733ff00b04f
|
|
262
|
+
activestorage (8.1.4) sha256=f4956f3ec9ee63e5e0b332b57c877cb627f82b56f4cc902279310d2aa285c7a8
|
|
263
|
+
activesupport (8.1.4) sha256=891dd3fe43c4fc8391934b237b1189bb1f661c932a84a840043db9d46a4e80df
|
|
264
|
+
addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af
|
|
265
|
+
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
266
|
+
bigdecimal (4.1.3) sha256=61ebe1e5e559bdc3cc6f2c0ee7f427321fc838f59611c294356eb04d6e21cf66
|
|
267
|
+
builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f
|
|
268
|
+
combustion (1.5.0) sha256=5e68cc8c2090ee06196a03e748276d1d63d4f63ed189888a23e1daa4fb79359a
|
|
269
|
+
concurrent-ruby (1.3.8) sha256=b2f1be836e968ccc78ccfce277ea79c72a88633f22306782c16ff23fb415d1e1
|
|
270
|
+
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
|
|
271
|
+
crass (1.0.7) sha256=94868719948664c89ddcaf0a37c65048413dfcb1c869470a5f7a7ceb5390b295
|
|
272
|
+
date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
|
|
273
|
+
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
|
|
274
|
+
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
275
|
+
erb (6.0.7) sha256=c5ca6dc25b0ef974a44dc8f59fe847577122483b1968a38dec305c60bf91ee92
|
|
276
|
+
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
|
|
277
|
+
ferrum (0.18.0) sha256=4cb8be16e352fc1d75f087e9214b34ec1b93ba932410c730a4724909ca89d7c6
|
|
278
|
+
globalid (1.4.0) sha256=037f12fbf1d9d7a014d501c2d5c77356fd4ddd96d7a7991d6700bba96706f427
|
|
279
|
+
htmlToPdf (3.0.0)
|
|
280
|
+
i18n (1.15.2) sha256=00f9eb62412fe593b2a65a97daa75300d37abb8f7202ec748e94b6d46a9dd1b5
|
|
281
|
+
io-console (0.9.4) sha256=a403304f32928ee85e56d457b4612ca43f2703b561a3258844992bd24085fbb1
|
|
282
|
+
irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3
|
|
283
|
+
json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df
|
|
284
|
+
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
|
285
|
+
loofah (2.25.2) sha256=2007f746959ac65552456e04b433e83deb22759ab38c838b4445c70e43425918
|
|
286
|
+
mail (2.9.1) sha256=06574eca475253d6c18145dd70af80d0eb970182d55053497c5f4d797ea160e8
|
|
287
|
+
marcel (1.2.1) sha256=1678e9360e32f9eafa917c80029e2f6d10b2715c66a4b87b6d0da9b9cd1f859f
|
|
288
|
+
mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef
|
|
289
|
+
minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1
|
|
290
|
+
net-imap (0.6.7) sha256=b5c9573be975d856de252ee851871724da66aa2d449b2482d5690bd12bc23660
|
|
291
|
+
net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3
|
|
292
|
+
net-protocol (0.4.0) sha256=f9f90c8c6f64794a45160bf422177a336db12809de3beeeaa26b88fcd2e8c853
|
|
293
|
+
net-smtp (0.5.2) sha256=35103cc04d6b2d94632f9928ede07483c24b70b9c0db1f231fea43909b678f3c
|
|
294
|
+
nio4r (2.7.5) sha256=6c90168e48fb5f8e768419c93abb94ba2b892a1d0602cb06eef16d8b7df1dca1
|
|
295
|
+
nokogiri (1.19.4-arm64-darwin) sha256=a46db9853286e6597b36ebc6953817d15acf3a299583eb3f89fdc6f91dd63527
|
|
296
|
+
pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570
|
|
297
|
+
prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
|
|
298
|
+
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
|
|
299
|
+
public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623
|
|
300
|
+
puma (6.6.1) sha256=b9b56e4a4ea75d1bfa6d9e1972ee2c9f43d0883f011826d914e8e37b3694ea1e
|
|
301
|
+
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
|
|
302
|
+
rack (3.2.7) sha256=93e13e1c24f93556671d85d2d79fa228c3485815c50d7e2f265b5330c6528fb7
|
|
303
|
+
rack-session (2.1.2) sha256=595434f8c0c3473ae7d7ac56ecda6cc6dfd9d37c0b2b5255330aa1576967ffe8
|
|
304
|
+
rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463
|
|
305
|
+
rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868
|
|
306
|
+
rails (8.1.4) sha256=5f3ecdf9a2a3b79b2e31b8fee3b64a00f7284d76e5631f87d0e58e665911a33b
|
|
307
|
+
rails-dom-testing (2.3.0) sha256=8acc7953a7b911ca44588bf08737bc16719f431a1cc3091a292bca7317925c1d
|
|
308
|
+
rails-html-sanitizer (1.7.1) sha256=e797a7c9b01e567307e317c576b49ab4168017e63eea4dba9ce3cb587e2f22c2
|
|
309
|
+
railties (8.1.4) sha256=b5e7a8e8984e33114d68af62227971960aae1e6c02bd7c9d826ffad97fff583c
|
|
21
310
|
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
|
|
311
|
+
rbs (4.2.0) sha256=51f7b886dcc05bc09e10b901daa6a81829f6adc03101d6ca9ea4aac6103e0674
|
|
312
|
+
rdoc (8.1.0) sha256=befc37880a5cfd36dcb176c748b5fd5ee39dd3536a75e81824e4972ce230f60a
|
|
313
|
+
reline (0.7.0) sha256=5b012d8e55dbf9d450f12bde2cf7d15ff546ae80b3f8f3b30e570d431815583d
|
|
314
|
+
rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
|
|
315
|
+
rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
|
|
316
|
+
rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
|
|
317
|
+
rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
|
|
318
|
+
rspec-rails (7.1.1) sha256=e15dccabed211e2fd92f21330c819adcbeb1591c1d66c580d8f2d8288557e331
|
|
319
|
+
rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
|
|
320
|
+
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
|
|
321
|
+
thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
|
|
322
|
+
timeout (0.6.1) sha256=78f57368a7e7bbadec56971f78a3f5ecbcfb59b7fcbb0a3ed6ddc08a5094accb
|
|
323
|
+
tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
|
|
324
|
+
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
|
|
325
|
+
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
|
|
326
|
+
useragent (0.16.11) sha256=700e6413ad4bb954bb63547fa098dddf7b0ebe75b40cc6f93b8d54255b173844
|
|
327
|
+
websocket-driver (0.8.2) sha256=97c556b019bf3410b4961002ac501621e9322d3f8a7bc02161a09301cc4c4146
|
|
328
|
+
websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241
|
|
329
|
+
zeitwerk (2.8.3) sha256=2c85125a8467ce069e20123d1e709a08955c9d29c118c25b46b7b7fafdbb92e5
|
|
22
330
|
|
|
23
331
|
BUNDLED WITH
|
|
24
332
|
4.0.6
|
data/README.md
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
# HtmlToPdf
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://rubygems.org/gems/htmlToPdf)
|
|
4
|
+
[](https://github.com/ramlaxmanyadav/htmlToPdf/actions/workflows/ci.yml)
|
|
5
|
+
[](LICENSE.txt)
|
|
6
|
+
|
|
7
|
+
Turn any Rails controller action into a downloadable PDF, rendered exactly as the browser would
|
|
8
|
+
render it — real CSS, real layout, real fonts — via a pooled headless Chrome instance instead of
|
|
9
|
+
an abandoned wkhtmltopdf binary.
|
|
4
10
|
|
|
5
11
|
Supports Rails 7.x and Rails 8.x (latest).
|
|
6
12
|
|
|
13
|
+
Renders through a pooled headless Chrome instance (via the [ferrum](https://github.com/rubycdp/ferrum) gem), so you get modern CSS (flexbox, grid, custom fonts) and only need a Chrome/Chromium install — no separate renderer binary to install or package.
|
|
14
|
+
|
|
15
|
+
## Docs
|
|
16
|
+
|
|
17
|
+
- [Architecture](docs/architecture.md) — why headless Chrome instead of wkhtmltopdf, the request
|
|
18
|
+
lifecycle, the `BrowserPool` design, and the `print_options` security model in detail.
|
|
19
|
+
- [HtmlToPdf in Rails](docs/rails-integration.md) — callback ordering, custom layouts, Chrome in
|
|
20
|
+
Docker, and the `asset_host` gotcha that leaves a PDF unstyled if you miss it.
|
|
21
|
+
- [Security](docs/security.md) — exactly what's safe to expose on a public action and what isn't.
|
|
22
|
+
- [Contributing & Releasing](docs/contributing.md) — running the test suite, extending the gem.
|
|
23
|
+
- Longer-form guides on the [docs site](https://ramlaxmanyadav.github.io/htmlToPdf/):
|
|
24
|
+
- [Headless Chrome vs. wkhtmltopdf for Rails PDF generation](https://ramlaxmanyadav.github.io/htmlToPdf/headless-chrome-vs-wkhtmltopdf.html)
|
|
25
|
+
- [The DoubleRenderError trap: rendering a Rails view to PDF](https://ramlaxmanyadav.github.io/htmlToPdf/rails-double-render-pdf.html)
|
|
26
|
+
- [Choosing a Rails HTML-to-PDF gem: HtmlToPdf vs. Grover vs. WickedPdf vs. Prawn](https://ramlaxmanyadav.github.io/htmlToPdf/choosing-a-rails-pdf-gem.html)
|
|
27
|
+
|
|
7
28
|
## Installation
|
|
8
|
-
|
|
29
|
+
|
|
30
|
+
#### Make sure Chrome or Chromium is installed on the machine that will render PDFs.
|
|
31
|
+
|
|
32
|
+
Ferrum auto-detects a local Google Chrome / Chromium install (including on macOS, Linux and in most CI images). If it's installed somewhere non-standard, or you're running as root in Docker, see [Configuration](#configuration) below, or [Chrome in Docker](docs/rails-integration.md#production-deployment-chrome-in-docker) for a container deployment.
|
|
9
33
|
|
|
10
34
|
Add this line to your application's Gemfile:
|
|
11
35
|
|
|
@@ -21,9 +45,14 @@ Or install it yourself as:
|
|
|
21
45
|
|
|
22
46
|
## Usage
|
|
23
47
|
|
|
24
|
-
|
|
48
|
+
Opt in on the controller(s) that should support PDF export — typically `ApplicationController`:
|
|
49
|
+
|
|
50
|
+
class ApplicationController < ActionController::Base
|
|
51
|
+
include HtmlToPdf
|
|
52
|
+
around_action :html_to_pdf
|
|
53
|
+
end
|
|
25
54
|
|
|
26
|
-
|
|
55
|
+
It must be an `around_action`, not a `before_action`: the rest of the callback chain and the action itself run normally via `yield`, so any other `before_action`s (e.g. one that loads `@record`) still run in their usual order and their instance variables are available to the view. Nothing happens for ordinary requests — `html_to_pdf` only takes over when the request's format is `pdf`. See [HtmlToPdf in Rails](docs/rails-integration.md) for why this has to be an `around_action` and what that fixed.
|
|
27
56
|
|
|
28
57
|
in views:
|
|
29
58
|
|
|
@@ -39,45 +68,97 @@ you can customize pdf like you can give the name and layout for the pdf.to custo
|
|
|
39
68
|
|
|
40
69
|
one can call any action as pdf and he get the pdf file of that action's html.
|
|
41
70
|
|
|
42
|
-
customizing page padding and
|
|
71
|
+
customizing page padding and print options:
|
|
43
72
|
|
|
44
73
|
<%= link_to 'download', your_action_path(:format => 'pdf', :pdf_options => {
|
|
45
74
|
title: 'pdf_name',
|
|
46
75
|
layout: 'layout_name',
|
|
47
76
|
padding: '10mm',
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
77
|
+
print_options: {
|
|
78
|
+
landscape: true,
|
|
79
|
+
format: 'A4',
|
|
51
80
|
margin_top: '15mm',
|
|
52
|
-
|
|
81
|
+
scale: 0.9,
|
|
82
|
+
print_background: true,
|
|
83
|
+
page_ranges: '1-3',
|
|
84
|
+
javascript_delay: 500
|
|
53
85
|
}
|
|
54
86
|
}) %>
|
|
55
87
|
|
|
56
|
-
|
|
88
|
+
`padding` is a shorthand that sets all four margins at once. `print_options` accepts the options Chrome's print-to-PDF engine supports:
|
|
89
|
+
|
|
90
|
+
| Option | Type | Notes |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `landscape` | boolean | |
|
|
93
|
+
| `format` | string | `'A4'`, `'Letter'`, `'Legal'`, `'Tabloid'`, `'Ledger'`, `'A0'`–`'A6'` (case-insensitive) |
|
|
94
|
+
| `paper_width`, `paper_height` | number or string | used instead of `format`; accepts a plain number (inches) or a string with a unit, e.g. `'210mm'` |
|
|
95
|
+
| `margin_top`, `margin_bottom`, `margin_left`, `margin_right` | number or string | same units as above |
|
|
96
|
+
| `scale` | number | 0.1–2 |
|
|
97
|
+
| `print_background` | boolean | defaults to `true` (configurable, see below) |
|
|
98
|
+
| `display_header_footer`, `header_template`, `footer_template` | boolean / string | templates are HTML; Chrome supports `<span class="pageNumber">`, `<span class="totalPages">`, `<span class="date">`, `<span class="title">`, `<span class="url">` inside them. **`header_template`/`footer_template` are only honored from `config.default_options`, not from a request's `print_options`, unless you explicitly set `config.allow_request_templates = true`** — see [Security](docs/security.md#the-one-exception-header_template--footer_template). |
|
|
99
|
+
| `page_ranges` | string | e.g. `'1-3'` |
|
|
100
|
+
| `prefer_css_page_size` | boolean | honor `@page` CSS size over `format`/`paper_width`/`paper_height` |
|
|
101
|
+
| `javascript_delay` | integer (ms) | pause between page load and capture, for content that renders asynchronously; capped at `config.max_javascript_delay_ms` (default 10s) |
|
|
57
102
|
|
|
58
|
-
##### Security note: `pdf_options` is read from the request's query params
|
|
103
|
+
##### Security note: `pdf_options` is read from the request's query params. `print_options` is a fixed, narrow set of PDF layout flags (margins, paper size, etc.) rather than arbitrary CLI arguments forwarded to a subprocess, so it can't be used to inject arbitrary binary flags — `header_template`/`footer_template` are the one exception (raw HTML Chrome renders as-is) and are filtered out of request-supplied options by default. Still, only expose the pdf format on actions where letting a caller tweak layout/margins is acceptable, or filter `pdf_options` yourself before it reaches `html_to_pdf` (e.g. in a `before_action` that runs earlier). Full detail in [Security](docs/security.md).
|
|
59
104
|
|
|
60
105
|
## Configuration
|
|
61
106
|
|
|
62
107
|
Set gem-wide defaults in an initializer (e.g. `config/initializers/html_to_pdf.rb`):
|
|
63
108
|
|
|
64
109
|
HtmlToPdf.configure do |config|
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
|
|
110
|
+
# Keyword options passed straight to Ferrum::Browser.new. Leave empty to
|
|
111
|
+
# let Ferrum auto-detect a local Chrome/Chromium install. Useful for a
|
|
112
|
+
# custom binary path, longer timeouts, or Chrome flags such as
|
|
113
|
+
# no-sandbox when running as root in Docker:
|
|
114
|
+
config.browser_options = {
|
|
115
|
+
# browser_path: '/usr/bin/chromium',
|
|
116
|
+
# timeout: 20,
|
|
117
|
+
# process_timeout: 30,
|
|
118
|
+
# browser_options: { 'no-sandbox' => nil, 'disable-gpu' => nil }
|
|
119
|
+
}
|
|
68
120
|
|
|
69
121
|
# Layout used when pdf_options[:layout] isn't given. Defaults to "application".
|
|
70
122
|
config.default_layout = "pdf"
|
|
71
123
|
|
|
72
|
-
#
|
|
73
|
-
# padding/
|
|
74
|
-
|
|
124
|
+
# Print options (see the table above) applied to every PDF, merged
|
|
125
|
+
# under any per-request padding/print_options. Defaults to
|
|
126
|
+
# { print_background: true }. header_template/footer_template are safe
|
|
127
|
+
# here (this is your own code, not request input) even though they're
|
|
128
|
+
# rejected from a request's print_options by default — see Security.
|
|
129
|
+
config.default_options = {
|
|
130
|
+
print_background: true,
|
|
131
|
+
format: 'A4',
|
|
132
|
+
footer_template: '<div style="font-size:10px; width:100%; text-align:center;"><span class="pageNumber"></span> / <span class="totalPages"></span></div>',
|
|
133
|
+
display_header_footer: true
|
|
134
|
+
}
|
|
75
135
|
|
|
76
|
-
# Directory
|
|
136
|
+
# Directory the rendered HTML is temporarily written to before Chrome
|
|
137
|
+
# loads it (via a file:// URL, so relative asset paths resolve).
|
|
138
|
+
# Defaults to Rails.root/tmp.
|
|
77
139
|
config.tmp_dir = Rails.root.join("tmp", "pdfs")
|
|
140
|
+
|
|
141
|
+
# Only set this if pdf_options never flows from unfiltered request
|
|
142
|
+
# params in your app. Defaults to false. See Security.
|
|
143
|
+
# config.allow_request_templates = true
|
|
144
|
+
|
|
145
|
+
# Upper bound (ms) on a request-supplied javascript_delay, so one
|
|
146
|
+
# caller can't stall the shared browser pool for everyone. Defaults
|
|
147
|
+
# to 10_000.
|
|
148
|
+
# config.max_javascript_delay_ms = 10_000
|
|
78
149
|
end
|
|
79
150
|
|
|
80
|
-
|
|
151
|
+
A single headless Chrome process is started lazily and reused across requests in the same Ruby process (each conversion gets its own isolated browser context), since launching Chrome per-request is comparatively expensive. It's restarted automatically if Chrome crashes or stops responding. See [Architecture](docs/architecture.md#browserpool) for the design and its scaling limits.
|
|
152
|
+
|
|
153
|
+
##### Make sure you have configured your `asset_host` in application's Rails environment, otherwise assets might not be loaded properly — this is a bigger deal than it sounds for this gem specifically; see [the asset_host gotcha](docs/rails-integration.md#the-asset_host-gotcha).
|
|
81
154
|
|
|
82
155
|
`config.action_controller.asset_host = "YOUR_ASSETS_HOST"`
|
|
83
156
|
|
|
157
|
+
## Contributing
|
|
158
|
+
|
|
159
|
+
See [Contributing & Releasing](docs/contributing.md) for running the test suite and extending the
|
|
160
|
+
gem.
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
MIT — see [LICENSE.txt](LICENSE.txt).
|