pdfkit 0.4.6 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pdfkit might be problematic. Click here for more details.

@@ -1,13 +1,11 @@
1
1
  class PDFKit
2
-
3
2
  class Source
4
-
5
3
  def initialize(url_file_or_html)
6
4
  @source = url_file_or_html
7
5
  end
8
6
 
9
7
  def url?
10
- @source.is_a?(String) && @source.match(/^http/)
8
+ @source.is_a?(String) && @source.match(/\Ahttp/)
11
9
  end
12
10
 
13
11
  def file?
@@ -21,7 +19,5 @@ class PDFKit
21
19
  def to_s
22
20
  file? ? @source.path : @source
23
21
  end
24
-
25
22
  end
26
-
27
- end
23
+ end
@@ -0,0 +1,3 @@
1
+ class PDFKit
2
+ VERSION = "0.5.0"
3
+ end
@@ -1,85 +1,27 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "pdfkit/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
- s.name = %q{pdfkit}
8
- s.version = "0.4.6"
6
+ s.name = "pdfkit"
7
+ s.version = PDFKit::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jared Pace", "Relevance"]
10
+ s.email = ["jared@codewordstudios.com"]
11
+ s.homepage = "http://github.com/jdpace/PDFKit"
12
+ s.summary = "HTML+CSS -> PDF"
13
+ s.description = "Uses wkhtmltopdf to create PDFs using HTML"
9
14
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["jdpace"]
12
- s.date = %q{2010-09-03}
13
- s.default_executable = %q{pdfkit}
14
- s.description = %q{Uses wkhtmltopdf to create PDFs using HTML}
15
- s.email = %q{jared@codewordstudios.com}
16
- s.executables = ["pdfkit"]
17
- s.extra_rdoc_files = [
18
- "LICENSE",
19
- "README.md"
20
- ]
21
- s.files = [
22
- ".document",
23
- ".gitignore",
24
- ".rspec",
25
- "Gemfile",
26
- "Gemfile.lock",
27
- "LICENSE",
28
- "POST_INSTALL",
29
- "README.md",
30
- "Rakefile",
31
- "VERSION",
32
- "bin/pdfkit",
33
- "lib/pdfkit.rb",
34
- "lib/pdfkit/configuration.rb",
35
- "lib/pdfkit/middleware.rb",
36
- "lib/pdfkit/pdfkit.rb",
37
- "lib/pdfkit/source.rb",
38
- "pdfkit.gemspec",
39
- "spec/fixtures/example.css",
40
- "spec/fixtures/example.html",
41
- "spec/middleware_spec.rb",
42
- "spec/pdfkit_spec.rb",
43
- "spec/source_spec.rb",
44
- "spec/spec_helper.rb"
45
- ]
46
- s.homepage = %q{http://github.com/jdpace/PDFKit}
47
- s.post_install_message = %q{******************************************************************
15
+ s.rubyforge_project = "pdfkit"
48
16
 
49
- Now install wkhtmltopdf binaries:
50
- Global: sudo `which pdfkit` --install-wkhtmltopdf
51
- or inside RVM folder: export TO=`which pdfkit | sed 's:/pdfkit:/wkhtmltopdf:'` && pdfkit --install-wkhtmltopdf
52
- (run pdfkit --help to see more options)
53
-
54
- ******************************************************************}
55
- s.rdoc_options = ["--charset=UTF-8"]
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
56
20
  s.require_paths = ["lib"]
57
- s.rubygems_version = %q{1.3.7}
58
- s.summary = %q{HTML+CSS -> PDF}
59
- s.test_files = [
60
- "spec/middleware_spec.rb",
61
- "spec/pdfkit_spec.rb",
62
- "spec/source_spec.rb",
63
- "spec/spec_helper.rb"
64
- ]
65
-
66
- if s.respond_to? :specification_version then
67
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
68
- s.specification_version = 3
69
21
 
70
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
71
- s.add_development_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
72
- s.add_development_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
73
- s.add_development_dependency(%q<mocha>, [">= 0"])
74
- else
75
- s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
76
- s.add_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
77
- s.add_dependency(%q<mocha>, [">= 0"])
78
- end
79
- else
80
- s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
81
- s.add_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
82
- s.add_dependency(%q<mocha>, [">= 0"])
83
- end
22
+ # Developmnet Dependencies
23
+ s.add_development_dependency(%q<rspec>, ["~> 2.2.0"])
24
+ s.add_development_dependency(%q<mocha>, [">= 0.9.10"])
25
+ s.add_development_dependency(%q<rack-test>, [">= 0.5.6"])
84
26
  end
85
27
 
@@ -1,11 +1,136 @@
1
1
  require 'spec_helper'
2
2
 
3
+ def app; Rack::Lint.new(@app); end
4
+
5
+ def mock_app(options = {}, conditions = {})
6
+ main_app = lambda { |env|
7
+ @env = env
8
+ headers = {'Content-Type' => "text/html"}
9
+ [200, headers, @body || ['Hello world!']]
10
+ }
11
+
12
+ builder = Rack::Builder.new
13
+ builder.use PDFKit::Middleware, options, conditions
14
+ builder.run main_app
15
+ @app = builder.to_app
16
+ end
17
+
3
18
  describe PDFKit::Middleware do
19
+
20
+ describe "#call" do
21
+ describe "conditions" do
22
+ describe ":only" do
23
+
24
+ describe "regex" do
25
+ describe "one" do
26
+ before { mock_app({}, :only => %r[^/public]) }
27
+
28
+ context "matching" do
29
+ specify do
30
+ get 'http://www.example.org/public/test.pdf'
31
+ last_response.headers["Content-Type"].should == "application/pdf"
32
+ last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
33
+ end
34
+ end
35
+
36
+ context "not matching" do
37
+ specify do
38
+ get 'http://www.example.org/secret/test.pdf'
39
+ last_response.headers["Content-Type"].should == "text/html"
40
+ last_response.body.should == "Hello world!"
41
+ end
42
+ end
43
+ end # one regex
44
+
45
+ describe "multiple" do
46
+ before { mock_app({}, :only => [%r[^/invoice], %r[^/public]]) }
47
+
48
+ context "matching" do
49
+ specify do
50
+ get 'http://www.example.org/public/test.pdf'
51
+ last_response.headers["Content-Type"].should == "application/pdf"
52
+ last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
53
+ end
54
+ end
55
+
56
+ context "not matching" do
57
+ specify do
58
+ get 'http://www.example.org/secret/test.pdf'
59
+ last_response.headers["Content-Type"].should == "text/html"
60
+ last_response.body.should == "Hello world!"
61
+ end
62
+ end
63
+ end # multiple regex
64
+ end # regex
65
+
66
+ describe "string" do
67
+ describe "one" do
68
+ before { mock_app({}, :only => '/public') }
69
+
70
+ context "matching" do
71
+ specify do
72
+ get 'http://www.example.org/public/test.pdf'
73
+ last_response.headers["Content-Type"].should == "application/pdf"
74
+ last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
75
+ end
76
+ end
77
+
78
+ context "not matching" do
79
+ specify do
80
+ get 'http://www.example.org/secret/test.pdf'
81
+ last_response.headers["Content-Type"].should == "text/html"
82
+ last_response.body.should == "Hello world!"
83
+ end
84
+ end
85
+ end # one string
86
+
87
+ describe "multiple" do
88
+ before { mock_app({}, :only => ['/invoice', '/public']) }
89
+
90
+ context "matching" do
91
+ specify do
92
+ get 'http://www.example.org/public/test.pdf'
93
+ last_response.headers["Content-Type"].should == "application/pdf"
94
+ last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
95
+ end
96
+ end
97
+
98
+ context "not matching" do
99
+ specify do
100
+ get 'http://www.example.org/secret/test.pdf'
101
+ last_response.headers["Content-Type"].should == "text/html"
102
+ last_response.body.should == "Hello world!"
103
+ end
104
+ end
105
+ end # multiple string
106
+ end # string
107
+
108
+ end
109
+ end
110
+
111
+ describe "remove .pdf from PATH_INFO and REQUEST_URI" do
112
+ before { mock_app }
113
+
114
+ context "matching" do
115
+ specify do
116
+ get 'http://www.example.org/public/file.pdf'
117
+ @env["PATH_INFO"].should == "/public/file"
118
+ @env["REQUEST_URI"].should == "/public/file"
119
+ end
120
+ specify do
121
+ get 'http://www.example.org/public/file.txt'
122
+ @env["PATH_INFO"].should == "/public/file.txt"
123
+ @env["REQUEST_URI"].should be_nil
124
+ end
125
+ end
126
+
127
+ end
128
+ end
129
+
4
130
  describe "#translate_paths" do
5
-
6
131
  before do
7
132
  @pdf = PDFKit::Middleware.new({})
8
- @env = {'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com'}
133
+ @env = { 'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com' }
9
134
  end
10
135
 
11
136
  it "should correctly parse relative url with single quotes" do
@@ -26,24 +151,5 @@ describe PDFKit::Middleware do
26
151
  body.should == "NO MATCH"
27
152
  end
28
153
  end
29
-
30
- describe "#set_request_to_render_as_pdf" do
31
-
32
- before do
33
- @pdf = PDFKit::Middleware.new({})
34
154
 
35
- @pdf_env = {'PATH_INFO' => Pathname.new("file.pdf"), 'REQUEST_URI' => Pathname.new("file.pdf")}
36
- @non_pdf_env = {'PATH_INFO' => Pathname.new("file.txt"), 'REQUEST_URI' => Pathname.new("file.txt")}
37
- end
38
-
39
- it "should replace .pdf in PATH_INFO when the extname is .pdf" do
40
- @pdf.send :set_request_to_render_as_pdf, @pdf_env
41
- @pdf_env['PATH_INFO'].should == "file"
42
- end
43
-
44
- it "should replace .pdf in REQUEST_URI when the extname is .pdf" do
45
- @pdf.send :set_request_to_render_as_pdf, @pdf_env
46
- @pdf_env['REQUEST_URI'].should == "file"
47
- end
48
- end
49
155
  end
@@ -1,84 +1,95 @@
1
+ #encoding: UTF-8
1
2
  require 'spec_helper'
2
3
 
3
4
  describe PDFKit do
4
-
5
+
5
6
  context "initialization" do
6
7
  it "should accept HTML as the source" do
7
8
  pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
8
9
  pdfkit.source.should be_html
9
10
  pdfkit.source.to_s.should == '<h1>Oh Hai</h1>'
10
11
  end
11
-
12
+
12
13
  it "should accept a URL as the source" do
13
14
  pdfkit = PDFKit.new('http://google.com')
14
15
  pdfkit.source.should be_url
15
16
  pdfkit.source.to_s.should == 'http://google.com'
16
17
  end
17
-
18
+
18
19
  it "should accept a File as the source" do
19
20
  file_path = File.join(SPEC_ROOT,'fixtures','example.html')
20
21
  pdfkit = PDFKit.new(File.new(file_path))
21
22
  pdfkit.source.should be_file
22
23
  pdfkit.source.to_s.should == file_path
23
24
  end
24
-
25
+
25
26
  it "should parse the options into a cmd line friedly format" do
26
27
  pdfkit = PDFKit.new('html', :page_size => 'Letter')
27
28
  pdfkit.options.should have_key('--page-size')
28
29
  end
29
-
30
+
30
31
  it "should provide default options" do
31
32
  pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
32
- ['--disable-smart-shrinking', '--margin-top', '--margin-right', '--margin-bottom', '--margin-left'].each do |option|
33
+ ['--margin-top', '--margin-right', '--margin-bottom', '--margin-left'].each do |option|
33
34
  pdfkit.options.should have_key(option)
34
35
  end
35
36
  end
36
-
37
+
37
38
  it "should default to 'UTF-8' encoding" do
38
39
  pdfkit = PDFKit.new('Captación')
39
40
  pdfkit.options['--encoding'].should == 'UTF-8'
40
41
  end
41
-
42
+
42
43
  it "should not have any stylesheedt by default" do
43
44
  pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
44
45
  pdfkit.stylesheets.should be_empty
45
46
  end
46
47
  end
47
-
48
+
48
49
  context "command" do
49
50
  it "should contstruct the correct command" do
50
51
  pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12)
