pdfkit 0.8.4.3.2 → 0.8.7.3
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/release-drafter.yml +2 -2
- data/.github/workflows/test.yml +71 -0
- data/.ruby-version +1 -1
- data/.travis.yml +32 -2
- data/CHANGELOG.md +34 -0
- data/Gemfile +1 -1
- data/README.md +7 -2
- data/lib/pdfkit/configuration.rb +4 -2
- data/lib/pdfkit/html_preprocessor.rb +2 -0
- data/lib/pdfkit/middleware.rb +9 -6
- data/lib/pdfkit/os.rb +2 -0
- data/lib/pdfkit/pdfkit.rb +16 -15
- data/lib/pdfkit/source.rb +8 -4
- data/lib/pdfkit/version.rb +3 -1
- data/lib/pdfkit/wkhtmltopdf.rb +7 -5
- data/lib/pdfkit.rb +3 -0
- data/pdfkit.gemspec +4 -2
- data/spec/configuration_spec.rb +2 -0
- data/spec/html_preprocessor_spec.rb +2 -0
- data/spec/middleware_spec.rb +64 -39
- data/spec/os_spec.rb +2 -0
- data/spec/pdfkit_spec.rb +70 -42
- data/spec/source_spec.rb +7 -5
- data/spec/spec_helper.rb +15 -1
- metadata +12 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d5a276883efaa6bba1349d1077bee9ed23e466e48006d7b87a8e6c6ffbbd83bb
|
|
4
|
+
data.tar.gz: 33632dc0ae3a917efe7a4d227ea3f1ef52a2901f125b5102f687d8058c32a135
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8694cd8411e17b0a960a5a931f84960031a935bfdb2f6fc43b6b460c8434644694e0b8dd764fb151cb722b947c9775c9540bd2b5935a0bbb5021705bbe7f8b52
|
|
7
|
+
data.tar.gz: 55fdc04026f173baa10fc1f349323b243f6ef9d17142a9ab196cdc4302c2444e7a72dcf1ba68c31c3a953ab1559add63c257a1c5c1012e9a3216765ae386457e
|
|
@@ -12,8 +12,8 @@ jobs:
|
|
|
12
12
|
steps:
|
|
13
13
|
# Drafts your next Release notes as Pull Requests are merged into "master"
|
|
14
14
|
- uses: release-drafter/release-drafter@v5
|
|
15
|
-
with:
|
|
15
|
+
# with:
|
|
16
16
|
# (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
|
|
17
17
|
# config-name: my-config.yml
|
|
18
18
|
env:
|
|
19
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
19
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: Test workflow
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
test:
|
|
7
|
+
strategy:
|
|
8
|
+
fail-fast: false
|
|
9
|
+
matrix:
|
|
10
|
+
os: [ubuntu-latest]
|
|
11
|
+
ruby:
|
|
12
|
+
- '2.5'
|
|
13
|
+
- '2.6'
|
|
14
|
+
- '2.7'
|
|
15
|
+
- '3.0'
|
|
16
|
+
- '3.1'
|
|
17
|
+
rails:
|
|
18
|
+
- '~> 4.1'
|
|
19
|
+
- '~> 5.2'
|
|
20
|
+
- '~> 6.0.0'
|
|
21
|
+
- '~> 6.1'
|
|
22
|
+
- '~> 7.0.0'
|
|
23
|
+
exclude:
|
|
24
|
+
- ruby: '2.5'
|
|
25
|
+
rails: '~> 7.0.0'
|
|
26
|
+
- ruby: '2.6'
|
|
27
|
+
rails: '~> 7.0.0'
|
|
28
|
+
- ruby: '2.7'
|
|
29
|
+
rails: '~> 4.1'
|
|
30
|
+
- ruby: '3.0'
|
|
31
|
+
rails: '~> 4.1'
|
|
32
|
+
- ruby: '3.0'
|
|
33
|
+
rails: '~> 5.2'
|
|
34
|
+
- ruby: '3.1'
|
|
35
|
+
rails: '~> 4.1'
|
|
36
|
+
- ruby: '3.1'
|
|
37
|
+
rails: '~> 5.2'
|
|
38
|
+
- ruby: '3.1'
|
|
39
|
+
rails: '~> 6.0.0'
|
|
40
|
+
runs-on: ${{ matrix.os }}
|
|
41
|
+
env:
|
|
42
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v2
|
|
45
|
+
- uses: ruby/setup-ruby@v1
|
|
46
|
+
# rubygems-update's latest is no longer compatible with ruby 2.5, so conditionally run ruby-setup setting the
|
|
47
|
+
# rubygem version the most recent valid version for 2.5:
|
|
48
|
+
# https://rubygems.org/gems/rubygems-update/versions/3.3.26
|
|
49
|
+
if: ${{ matrix.ruby == '2.5' }}
|
|
50
|
+
with:
|
|
51
|
+
ruby-version: ${{ matrix.ruby }}
|
|
52
|
+
rubygems: 3.3.26
|
|
53
|
+
bundler: latest
|
|
54
|
+
bundler-cache: true
|
|
55
|
+
- uses: ruby/setup-ruby@v1
|
|
56
|
+
# otherwise, we can use rubygems latest
|
|
57
|
+
if: ${{ matrix.ruby != '2.5' }}
|
|
58
|
+
with:
|
|
59
|
+
ruby-version: ${{ matrix.ruby }}
|
|
60
|
+
rubygems: latest
|
|
61
|
+
bundler: latest
|
|
62
|
+
bundler-cache: true
|
|
63
|
+
|
|
64
|
+
- name: Setup wkhtmltopdf
|
|
65
|
+
run: |
|
|
66
|
+
sudo apt-get install -y xfonts-base xfonts-75dpi
|
|
67
|
+
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.bionic_amd64.deb
|
|
68
|
+
sudo dpkg -i wkhtmltox_0.12.6-1.bionic_amd64.deb
|
|
69
|
+
|
|
70
|
+
- name: Run tests
|
|
71
|
+
run: bundle exec rake
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.6.
|
|
1
|
+
2.6.9
|
data/.travis.yml
CHANGED
|
@@ -1,10 +1,40 @@
|
|
|
1
1
|
language: ruby
|
|
2
2
|
|
|
3
3
|
rvm:
|
|
4
|
-
- 2.3
|
|
5
|
-
- 2.4
|
|
6
4
|
- 2.5
|
|
7
5
|
- 2.6
|
|
6
|
+
- 2.7
|
|
7
|
+
- 3.0
|
|
8
|
+
- 3.1
|
|
9
|
+
|
|
10
|
+
env:
|
|
11
|
+
matrix:
|
|
12
|
+
- RAILS_VERSION="~> 4.1"
|
|
13
|
+
- RAILS_VERSION="~> 5.2"
|
|
14
|
+
- RAILS_VERSION="~> 6.0.0"
|
|
15
|
+
- RAILS_VERSION="~> 6.1"
|
|
16
|
+
- RAILS_VERSION="~> 7.0.0"
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
exclude:
|
|
20
|
+
- rvm: 2.5
|
|
21
|
+
env: RAILS_VERSION="~> 7.0.0"
|
|
22
|
+
- rvm: 2.6
|
|
23
|
+
env: RAILS_VERSION="~> 7.0.0"
|
|
24
|
+
- rvm: 2.7
|
|
25
|
+
env: RAILS_VERSION="~> 4.1"
|
|
26
|
+
- rvm: 3.0
|
|
27
|
+
env: RAILS_VERSION="~> 4.1"
|
|
28
|
+
- rvm: 3.0
|
|
29
|
+
env: RAILS_VERSION="~> 5.2"
|
|
30
|
+
- rvm: 3.1
|
|
31
|
+
env: RAILS_VERSION="~> 4.1"
|
|
32
|
+
- rvm: 3.1
|
|
33
|
+
env: RAILS_VERSION="~> 5.2"
|
|
34
|
+
- rvm: 3.1
|
|
35
|
+
env: RAILS_VERSION="~> 6.0.0"
|
|
36
|
+
|
|
37
|
+
cache: bundler
|
|
8
38
|
|
|
9
39
|
before_install:
|
|
10
40
|
- gem update --system
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,37 @@
|
|
|
1
|
+
2023-02-27
|
|
2
|
+
=================
|
|
3
|
+
* Bump to 0.8.7.3
|
|
4
|
+
* Allow passing a `Pathname` object to the `path` argument by @yujideveloper in https://github.com/pdfkit/pdfkit/pull/522
|
|
5
|
+
* Update repeatable options by @mguidetti in https://github.com/pdfkit/pdfkit/pull/524
|
|
6
|
+
|
|
7
|
+
2022-10-18
|
|
8
|
+
=================
|
|
9
|
+
* Bump to 0.8.7.2
|
|
10
|
+
* Call IO.popen with an Array of command arguments (#519)
|
|
11
|
+
|
|
12
|
+
2022-10-17
|
|
13
|
+
=================
|
|
14
|
+
* Bump to 0.8.7.1
|
|
15
|
+
* Support non-lower-case Content-Type header provided by app (#516)
|
|
16
|
+
|
|
17
|
+
2022-10-02
|
|
18
|
+
=================
|
|
19
|
+
* Bump to 0.8.7
|
|
20
|
+
* Lowercase the header names for rack 3 changes (#511)
|
|
21
|
+
* Partially escaped URLs should be escaped (#509)
|
|
22
|
+
|
|
23
|
+
2022-04-11
|
|
24
|
+
=================
|
|
25
|
+
* Bump to 0.8.6
|
|
26
|
+
* Update ruby and rails versions
|
|
27
|
+
|
|
28
|
+
2021-01-23
|
|
29
|
+
=================
|
|
30
|
+
* Bump to 0.8.5
|
|
31
|
+
* Make `PDFKit::VERSION` public (#484)
|
|
32
|
+
* Fix to render stylesheets as html safe string on Rails 6 (#483)
|
|
33
|
+
* Adds support for Rails 6
|
|
34
|
+
|
|
1
35
|
2020-08-16
|
|
2
36
|
=================
|
|
3
37
|
* Bump to 0.8.4.3.2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Create PDFs using plain old HTML+CSS. Uses [wkhtmltopdf](http://github.com/antialize/wkhtmltopdf) on the back-end which renders HTML using Webkit.
|
|
4
4
|
|
|
5
|
+
## Supported versions
|
|
6
|
+
|
|
7
|
+
- Ruby 2.5, 2.6, 2.7, 3.0, 3.1
|
|
8
|
+
- Rails 4.2, 5.2, 6.0, 6.1, 7.0
|
|
9
|
+
|
|
5
10
|
## Install
|
|
6
11
|
|
|
7
12
|
### PDFKit
|
|
@@ -58,7 +63,7 @@ PDFKit.new(html, protocol: 'https').to_file
|
|
|
58
63
|
```
|
|
59
64
|
|
|
60
65
|
### Using cookies in scraping
|
|
61
|
-
If you want to pass a cookie to
|
|
66
|
+
If you want to pass a cookie to pdfkit to scrape a website, you can
|
|
62
67
|
pass it in a hash:
|
|
63
68
|
```ruby
|
|
64
69
|
kit = PDFKit.new(url, cookie: {cookie_name: :cookie_value})
|
|
@@ -167,7 +172,7 @@ Will cause the .pdf to be saved to `path/to/saved.pdf` in addition to being sent
|
|
|
167
172
|
asset host.
|
|
168
173
|
|
|
169
174
|
* **Mangled output in the browser:** Be sure that your HTTP response
|
|
170
|
-
headers specify "
|
|
175
|
+
headers specify "content-type: application/pdf"
|
|
171
176
|
|
|
172
177
|
## Note on Patches/Pull Requests
|
|
173
178
|
|
data/lib/pdfkit/configuration.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
class PDFKit
|
|
2
4
|
class Configuration
|
|
3
5
|
attr_accessor :meta_tag_prefix, :root_url
|
|
@@ -26,7 +28,7 @@ class PDFKit
|
|
|
26
28
|
|
|
27
29
|
def default_wkhtmltopdf
|
|
28
30
|
return @default_command_path if @default_command_path
|
|
29
|
-
if defined?(Bundler::GemfileError) && File.
|
|
31
|
+
if defined?(Bundler::GemfileError) && File.exist?('Gemfile')
|
|
30
32
|
@default_command_path = `bundle exec which wkhtmltopdf`.chomp.lines.last
|
|
31
33
|
end
|
|
32
34
|
@default_command_path = `which wkhtmltopdf`.chomp if @default_command_path.nil? || @default_command_path.empty?
|
|
@@ -43,7 +45,7 @@ class PDFKit
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
def executable
|
|
46
|
-
using_xvfb? ?
|
|
48
|
+
using_xvfb? ? ['xvfb-run', wkhtmltopdf] : wkhtmltopdf
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def using_xvfb?
|
data/lib/pdfkit/middleware.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
class PDFKit
|
|
2
4
|
class Middleware
|
|
3
5
|
def initialize(app, options = {}, conditions = {})
|
|
@@ -20,7 +22,8 @@ class PDFKit
|
|
|
20
22
|
status, headers, response = @app.call(env)
|
|
21
23
|
|
|
22
24
|
begin
|
|
23
|
-
|
|
25
|
+
content_type_header = headers.has_key?('Content-Type') ? 'Content-Type' : 'content-type'
|
|
26
|
+
if rendering_pdf? && headers[content_type_header] =~ /text\/html|application\/xhtml\+xml/
|
|
24
27
|
body = response.respond_to?(:body) ? response.body : response.join
|
|
25
28
|
body = body.join if body.is_a?(Array)
|
|
26
29
|
|
|
@@ -42,13 +45,13 @@ class PDFKit
|
|
|
42
45
|
|
|
43
46
|
unless @caching
|
|
44
47
|
# Do not cache PDFs
|
|
45
|
-
headers.delete('
|
|
46
|
-
headers.delete('
|
|
48
|
+
headers.delete('etag')
|
|
49
|
+
headers.delete('cache-control')
|
|
47
50
|
end
|
|
48
51
|
|
|
49
|
-
headers['
|
|
50
|
-
headers[
|
|
51
|
-
headers['
|
|
52
|
+
headers['content-length'] = (body.respond_to?(:bytesize) ? body.bytesize : body.size).to_s
|
|
53
|
+
headers[content_type_header] = 'application/pdf'
|
|
54
|
+
headers['content-disposition'] ||= @conditions[:disposition] || 'inline'
|
|
52
55
|
end
|
|
53
56
|
rescue StandardError => e
|
|
54
57
|
status = 500
|
data/lib/pdfkit/os.rb
CHANGED
data/lib/pdfkit/pdfkit.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'shellwords'
|
|
2
4
|
require 'tempfile'
|
|
3
5
|
|
|
@@ -6,8 +8,8 @@ class PDFKit
|
|
|
6
8
|
|
|
7
9
|
class NoExecutableError < Error
|
|
8
10
|
def initialize
|
|
9
|
-
msg
|
|
10
|
-
|
|
11
|
+
msg = "No wkhtmltopdf executable found at #{PDFKit.configuration.wkhtmltopdf}\n" \
|
|
12
|
+
">> Please install wkhtmltopdf - https://github.com/pdfkit/PDFKit/wiki/Installing-WKHTMLTOPDF"
|
|
11
13
|
super(msg)
|
|
12
14
|
end
|
|
13
15
|
end
|
|
@@ -40,20 +42,15 @@ class PDFKit
|
|
|
40
42
|
@renderer = WkHTMLtoPDF.new options
|
|
41
43
|
@renderer.normalize_options
|
|
42
44
|
|
|
43
|
-
raise NoExecutableError unless File.
|
|
45
|
+
raise NoExecutableError unless File.exist?(PDFKit.configuration.wkhtmltopdf)
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
def command(path = nil)
|
|
47
|
-
args =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
# in the source. Please see https://github.com/pdfkit/pdfkit/issues/164.
|
|
53
|
-
input_for_command = @source.to_input_for_command
|
|
54
|
-
output_for_command = path ? Shellwords.shellescape(path) : '-'
|
|
55
|
-
|
|
56
|
-
"#{shell_escaped_command} #{input_for_command} #{output_for_command}"
|
|
49
|
+
args = [*executable]
|
|
50
|
+
args.concat(@renderer.options_for_command)
|
|
51
|
+
args << @source.to_input_for_command
|
|
52
|
+
args << (path ? path.to_s : '-')
|
|
53
|
+
args
|
|
57
54
|
end
|
|
58
55
|
|
|
59
56
|
def options
|
|
@@ -114,7 +111,9 @@ class PDFKit
|
|
|
114
111
|
end
|
|
115
112
|
|
|
116
113
|
def style_tag_for(stylesheet)
|
|
117
|
-
"<style>#{File.read(stylesheet)}</style>"
|
|
114
|
+
style = "<style>#{File.read(stylesheet)}</style>"
|
|
115
|
+
style = style.html_safe if style.respond_to?(:html_safe)
|
|
116
|
+
style
|
|
118
117
|
end
|
|
119
118
|
|
|
120
119
|
def preprocess_html
|
|
@@ -129,7 +128,9 @@ class PDFKit
|
|
|
129
128
|
|
|
130
129
|
stylesheets.each do |stylesheet|
|
|
131
130
|
if @source.to_s.match(/<\/head>/)
|
|
132
|
-
@source = Source.new(@source.to_s.gsub(/(<\/head>)/) {|s|
|
|
131
|
+
@source = Source.new(@source.to_s.gsub(/(<\/head>)/) {|s|
|
|
132
|
+
style_tag_for(stylesheet) + (s.respond_to?(:html_safe) ? s.html_safe : s)
|
|
133
|
+
})
|
|
133
134
|
else
|
|
134
135
|
@source.to_s.insert(0, style_tag_for(stylesheet))
|
|
135
136
|
end
|
data/lib/pdfkit/source.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'tempfile'
|
|
2
4
|
require 'uri'
|
|
3
5
|
|
|
@@ -7,6 +9,8 @@ class PDFKit
|
|
|
7
9
|
|
|
8
10
|
def initialize(url_file_or_html)
|
|
9
11
|
@source = url_file_or_html
|
|
12
|
+
# @source is assumed to be modifiable, so make sure it is.
|
|
13
|
+
@source = @source.dup if @source.is_a?(String) && @source.frozen?
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def url?
|
|
@@ -25,7 +29,7 @@ class PDFKit
|
|
|
25
29
|
if file?
|
|
26
30
|
@source.path
|
|
27
31
|
elsif url?
|
|
28
|
-
|
|
32
|
+
escaped_url
|
|
29
33
|
else
|
|
30
34
|
SOURCE_FROM_STDIN
|
|
31
35
|
end
|
|
@@ -37,12 +41,12 @@ class PDFKit
|
|
|
37
41
|
|
|
38
42
|
private
|
|
39
43
|
|
|
40
|
-
def
|
|
41
|
-
url_needs_escaping? ? URI::escape(@source) : @source
|
|
44
|
+
def escaped_url
|
|
45
|
+
url_needs_escaping? ? URI::DEFAULT_PARSER.escape(@source) : @source
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
def url_needs_escaping?
|
|
45
|
-
URI::
|
|
49
|
+
URI::DEFAULT_PARSER.escape(URI::DEFAULT_PARSER.unescape(@source)) != @source
|
|
46
50
|
end
|
|
47
51
|
end
|
|
48
52
|
end
|
data/lib/pdfkit/version.rb
CHANGED
data/lib/pdfkit/wkhtmltopdf.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
class PDFKit
|
|
2
4
|
class WkHTMLtoPDF
|
|
3
5
|
attr_reader :options
|
|
4
|
-
# Pulled from:
|
|
5
|
-
# https://github.com/wkhtmltopdf/wkhtmltopdf/blob/
|
|
6
|
-
REPEATABLE_OPTIONS = %w[--allow --cookie --custom-header --post --post-file --run-script]
|
|
7
|
-
SPECIAL_OPTIONS = %w[cover toc]
|
|
6
|
+
# Pulled from:
|
|
7
|
+
# https://github.com/wkhtmltopdf/wkhtmltopdf/blob/6a57c1449797d6cb915921fb747f3ac36199241f/docs/usage/wkhtmltopdf.txt#L104
|
|
8
|
+
REPEATABLE_OPTIONS = %w[--allow --bypass-proxy-for --cookie --custom-header --post --post-file --run-script --replace].freeze
|
|
9
|
+
SPECIAL_OPTIONS = %w[cover toc].freeze
|
|
8
10
|
|
|
9
11
|
def initialize(options)
|
|
10
12
|
@options = options
|
|
@@ -62,7 +64,7 @@ class PDFKit
|
|
|
62
64
|
when Array
|
|
63
65
|
value.flatten.collect{|x| x.to_s}
|
|
64
66
|
else
|
|
65
|
-
|
|
67
|
+
value.to_s
|
|
66
68
|
end
|
|
67
69
|
end
|
|
68
70
|
|
data/lib/pdfkit.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'pdfkit/source'
|
|
2
4
|
require 'pdfkit/pdfkit'
|
|
3
5
|
require 'pdfkit/middleware'
|
|
@@ -5,3 +7,4 @@ require 'pdfkit/html_preprocessor'
|
|
|
5
7
|
require 'pdfkit/os'
|
|
6
8
|
require 'pdfkit/configuration'
|
|
7
9
|
require 'pdfkit/wkhtmltopdf'
|
|
10
|
+
require 'pdfkit/version'
|
data/pdfkit.gemspec
CHANGED
|
@@ -18,13 +18,15 @@ Gem::Specification.new do |s|
|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
19
|
s.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
+
s.required_ruby_version = ">= 2.5"
|
|
22
|
+
|
|
21
23
|
s.requirements << "wkhtmltopdf"
|
|
22
24
|
|
|
23
25
|
# Development Dependencies
|
|
24
26
|
s.add_development_dependency(%q<activesupport>, [">= 4.1.11"])
|
|
25
27
|
s.add_development_dependency(%q<mocha>, [">= 0.9.10"])
|
|
26
28
|
s.add_development_dependency(%q<rack-test>, [">= 0.5.6"])
|
|
27
|
-
s.add_development_dependency(%q<rake>, ["
|
|
28
|
-
s.add_development_dependency(%q<rdoc>, ["
|
|
29
|
+
s.add_development_dependency(%q<rake>, [">= 12.3.3"])
|
|
30
|
+
s.add_development_dependency(%q<rdoc>, [">= 4.0.1"])
|
|
29
31
|
s.add_development_dependency(%q<rspec>, ["~> 3.0"])
|
|
30
32
|
end
|
data/spec/configuration_spec.rb
CHANGED
data/spec/middleware_spec.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
def app; Rack::Lint.new(@app); end
|
|
@@ -17,7 +19,7 @@ end
|
|
|
17
19
|
|
|
18
20
|
describe PDFKit::Middleware do
|
|
19
21
|
let(:headers) do
|
|
20
|
-
{'
|
|
22
|
+
{'content-type' => "text/html"}
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
describe "#call" do
|
|
@@ -53,36 +55,36 @@ describe PDFKit::Middleware do
|
|
|
53
55
|
describe "caching" do
|
|
54
56
|
let(:headers) do
|
|
55
57
|
{
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
'
|
|
58
|
+
'content-type' => "text/html",
|
|
59
|
+
'etag' => 'foo',
|
|
60
|
+
'cache-control' => 'max-age=2592000, public'
|
|
59
61
|
}
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
context "by default" do
|
|
63
65
|
before { mock_app }
|
|
64
66
|
|
|
65
|
-
it "deletes
|
|
67
|
+
it "deletes etag" do
|
|
66
68
|
get 'http://www.example.org/public/test.pdf'
|
|
67
|
-
expect(last_response.headers["
|
|
69
|
+
expect(last_response.headers["etag"]).to be_nil
|
|
68
70
|
end
|
|
69
|
-
it "deletes
|
|
71
|
+
it "deletes cache-control" do
|
|
70
72
|
get 'http://www.example.org/public/test.pdf'
|
|
71
|
-
expect(last_response.headers["
|
|
73
|
+
expect(last_response.headers["cache-control"]).to be_nil
|
|
72
74
|
end
|
|
73
75
|
end
|
|
74
76
|
|
|
75
77
|
context "when on" do
|
|
76
78
|
before { mock_app({}, :caching => true) }
|
|
77
79
|
|
|
78
|
-
it "preserves
|
|
80
|
+
it "preserves etag" do
|
|
79
81
|
get 'http://www.example.org/public/test.pdf'
|
|
80
|
-
expect(last_response.headers["
|
|
82
|
+
expect(last_response.headers["etag"]).not_to be_nil
|
|
81
83
|
end
|
|
82
84
|
|
|
83
|
-
it "preserves
|
|
85
|
+
it "preserves cache-control" do
|
|
84
86
|
get 'http://www.example.org/public/test.pdf'
|
|
85
|
-
expect(last_response.headers["
|
|
87
|
+
expect(last_response.headers["cache-control"]).not_to be_nil
|
|
86
88
|
end
|
|
87
89
|
end
|
|
88
90
|
end
|
|
@@ -97,7 +99,7 @@ describe PDFKit::Middleware do
|
|
|
97
99
|
context "matching" do
|
|
98
100
|
specify do
|
|
99
101
|
get 'http://www.example.org/public/test.pdf'
|
|
100
|
-
expect(last_response.headers["
|
|
102
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
101
103
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
|
102
104
|
end
|
|
103
105
|
end
|
|
@@ -105,7 +107,7 @@ describe PDFKit::Middleware do
|
|
|
105
107
|
context "not matching" do
|
|
106
108
|
specify do
|
|
107
109
|
get 'http://www.example.org/secret/test.pdf'
|
|
108
|
-
expect(last_response.headers["
|
|
110
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
|
109
111
|
expect(last_response.body).to eq("Hello world!")
|
|
110
112
|
end
|
|
111
113
|
end
|
|
@@ -117,7 +119,7 @@ describe PDFKit::Middleware do
|
|
|
117
119
|
context "matching" do
|
|
118
120
|
specify do
|
|
119
121
|
get 'http://www.example.org/public/test.pdf'
|
|
120
|
-
expect(last_response.headers["
|
|
122
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
121
123
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
|
122
124
|
end
|
|
123
125
|
end
|
|
@@ -125,7 +127,7 @@ describe PDFKit::Middleware do
|
|
|
125
127
|
context "not matching" do
|
|
126
128
|
specify do
|
|
127
129
|
get 'http://www.example.org/secret/test.pdf'
|
|
128
|
-
expect(last_response.headers["
|
|
130
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
|
129
131
|
expect(last_response.body).to eq("Hello world!")
|
|
130
132
|
end
|
|
131
133
|
end
|
|
@@ -139,7 +141,7 @@ describe PDFKit::Middleware do
|
|
|
139
141
|
context "matching" do
|
|
140
142
|
specify do
|
|
141
143
|
get 'http://www.example.org/public/test.pdf'
|
|
142
|
-
expect(last_response.headers["
|
|
144
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
143
145
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
|
144
146
|
end
|
|
145
147
|
end
|
|
@@ -147,7 +149,7 @@ describe PDFKit::Middleware do
|
|
|
147
149
|
context "not matching" do
|
|
148
150
|
specify do
|
|
149
151
|
get 'http://www.example.org/secret/test.pdf'
|
|
150
|
-
expect(last_response.headers["
|
|
152
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
|
151
153
|
expect(last_response.body).to eq("Hello world!")
|
|
152
154
|
end
|
|
153
155
|
end
|
|
@@ -159,7 +161,7 @@ describe PDFKit::Middleware do
|
|
|
159
161
|
context "matching" do
|
|
160
162
|
specify do
|
|
161
163
|
get 'http://www.example.org/public/test.pdf'
|
|
162
|
-
expect(last_response.headers["
|
|
164
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
163
165
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
|
164
166
|
end
|
|
165
167
|
end
|
|
@@ -167,7 +169,7 @@ describe PDFKit::Middleware do
|
|
|
167
169
|
context "not matching" do
|
|
168
170
|
specify do
|
|
169
171
|
get 'http://www.example.org/secret/test.pdf'
|
|
170
|
-
expect(last_response.headers["
|
|
172
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
|
171
173
|
expect(last_response.body).to eq("Hello world!")
|
|
172
174
|
end
|
|
173
175
|
end
|
|
@@ -185,7 +187,7 @@ describe PDFKit::Middleware do
|
|
|
185
187
|
context "matching" do
|
|
186
188
|
specify do
|
|
187
189
|
get 'http://www.example.org/public/test.pdf'
|
|
188
|
-
expect(last_response.headers["
|
|
190
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
189
191
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
|
190
192
|
end
|
|
191
193
|
end
|
|
@@ -193,7 +195,7 @@ describe PDFKit::Middleware do
|
|
|
193
195
|
context "not matching" do
|
|
194
196
|
specify do
|
|
195
197
|
get 'http://www.example.org/secret/test.pdf'
|
|
196
|
-
expect(last_response.headers["
|
|
198
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
|
197
199
|
expect(last_response.body).to eq("Hello world!")
|
|
198
200
|
end
|
|
199
201
|
end
|
|
@@ -205,7 +207,7 @@ describe PDFKit::Middleware do
|
|
|
205
207
|
context "matching" do
|
|
206
208
|
specify do
|
|
207
209
|
get 'http://www.example.org/public/test.pdf'
|
|
208
|
-
expect(last_response.headers["
|
|
210
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
209
211
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
|
210
212
|
end
|
|
211
213
|
end
|
|
@@ -213,7 +215,7 @@ describe PDFKit::Middleware do
|
|
|
213
215
|
context "not matching" do
|
|
214
216
|
specify do
|
|
215
217
|
get 'http://www.example.org/secret/test.pdf'
|
|
216
|
-
expect(last_response.headers["
|
|
218
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
|
217
219
|
expect(last_response.body).to eq("Hello world!")
|
|
218
220
|
end
|
|
219
221
|
end
|
|
@@ -227,7 +229,7 @@ describe PDFKit::Middleware do
|
|
|
227
229
|
context "matching" do
|
|
228
230
|
specify do
|
|
229
231
|
get 'http://www.example.org/public/test.pdf'
|
|
230
|
-
expect(last_response.headers["
|
|
232
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
231
233
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
|
232
234
|
end
|
|
233
235
|
end
|
|
@@ -235,7 +237,7 @@ describe PDFKit::Middleware do
|
|
|
235
237
|
context "not matching" do
|
|
236
238
|
specify do
|
|
237
239
|
get 'http://www.example.org/secret/test.pdf'
|
|
238
|
-
expect(last_response.headers["
|
|
240
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
|
239
241
|
expect(last_response.body).to eq("Hello world!")
|
|
240
242
|
end
|
|
241
243
|
end
|
|
@@ -247,7 +249,7 @@ describe PDFKit::Middleware do
|
|
|
247
249
|
context "matching" do
|
|
248
250
|
specify do
|
|
249
251
|
get 'http://www.example.org/public/test.pdf'
|
|
250
|
-
expect(last_response.headers["
|
|
252
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
251
253
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
|
252
254
|
end
|
|
253
255
|
end
|
|
@@ -255,7 +257,7 @@ describe PDFKit::Middleware do
|
|
|
255
257
|
context "not matching" do
|
|
256
258
|
specify do
|
|
257
259
|
get 'http://www.example.org/secret/test.pdf'
|
|
258
|
-
expect(last_response.headers["
|
|
260
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
|
259
261
|
expect(last_response.body).to eq("Hello world!")
|
|
260
262
|
end
|
|
261
263
|
end
|
|
@@ -267,8 +269,8 @@ describe PDFKit::Middleware do
|
|
|
267
269
|
describe "saving generated pdf to disk" do
|
|
268
270
|
before do
|
|
269
271
|
#make sure tests don't find an old test_save.pdf
|
|
270
|
-
File.delete('spec/test_save.pdf') if File.
|
|
271
|
-
expect(File.
|
|
272
|
+
File.delete('spec/test_save.pdf') if File.exist?('spec/test_save.pdf')
|
|
273
|
+
expect(File.exist?('spec/test_save.pdf')).to eq(false)
|
|
272
274
|
end
|
|
273
275
|
|
|
274
276
|
context "when header PDFKit-save-pdf is present" do
|
|
@@ -276,7 +278,7 @@ describe PDFKit::Middleware do
|
|
|
276
278
|
headers = { 'PDFKit-save-pdf' => 'spec/test_save.pdf' }
|
|
277
279
|
mock_app({}, {only: '/public'}, headers)
|
|
278
280
|
get 'http://www.example.org/public/test_save.pdf'
|
|
279
|
-
expect(File.
|
|
281
|
+
expect(File.exist?('spec/test_save.pdf')).to eq(true)
|
|
280
282
|
end
|
|
281
283
|
|
|
282
284
|
it "does not raise when target directory does not exist" do
|
|
@@ -292,7 +294,7 @@ describe PDFKit::Middleware do
|
|
|
292
294
|
it "does not saved the .pdf to disk" do
|
|
293
295
|
mock_app({}, {only: '/public'}, {} )
|
|
294
296
|
get 'http://www.example.org/public/test_save.pdf'
|
|
295
|
-
expect(File.
|
|
297
|
+
expect(File.exist?('spec/test_save.pdf')).to eq(false)
|
|
296
298
|
end
|
|
297
299
|
end
|
|
298
300
|
end
|
|
@@ -346,14 +348,14 @@ describe PDFKit::Middleware do
|
|
|
346
348
|
describe "doesn't overwrite existing value" do
|
|
347
349
|
let(:headers) do
|
|
348
350
|
super().merge({
|
|
349
|
-
'
|
|
351
|
+
'content-disposition' => 'attachment; filename=report-20200101.pdf'
|
|
350
352
|
})
|
|
351
353
|
end
|
|
352
354
|
|
|
353
355
|
specify do
|
|
354
356
|
mock_app({}, { :disposition => 'inline' })
|
|
355
357
|
get 'http://www.example.org/public/test.pdf'
|
|
356
|
-
expect(last_response.headers["
|
|
358
|
+
expect(last_response.headers["content-disposition"]).to eq('attachment; filename=report-20200101.pdf')
|
|
357
359
|
end
|
|
358
360
|
end
|
|
359
361
|
|
|
@@ -362,7 +364,7 @@ describe PDFKit::Middleware do
|
|
|
362
364
|
specify do
|
|
363
365
|
mock_app
|
|
364
366
|
get 'http://www.example.org/public/test.pdf'
|
|
365
|
-
expect(last_response.headers["
|
|
367
|
+
expect(last_response.headers["content-disposition"]).to eq("inline")
|
|
366
368
|
end
|
|
367
369
|
end
|
|
368
370
|
|
|
@@ -370,7 +372,7 @@ describe PDFKit::Middleware do
|
|
|
370
372
|
specify do
|
|
371
373
|
mock_app({}, { :disposition => 'inline' })
|
|
372
374
|
get 'http://www.example.org/public/test.pdf'
|
|
373
|
-
expect(last_response.headers["
|
|
375
|
+
expect(last_response.headers["content-disposition"]).to eq("inline")
|
|
374
376
|
end
|
|
375
377
|
end
|
|
376
378
|
end
|
|
@@ -380,7 +382,7 @@ describe PDFKit::Middleware do
|
|
|
380
382
|
specify do
|
|
381
383
|
mock_app({}, { :disposition => 'attachment' })
|
|
382
384
|
get 'http://www.example.org/public/test.pdf'
|
|
383
|
-
expect(last_response.headers["
|
|
385
|
+
expect(last_response.headers["content-disposition"]).to eq("attachment")
|
|
384
386
|
end
|
|
385
387
|
end
|
|
386
388
|
|
|
@@ -388,7 +390,7 @@ describe PDFKit::Middleware do
|
|
|
388
390
|
specify do
|
|
389
391
|
mock_app({}, { :disposition => 'attachment; filename=report.pdf' })
|
|
390
392
|
get 'http://www.example.org/public/test.pdf'
|
|
391
|
-
expect(last_response.headers["
|
|
393
|
+
expect(last_response.headers["content-disposition"]).to eq("attachment; filename=report.pdf")
|
|
392
394
|
end
|
|
393
395
|
end
|
|
394
396
|
end
|
|
@@ -420,6 +422,29 @@ describe PDFKit::Middleware do
|
|
|
420
422
|
end
|
|
421
423
|
end
|
|
422
424
|
|
|
425
|
+
describe "content type header" do
|
|
426
|
+
before { mock_app }
|
|
427
|
+
|
|
428
|
+
context "lower case" do
|
|
429
|
+
specify "header gets correctly updated" do
|
|
430
|
+
get 'http://www.example.org/public/test.pdf'
|
|
431
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
context "mixed case" do
|
|
436
|
+
let(:headers) do
|
|
437
|
+
{'Content-Type' => "text/html"}
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
specify "header gets correctly updated" do
|
|
441
|
+
pending("this test only applies to rack 2.x and is rejected by rack 3.x") if Rack.release >= "3.0.0"
|
|
442
|
+
get 'http://www.example.org/public/test.pdf'
|
|
443
|
+
expect(last_response.headers["Content-Type"]).to eq("application/pdf")
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
423
448
|
describe "remove .pdf from PATH_INFO and REQUEST_URI" do
|
|
424
449
|
before { mock_app }
|
|
425
450
|
|
|
@@ -444,7 +469,7 @@ describe PDFKit::Middleware do
|
|
|
444
469
|
main_app = lambda { |env|
|
|
445
470
|
@env = env
|
|
446
471
|
@env['SCRIPT_NAME'] = '/example.org'
|
|
447
|
-
headers = {'
|
|
472
|
+
headers = {'content-type' => "text/html"}
|
|
448
473
|
[200, headers, @body || ['Hello world!']]
|
|
449
474
|
}
|
|
450
475
|
|
data/spec/os_spec.rb
CHANGED
data/spec/pdfkit_spec.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#encoding: UTF-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
2
4
|
require 'spec_helper'
|
|
3
5
|
|
|
4
6
|
describe PDFKit do
|
|
@@ -27,7 +29,7 @@ describe PDFKit do
|
|
|
27
29
|
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
|
28
30
|
pdfkit = PDFKit.new(Tempfile.new(file_path))
|
|
29
31
|
expect(pdfkit.source).to be_file
|
|
30
|
-
expect(pdfkit.source.to_s).to match
|
|
32
|
+
expect(pdfkit.source.to_s).to match(/^#{Dir.tmpdir}/)
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
# Options
|
|
@@ -43,8 +45,8 @@ describe PDFKit do
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
it "transforms complex keys into command-line arguments" do
|
|
46
|
-
pdfkit = PDFKit.new('html', :
|
|
47
|
-
expect(pdfkit.options).to have_key('--
|
|
48
|
+
pdfkit = PDFKit.new('html', :header_left => {'value' => 'something else'} )
|
|
49
|
+
expect(pdfkit.options).to have_key('--header-left')
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
it "drops options with false or falsey values" do
|
|
@@ -70,8 +72,8 @@ describe PDFKit do
|
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
it "parses hash option values into an array" do
|
|
73
|
-
pdfkit = PDFKit.new('html', :
|
|
74
|
-
expect(pdfkit.options['--
|
|
75
|
+
pdfkit = PDFKit.new('html', :header_left => {'value' => 'something else'} )
|
|
76
|
+
expect(pdfkit.options['--header-left']).to eql ['value', 'something else']
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
it "flattens hash options into the key" do
|
|
@@ -82,8 +84,8 @@ describe PDFKit do
|
|
|
82
84
|
end
|
|
83
85
|
|
|
84
86
|
it "parses array option values into a string" do
|
|
85
|
-
pdfkit = PDFKit.new('html', :
|
|
86
|
-
expect(pdfkit.options['--
|
|
87
|
+
pdfkit = PDFKit.new('html', :header_left => ['value', 'something else'] )
|
|
88
|
+
expect(pdfkit.options['--header-left']).to eql ['value', 'something else']
|
|
87
89
|
end
|
|
88
90
|
|
|
89
91
|
it "flattens array options" do
|
|
@@ -173,22 +175,36 @@ describe PDFKit do
|
|
|
173
175
|
it "constructs the correct command" do
|
|
174
176
|
pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12, :replace => {'foo' => 'bar'})
|
|
175
177
|
command = pdfkit.command
|
|
176
|
-
expect(command).to
|
|
177
|
-
expect(command).to
|
|
178
|
-
expect(command).to
|
|
179
|
-
expect(command).to
|
|
178
|
+
expect(command.first).to match(/wkhtmltopdf/)
|
|
179
|
+
expect(command).to contain %w[--page-size Letter]
|
|
180
|
+
expect(command).to contain %w[--toc-l1-font-size 12]
|
|
181
|
+
expect(command).to contain %w[--replace foo bar]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "contains a specified by path argument" do
|
|
185
|
+
pdfkit = PDFKit.new('html')
|
|
186
|
+
command = pdfkit.command("/foo/bar")
|
|
187
|
+
expect(command.first).to match(/wkhtmltopdf/)
|
|
188
|
+
expect(command.last).to eq("/foo/bar")
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "contains a specified by path argument of Pathname" do
|
|
192
|
+
pdfkit = PDFKit.new('html')
|
|
193
|
+
command = pdfkit.command(Pathname.new("/foo/bar"))
|
|
194
|
+
expect(command.first).to match(/wkhtmltopdf/)
|
|
195
|
+
expect(command.last).to eq("/foo/bar")
|
|
180
196
|
end
|
|
181
197
|
|
|
182
198
|
it "sets up one cookie when hash has only one cookie" do
|
|
183
199
|
pdfkit = PDFKit.new('html', cookie: {cookie_name: :cookie_value})
|
|
184
200
|
command = pdfkit.command
|
|
185
|
-
expect(command).to
|
|
201
|
+
expect(command).to contain %w[--cookie cookie_name cookie_value]
|
|
186
202
|
end
|
|
187
203
|
|
|
188
|
-
it "does not
|
|
204
|
+
it "does not split Windows paths that contain spaces" do
|
|
189
205
|
pdfkit = PDFKit.new('html')
|
|
190
206
|
allow(PDFKit.configuration).to receive(:wkhtmltopdf).and_return 'c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe'
|
|
191
|
-
expect(pdfkit.command).not_to
|
|
207
|
+
expect(pdfkit.command).not_to contain(%w[c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe])
|
|
192
208
|
end
|
|
193
209
|
|
|
194
210
|
it "does not shell escape source URLs" do
|
|
@@ -205,15 +221,15 @@ describe PDFKit do
|
|
|
205
221
|
it "sets up multiple cookies when passed multiple cookies" do
|
|
206
222
|
pdfkit = PDFKit.new('html', :cookie => {:cookie_name1 => :cookie_val1, :cookie_name2 => :cookie_val2})
|
|
207
223
|
command = pdfkit.command
|
|
208
|
-
expect(command).to
|
|
209
|
-
expect(command).to
|
|
224
|
+
expect(command).to contain %w[--cookie cookie_name1 cookie_val1]
|
|
225
|
+
expect(command).to contain %w[--cookie cookie_name2 cookie_val2]
|
|
210
226
|
end
|
|
211
227
|
|
|
212
228
|
it "sets up multiple cookies when passed an array of tuples" do
|
|
213
229
|
pdfkit = PDFKit.new('html', :cookie => [[:cookie_name1, :cookie_val1], [:cookie_name2, :cookie_val2]])
|
|
214
230
|
command = pdfkit.command
|
|
215
|
-
expect(command).to
|
|
216
|
-
expect(command).to
|
|
231
|
+
expect(command).to contain %w[--cookie cookie_name1 cookie_val1]
|
|
232
|
+
expect(command).to contain %w[--cookie cookie_name2 cookie_val2]
|
|
217
233
|
end
|
|
218
234
|
|
|
219
235
|
it "will not include default options it is told to omit" do
|
|
@@ -227,48 +243,57 @@ describe PDFKit do
|
|
|
227
243
|
expect(pdfkit.command).not_to include('--disable-smart-shrinking')
|
|
228
244
|
end
|
|
229
245
|
|
|
230
|
-
it "
|
|
246
|
+
it "must not split string arguments containing spaces" do
|
|
231
247
|
pdfkit = PDFKit.new('html', :header_center => "foo [page]")
|
|
232
|
-
expect(pdfkit.command).to
|
|
248
|
+
expect(pdfkit.command).to contain ['--header-center', 'foo [page]']
|
|
233
249
|
end
|
|
234
250
|
|
|
235
|
-
it "
|
|
251
|
+
it "paramatarizes string arguments" do
|
|
236
252
|
pdfkit = PDFKit.new('html', :header_center => "$(ls)")
|
|
237
|
-
expect(pdfkit.command).to
|
|
253
|
+
expect(pdfkit.command).to contain %w[--header-center $(ls)]
|
|
238
254
|
end
|
|
239
255
|
|
|
240
256
|
it "read the source from stdin if it is html" do
|
|
241
257
|
pdfkit = PDFKit.new('html')
|
|
242
|
-
|
|
258
|
+
command = pdfkit.command
|
|
259
|
+
expect(command[-2]).to eq('-')
|
|
260
|
+
expect(command[-1]).to eq('-')
|
|
243
261
|
end
|
|
244
262
|
|
|
245
263
|
it "specifies the URL to the source if it is a url" do
|
|
246
264
|
pdfkit = PDFKit.new('http://google.com')
|
|
247
|
-
|
|
265
|
+
command = pdfkit.command
|
|
266
|
+
expect(command[-2]).to eq("http://google.com")
|
|
267
|
+
expect(command[-1]).to eq("-")
|
|
248
268
|
end
|
|
249
269
|
|
|
250
270
|
it "does not break Windows paths" do
|
|
251
271
|
pdfkit = PDFKit.new('html')
|
|
252
272
|
allow(PDFKit.configuration).to receive(:wkhtmltopdf).and_return 'c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe'
|
|
253
|
-
expect(pdfkit.command).not_to
|
|
273
|
+
expect(pdfkit.command).not_to contain ['Program', 'Files']
|
|
254
274
|
end
|
|
255
275
|
|
|
256
276
|
it "specifies the path to the source if it is a file" do
|
|
257
277
|
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
|
258
278
|
pdfkit = PDFKit.new(File.new(file_path))
|
|
259
|
-
|
|
279
|
+
command = pdfkit.command
|
|
280
|
+
expect(command[-2]).to eq(file_path)
|
|
281
|
+
expect(command[-1]).to eq('-')
|
|
260
282
|
end
|
|
261
283
|
|
|
262
284
|
it "specifies the path to the source if it is a tempfile" do
|
|
263
285
|
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
|
264
286
|
pdfkit = PDFKit.new(Tempfile.new(file_path))
|
|
265
|
-
|
|
287
|
+
command = pdfkit.command
|
|
288
|
+
expect(command[-2]).to start_with(Dir.tmpdir)
|
|
289
|
+
expect(command[-1]).to eq('-')
|
|
266
290
|
end
|
|
267
291
|
|
|
268
292
|
it "specifies the path for the ouput if a path is given" do
|
|
269
293
|
file_path = "/path/to/output.pdf"
|
|
270
294
|
pdfkit = PDFKit.new("html")
|
|
271
|
-
|
|
295
|
+
command = pdfkit.command(file_path)
|
|
296
|
+
expect(command.last).to eq(file_path)
|
|
272
297
|
end
|
|
273
298
|
|
|
274
299
|
it "detects special pdfkit meta tags" do
|
|
@@ -282,8 +307,8 @@ describe PDFKit do
|
|
|
282
307
|
}
|
|
283
308
|
pdfkit = PDFKit.new(body)
|
|
284
309
|
command = pdfkit.command
|
|
285
|
-
expect(command).to
|
|
286
|
-
expect(command).to
|
|
310
|
+
expect(command).to contain %w[--page-size Legal]
|
|
311
|
+
expect(command).to contain %w[--orientation Landscape]
|
|
287
312
|
end
|
|
288
313
|
|
|
289
314
|
it "detects cookies meta tag" do
|
|
@@ -297,7 +322,7 @@ describe PDFKit do
|
|
|
297
322
|
}
|
|
298
323
|
pdfkit = PDFKit.new(body)
|
|
299
324
|
command = pdfkit.command
|
|
300
|
-
expect(command).to
|
|
325
|
+
expect(command).to contain %w[--cookie rails_session rails_session_value --cookie cookie_variable cookie_variable_value]
|
|
301
326
|
end
|
|
302
327
|
|
|
303
328
|
it "detects disable_smart_shrinking meta tag" do
|
|
@@ -311,7 +336,7 @@ describe PDFKit do
|
|
|
311
336
|
pdfkit = PDFKit.new(body)
|
|
312
337
|
command = pdfkit.command
|
|
313
338
|
expect(command).to include "--disable-smart-shrinking"
|
|
314
|
-
expect(command).not_to
|
|
339
|
+
expect(command).not_to contain %w[--disable-smart-shrinking true]
|
|
315
340
|
end
|
|
316
341
|
|
|
317
342
|
it "detects names with hyphens instead of underscores" do
|
|
@@ -340,8 +365,8 @@ describe PDFKit do
|
|
|
340
365
|
}
|
|
341
366
|
pdfkit = PDFKit.new(body)
|
|
342
367
|
command = pdfkit.command
|
|
343
|
-
expect(command).to
|
|
344
|
-
expect(command).to
|
|
368
|
+
expect(command).to contain %w[--page-size Legal]
|
|
369
|
+
expect(command).to contain %w[--orientation Landscape]
|
|
345
370
|
end
|
|
346
371
|
|
|
347
372
|
it "skips non-pdfkit meta tags" do
|
|
@@ -356,8 +381,8 @@ describe PDFKit do
|
|
|
356
381
|
}
|
|
357
382
|
pdfkit = PDFKit.new(body)
|
|
358
383
|
command = pdfkit.command
|
|
359
|
-
expect(command).not_to
|
|
360
|
-
expect(command).to
|
|
384
|
+
expect(command).not_to contain %w[--page-size Legal]
|
|
385
|
+
expect(command).to contain %w[--orientation Landscape]
|
|
361
386
|
end
|
|
362
387
|
|
|
363
388
|
it "does not use quiet when told to" do
|
|
@@ -420,14 +445,9 @@ describe PDFKit do
|
|
|
420
445
|
allow(PDFKit::OS).to receive(:host_is_windows?).and_return(true)
|
|
421
446
|
end
|
|
422
447
|
|
|
423
|
-
it "escapes special windows characters" do
|
|
424
|
-
pdf = PDFKit.new('html', :title => 'hello(world)')
|
|
425
|
-
expect(pdf.command).to include 'hello^(world^)'
|
|
426
|
-
end
|
|
427
|
-
|
|
428
448
|
it "quotes spaces in options" do
|
|
429
449
|
pdf = PDFKit.new('html', :title => 'hello world')
|
|
430
|
-
expect(pdf.command).to
|
|
450
|
+
expect(pdf.command).to contain ['--title', "hello world"]
|
|
431
451
|
end
|
|
432
452
|
end
|
|
433
453
|
end
|
|
@@ -501,6 +521,14 @@ describe PDFKit do
|
|
|
501
521
|
expect(pdfkit.source.to_s).to include("<style>#{File.read(css)}</style></head>")
|
|
502
522
|
end
|
|
503
523
|
|
|
524
|
+
it "can deal with ActiveSupport::SafeBuffer if the HTML doesn't have a head tag" do
|
|
525
|
+
pdfkit = PDFKit.new(ActiveSupport::SafeBuffer.new "<html><body>Hai!</body></html>")
|
|
526
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
|
527
|
+
pdfkit.stylesheets << css
|
|
528
|
+
pdfkit.to_pdf
|
|
529
|
+
expect(pdfkit.source.to_s).to include("<style>#{File.read(css)}</style>")
|
|
530
|
+
end
|
|
531
|
+
|
|
504
532
|
it "escapes \\X in stylesheets" do
|
|
505
533
|
pdfkit = PDFKit.new("<html><head></head><body>Hai!</body></html>")
|
|
506
534
|
css = File.join(SPEC_ROOT,'fixtures','example_with_hex_symbol.css')
|
data/spec/source_spec.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
describe PDFKit::Source do
|
|
@@ -73,14 +75,14 @@ describe PDFKit::Source do
|
|
|
73
75
|
end
|
|
74
76
|
|
|
75
77
|
describe "#to_input_for_command" do
|
|
76
|
-
it "URI escapes source
|
|
77
|
-
source = PDFKit::Source.new("https://www.google.com/search?q=
|
|
78
|
-
expect(source.to_input_for_command).to eq "
|
|
78
|
+
it "URI escapes source URI" do
|
|
79
|
+
source = PDFKit::Source.new("https://www.google.com/search?q=foo bar")
|
|
80
|
+
expect(source.to_input_for_command).to eq "https://www.google.com/search?q=foo%20bar"
|
|
79
81
|
end
|
|
80
82
|
|
|
81
83
|
it "does not URI escape previously escaped source URLs" do
|
|
82
|
-
source = PDFKit::Source.new("https://www.google.com/search?q=
|
|
83
|
-
expect(source.to_input_for_command).to eq "
|
|
84
|
+
source = PDFKit::Source.new("https://www.google.com/search?q=foo%20bar")
|
|
85
|
+
expect(source.to_input_for_command).to eq "https://www.google.com/search?q=foo%20bar"
|
|
84
86
|
end
|
|
85
87
|
|
|
86
88
|
it "returns a '-' for HTML strings to indicate that we send that content through STDIN" do
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
SPEC_ROOT = File.dirname(__FILE__)
|
|
2
4
|
$LOAD_PATH.unshift(SPEC_ROOT)
|
|
3
5
|
$LOAD_PATH.unshift(File.join(SPEC_ROOT, '..', 'lib'))
|
|
@@ -6,14 +8,26 @@ SimpleCov.start do
|
|
|
6
8
|
add_filter 'spec/'
|
|
7
9
|
end
|
|
8
10
|
|
|
11
|
+
Warning[:deprecated] = true if defined?(Warning.[]=)
|
|
12
|
+
|
|
9
13
|
require 'pdfkit'
|
|
10
14
|
require 'rspec'
|
|
11
15
|
require 'mocha'
|
|
12
16
|
require 'rack'
|
|
13
17
|
require 'rack/test'
|
|
14
18
|
require 'active_support'
|
|
15
|
-
require 'custom_wkhtmltopdf_path' if File.
|
|
19
|
+
require 'custom_wkhtmltopdf_path' if File.exist?(File.join(SPEC_ROOT, 'custom_wkhtmltopdf_path.rb'))
|
|
16
20
|
|
|
17
21
|
RSpec.configure do |config|
|
|
18
22
|
include Rack::Test::Methods
|
|
19
23
|
end
|
|
24
|
+
|
|
25
|
+
RSpec::Matchers.define :contain do |expected|
|
|
26
|
+
match do |actual|
|
|
27
|
+
(0..(actual.length - expected.length)).any? do |base_index|
|
|
28
|
+
expected.each_with_index.all? do |expected_element,index|
|
|
29
|
+
actual[base_index+index] == expected_element
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pdfkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.7.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jared Pace
|
|
8
8
|
- Relevance
|
|
9
|
-
autorequire:
|
|
9
|
+
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2023-05-30 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activesupport
|
|
@@ -57,28 +57,28 @@ dependencies:
|
|
|
57
57
|
name: rake
|
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
|
59
59
|
requirements:
|
|
60
|
-
- - "
|
|
60
|
+
- - ">="
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
62
|
version: 12.3.3
|
|
63
63
|
type: :development
|
|
64
64
|
prerelease: false
|
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
66
|
requirements:
|
|
67
|
-
- - "
|
|
67
|
+
- - ">="
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
69
|
version: 12.3.3
|
|
70
70
|
- !ruby/object:Gem::Dependency
|
|
71
71
|
name: rdoc
|
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
|
73
73
|
requirements:
|
|
74
|
-
- - "
|
|
74
|
+
- - ">="
|
|
75
75
|
- !ruby/object:Gem::Version
|
|
76
76
|
version: 4.0.1
|
|
77
77
|
type: :development
|
|
78
78
|
prerelease: false
|
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
|
80
80
|
requirements:
|
|
81
|
-
- - "
|
|
81
|
+
- - ">="
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
83
|
version: 4.0.1
|
|
84
84
|
- !ruby/object:Gem::Dependency
|
|
@@ -105,6 +105,7 @@ files:
|
|
|
105
105
|
- ".document"
|
|
106
106
|
- ".github/workflows/release-drafter.yml"
|
|
107
107
|
- ".github/workflows/stale.yml"
|
|
108
|
+
- ".github/workflows/test.yml"
|
|
108
109
|
- ".gitignore"
|
|
109
110
|
- ".rspec"
|
|
110
111
|
- ".ruby-gemset"
|
|
@@ -140,7 +141,7 @@ homepage: https://github.com/pdfkit/pdfkit
|
|
|
140
141
|
licenses:
|
|
141
142
|
- MIT
|
|
142
143
|
metadata: {}
|
|
143
|
-
post_install_message:
|
|
144
|
+
post_install_message:
|
|
144
145
|
rdoc_options: []
|
|
145
146
|
require_paths:
|
|
146
147
|
- lib
|
|
@@ -148,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
148
149
|
requirements:
|
|
149
150
|
- - ">="
|
|
150
151
|
- !ruby/object:Gem::Version
|
|
151
|
-
version: '
|
|
152
|
+
version: '2.5'
|
|
152
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
154
|
requirements:
|
|
154
155
|
- - ">="
|
|
@@ -156,8 +157,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
156
157
|
version: '0'
|
|
157
158
|
requirements:
|
|
158
159
|
- wkhtmltopdf
|
|
159
|
-
rubygems_version: 3.0.3
|
|
160
|
-
signing_key:
|
|
160
|
+
rubygems_version: 3.0.3.1
|
|
161
|
+
signing_key:
|
|
161
162
|
specification_version: 4
|
|
162
163
|
summary: HTML+CSS -> PDF
|
|
163
164
|
test_files:
|