51
52
  pdfkit.command[0].should include('wkhtmltopdf')
52
- pdfkit.command[pdfkit.command.index('--page-size') + 1].should == 'Letter'
53
- pdfkit.command[pdfkit.command.index('--toc-l1-font-size') + 1].should == '12'
53
+ pdfkit.command[pdfkit.command.index('"--page-size"') + 1].should == '"Letter"'
54
+ pdfkit.command[pdfkit.command.index('"--toc-l1-font-size"') + 1].should == '"12"'
54
55
  end
55
-
56
+
56
57
  it "will not include default options it is told to omit" do
58
+ PDFKit.configure do |config|
59
+ config.default_options[:disable_smart_shrinking] = true
60
+ end
61
+
57
62
  pdfkit = PDFKit.new('html')
58
- pdfkit.command.should include('--disable-smart-shrinking')
63
+ pdfkit.command.should include('"--disable-smart-shrinking"')
59
64
  pdfkit = PDFKit.new('html', :disable_smart_shrinking => false)
60
- pdfkit.command.should_not include('--disable-smart-shrinking')
65
+ pdfkit.command.should_not include('"--disable-smart-shrinking"')
61
66
  end
62
-
67
+
63
68
  it "should encapsulate string arguments in quotes" do
64
69
  pdfkit = PDFKit.new('html', :header_center => "foo [page]")
65
- pdfkit.command[pdfkit.command.index('--header-center') + 1].should == 'foo [page]'
70
+ pdfkit.command[pdfkit.command.index('"--header-center"') + 1].should == '"foo [page]"'
66
71
  end
67
-
72
+
68
73
  it "read the source from stdin if it is html" do
69
74
  pdfkit = PDFKit.new('html')
70
- pdfkit.command[-2..-1].should == ['-', '-']
75
+ pdfkit.command[-2..-1].should == ['"-"', '"-"']
71
76
  end
72
-
77
+
73
78
  it "specify the URL to the source if it is a url" do
74
79
  pdfkit = PDFKit.new('http://google.com')
75
- pdfkit.command[-2..-1].should == ['http://google.com', '-']
80
+ pdfkit.command[-2..-1].should == ['"http://google.com"', '"-"']
76
81
  end
77
-
82
+
78
83
  it "should specify the path to the source if it is a file" do
79
84
  file_path = File.join(SPEC_ROOT,'fixtures','example.html')
80
85
  pdfkit = PDFKit.new(File.new(file_path))
81
- pdfkit.command[-2..-1].should == [file_path, '-']
86
+ pdfkit.command[-2..-1].should == [%Q{"#{file_path}"}, '"-"']
87
+ end
88
+
89
+ it "should specify the path for the ouput if a apth is given" do
90
+ file_path = "/path/to/output.pdf"
91
+ pdfkit = PDFKit.new("html")
92
+ pdfkit.command(file_path).last.should == %Q{"#{file_path}"}
82
93
  end
83
94
 
84
95
  it "should detect special pdfkit meta tags" do
@@ -91,30 +102,30 @@ describe PDFKit do
91
102
  </html>
92
103
  }
93
104
  pdfkit = PDFKit.new(body)
94
- pdfkit.command[pdfkit.command.index('--page-size') + 1].should == 'Legal'
95
- pdfkit.command[pdfkit.command.index('--orientation') + 1].should == 'Landscape'
105
+ pdfkit.command[pdfkit.command.index('"--page-size"') + 1].should == '"Legal"'
106
+ pdfkit.command[pdfkit.command.index('"--orientation"') + 1].should == '"Landscape"'
96
107
  end
97
108
  end
98
-
109
+
99
110
  context "#to_pdf" do
100
111
  it "should generate a PDF of the HTML" do
101
112
  pdfkit = PDFKit.new('html', :page_size => 'Letter')
102
113
  pdf = pdfkit.to_pdf
103
114
  pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
104
115
  end
105
-
116
+
106
117
  it "should generate a PDF with a numerical parameter" do
107
118
  pdfkit = PDFKit.new('html', :header_spacing => 1)
108
119
  pdf = pdfkit.to_pdf
109
120
  pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
110
121
  end
111
-
122
+
112
123
  it "should generate a PDF with a symbol parameter" do
113
124
  pdfkit = PDFKit.new('html', :page_size => :Letter)
114
125
  pdf = pdfkit.to_pdf
115
126
  pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
116
127
  end
117
-
128
+
118
129
  it "should have the stylesheet added to the head if it has one" do
119
130
  pdfkit = PDFKit.new("<html><head></head><body>Hai!</body></html>")
120
131
  css = File.join(SPEC_ROOT,'fixtures','example.css')
@@ -122,7 +133,7 @@ describe PDFKit do
122
133
  pdfkit.to_pdf
123
134
  pdfkit.source.to_s.should include("<style>#{File.read(css)}</style>")
124
135
  end
125
-
136
+
126
137
  it "should prepend style tags if the HTML doesn't have a head tag" do
127
138
  pdfkit = PDFKit.new("<html><body>Hai!</body></html>")
128
139
  css = File.join(SPEC_ROOT,'fixtures','example.css')
@@ -130,7 +141,7 @@ describe PDFKit do
130
141
  pdfkit.to_pdf
131
142
  pdfkit.source.to_s.should include("<style>#{File.read(css)}</style><html>")
132
143
  end
133
-
144
+
134
145
  it "should throw an error if the source is not html and stylesheets have been added" do
135
146
  pdfkit = PDFKit.new('http://google.com')
136
147
  css = File.join(SPEC_ROOT,'fixtures','example.css')
@@ -138,41 +149,40 @@ describe PDFKit do
138
149
  lambda { pdfkit.to_pdf }.should raise_error(PDFKit::ImproperSourceError)
139
150
  end
140
151
  end
141
-
152
+
142
153
  context "#to_file" do
143
154
  before do
144
155
  @file_path = File.join(SPEC_ROOT,'fixtures','test.pdf')
145
156
  File.delete(@file_path) if File.exist?(@file_path)
146
157
  end
147
-
158
+
148
159
  after do
149
160
  File.delete(@file_path)
150
161
  end
151
-
162
+
152
163
  it "should create a file with the PDF as content" do
153
164
  pdfkit = PDFKit.new('html', :page_size => 'Letter')
154
- pdfkit.expects(:to_pdf).returns('PDF')
155
165
  file = pdfkit.to_file(@file_path)
156
166
  file.should be_instance_of(File)
157
- File.read(file.path).should == 'PDF'
167
+ File.read(file.path)[0...4].should == "%PDF" # PDF Signature at beginning of file
158
168
  end
159
169
  end
160
-
170
+
161
171
  context "security" do
162
172
  before do
163
173
  @test_path = File.join(SPEC_ROOT,'fixtures','security-oops')
164
174
  File.delete(@test_path) if File.exist?(@test_path)
165
175
  end
166
-
176
+
167
177
  after do
168
178
  File.delete(@test_path) if File.exist?(@test_path)
169
179
  end
170
-
180
+
171
181
  it "should not allow shell injection in options" do
172
182
  pdfkit = PDFKit.new('html', :header_center => "a title\"; touch #{@test_path} #")
173
183
  pdfkit.to_pdf
174
184
  File.exist?(@test_path).should be_false
175
185
  end
176
186
  end
177
-
187
+
178
188
  end