remi-rack-staticifier 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +1 -1
- data/bin/staticify +88 -0
- data/examples/blog-to-staticify/config.ru +3 -0
- data/examples/blog-to-staticify/my-blog.rb +17 -0
- data/examples/blog-to-staticify/paths-to-cache +3 -0
- data/examples/blog-to-staticify/posts/first.mkd +3 -0
- data/examples/blog-to-staticify/posts/second.mkd +5 -0
- data/examples/sinatra-blog-with-built-in-caching/my-sinatra-blog.rb +29 -0
- data/lib/rack-staticifier.rb +8 -3
- data/spec/rack-staticifier_spec.rb +64 -0
- metadata +12 -3
- data/examples/my-sinatra-blog.rb +0 -28
data/VERSION.yml
CHANGED
data/bin/staticify
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Simple script for staticifying your Rack applications
|
4
|
+
#
|
5
|
+
# Checks for config.ru / Rails by defualt, otherwise you can:
|
6
|
+
#
|
7
|
+
# $ staticify -r myapp.rb --app 'lambda {|env| [200, {}, "hi!"] }' info
|
8
|
+
# $ staticify -r myapp.rb,another-file.rb --app 'Sinatra::Application' get '/'
|
9
|
+
# $ staticify -r myapp --app 'MyApp.new' '/'
|
10
|
+
#
|
11
|
+
%w( rubygems rackbox optparse fileutils ).each {|lib| require lib }
|
12
|
+
|
13
|
+
require File.dirname(__FILE__) + '/../lib/rack-staticifier'
|
14
|
+
|
15
|
+
def usage
|
16
|
+
puts <<USAGE
|
17
|
+
staticify == %{ For staticifying your Rack applications }
|
18
|
+
|
19
|
+
Usage:
|
20
|
+
staticify # print this usage information
|
21
|
+
staticify . # staticify Rack app in current directory
|
22
|
+
|
23
|
+
USAGE
|
24
|
+
end
|
25
|
+
|
26
|
+
if ARGV.empty?
|
27
|
+
usage
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
|
31
|
+
#### ==== Option Parsing ==== ####
|
32
|
+
|
33
|
+
files_to_require = []
|
34
|
+
ruby_to_run = nil
|
35
|
+
path_to_cache_to = '.site'
|
36
|
+
|
37
|
+
opts = OptionParser.new do |opts|
|
38
|
+
opts.on('-r', '--require [file]') {|x| files_to_require << x }
|
39
|
+
opts.on('-a', '--app [ruby]') {|x| ruby_to_run = x }
|
40
|
+
opts.on('-d', '--dir [dir]') {|x| path_to_cache_to = x }
|
41
|
+
end
|
42
|
+
opts.parse! ARGV
|
43
|
+
|
44
|
+
app_directory = ARGV.shift
|
45
|
+
unless File.directory? app_directory
|
46
|
+
puts "App directory not found: #{ app_directory }\n\n"
|
47
|
+
usage
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
FileUtils.cd app_directory
|
51
|
+
|
52
|
+
files_to_require.each {|file| require file }
|
53
|
+
if ruby_to_run
|
54
|
+
begin
|
55
|
+
RackBox.app = eval(ruby_to_run)
|
56
|
+
rescue Exception => ex
|
57
|
+
puts "Tried running Ruby code to set Rack app: #{ ruby_to_run.inspect }"
|
58
|
+
raise ex
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
unless RackBox.app(:silent => true)
|
63
|
+
puts "Cannot find your Rack application\n\n"
|
64
|
+
usage
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
|
68
|
+
#### ==== Get Routes to Cache ==== ####
|
69
|
+
|
70
|
+
paths_to_cache = []
|
71
|
+
while path = gets
|
72
|
+
paths_to_cache << path.strip
|
73
|
+
end
|
74
|
+
|
75
|
+
puts "Caching to #{ path_to_cache_to }"
|
76
|
+
|
77
|
+
puts "#{ paths_to_cache.length } paths to cache:"
|
78
|
+
|
79
|
+
#### ==== Cache the Routes ==== ####"
|
80
|
+
|
81
|
+
FileUtils.rm_rf path_to_cache_to
|
82
|
+
|
83
|
+
RackBox.app = Rack::Staticifier.new(RackBox.app, :root => path_to_cache_to)
|
84
|
+
|
85
|
+
paths_to_cache.each do |path|
|
86
|
+
response = RackBox.request path
|
87
|
+
puts " #{ response.status } #{ path }"
|
88
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
%w( rubygems sinatra maruku ).each {|lib| require lib }
|
4
|
+
|
5
|
+
get '/' do
|
6
|
+
"welcome to my blog!"
|
7
|
+
end
|
8
|
+
|
9
|
+
get '/:name.html' do
|
10
|
+
file = File.join File.dirname(__FILE__), 'posts', "#{ params['name'] }.mkd"
|
11
|
+
if File.file? file
|
12
|
+
Maruku.new(File.read(file)).to_html
|
13
|
+
else
|
14
|
+
status 404
|
15
|
+
"Not Found! #{ params['name'] }"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# %w( rubygems sinatra rack/staticifier ).each {|lib| require lib }
|
3
|
+
%w( rubygems sinatra ).each {|lib| require lib }
|
4
|
+
require File.dirname(__FILE__) + '/../lib/rack-staticifier'
|
5
|
+
|
6
|
+
use Rack::Staticifier
|
7
|
+
|
8
|
+
set :public, 'cache'
|
9
|
+
|
10
|
+
$posts = {
|
11
|
+
'hello-world' => '<html><body>Hello World!</body></html>',
|
12
|
+
'hi-there' => 'Hi from my blog post text'
|
13
|
+
}
|
14
|
+
|
15
|
+
get '/' do
|
16
|
+
"Home Page rendered at #{ Time.now }"
|
17
|
+
end
|
18
|
+
|
19
|
+
get '/:post.html' do
|
20
|
+
name = params['post']
|
21
|
+
|
22
|
+
if $posts.keys.include?(name)
|
23
|
+
$posts[name]
|
24
|
+
|
25
|
+
else
|
26
|
+
status 404
|
27
|
+
"Cannot find page: #{ name }"
|
28
|
+
end
|
29
|
+
end
|
data/lib/rack-staticifier.rb
CHANGED
@@ -28,6 +28,8 @@ module Rack #:nodoc:
|
|
28
28
|
#
|
29
29
|
class Staticifier
|
30
30
|
|
31
|
+
STATUS_CODES_NOT_TO_CACHE = [ 304 ]
|
32
|
+
|
31
33
|
# the Rack application
|
32
34
|
attr_reader :app
|
33
35
|
|
@@ -35,7 +37,7 @@ module Rack #:nodoc:
|
|
35
37
|
attr_reader :config
|
36
38
|
|
37
39
|
def initialize app, config_options = nil, &block
|
38
|
-
@app
|
40
|
+
@app = app
|
39
41
|
@config = default_config_options
|
40
42
|
|
41
43
|
config.merge!(config_options) if config_options
|
@@ -55,7 +57,10 @@ module Rack #:nodoc:
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def should_cache_response? env, response
|
58
|
-
return
|
60
|
+
return false if STATUS_CODES_NOT_TO_CACHE.include?(response.first) # there are certain HTTP Status Codes we should never cache
|
61
|
+
return false if response.last.respond_to?(:to_path) # we don't cache Rack::File's
|
62
|
+
return true unless config.keys.include?(:cache_if) and config[:cache_if].respond_to?(:call) # true if no cache_if / block
|
63
|
+
|
59
64
|
should_cache = config[:cache_if].call(env, response)
|
60
65
|
should_cache
|
61
66
|
end
|
@@ -65,7 +70,7 @@ module Rack #:nodoc:
|
|
65
70
|
request_path << 'index.html' if request_path.end_with?('/')
|
66
71
|
|
67
72
|
basename = ::File.basename request_path
|
68
|
-
dirname = ::File.join config[:root], ::File.dirname(request_path)
|
73
|
+
dirname = ::File.join config[:root], ::File.dirname(request_path)
|
69
74
|
fullpath = ::File.join dirname, basename
|
70
75
|
|
71
76
|
FileUtils.mkdir_p(dirname)
|
@@ -130,5 +130,69 @@ describe Rack::Staticifier do
|
|
130
130
|
File.read("cache/#{uri}.html").should == "hello from /#{uri}.html"
|
131
131
|
end
|
132
132
|
end
|
133
|
+
|
134
|
+
it 'should not be cache a Rack::File (#to_path)' do
|
135
|
+
pending "either RackBox or Rack::MockRequest isn't happy about running this"
|
136
|
+
|
137
|
+
=begin
|
138
|
+
1)
|
139
|
+
TypeError in 'Rack::Staticifier should not be cache a Rack::File (#to_path)'
|
140
|
+
can't convert nil into String
|
141
|
+
/usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/file.rb:81:in `initialize'
|
142
|
+
/usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/file.rb:81:in `open'
|
143
|
+
/usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/file.rb:81:in `each'
|
144
|
+
/usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/mock.rb:126:in `initialize'
|
145
|
+
/usr/lib/ruby/gems/1.8/gems/remi-rackbox-1.1.5/lib/rackbox/rack/sticky_sessions.rb:40:in `new'
|
146
|
+
/usr/lib/ruby/gems/1.8/gems/remi-rackbox-1.1.5/lib/rackbox/rack/sticky_sessions.rb:40:in `request'
|
147
|
+
/usr/lib/ruby/gems/1.8/gems/rack-1.0.0/lib/rack/mock.rb:55:in `get'
|
148
|
+
/usr/lib/ruby/gems/1.8/gems/remi-rackbox-1.1.5/lib/rackbox/rackbox.rb:84:in `send'
|
149
|
+
/usr/lib/ruby/gems/1.8/gems/remi-rackbox-1.1.5/lib/rackbox/rackbox.rb:84:in `request'
|
150
|
+
./spec/rack-staticifier_spec.rb:137:
|
151
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/example/example_methods.rb:37:in `instance_eval'
|
152
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/example/example_methods.rb:37:in `execute'
|
153
|
+
/usr/lib/ruby/1.8/timeout.rb:53:in `timeout'
|
154
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/example/example_methods.rb:34:in `execute'
|
155
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/example/example_group_methods.rb:208:in `execute_examples'
|
156
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/example/example_group_methods.rb:206:in `each'
|
157
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/example/example_group_methods.rb:206:in `execute_examples'
|
158
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/example/example_group_methods.rb:104:in `run'
|
159
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/runner/example_group_runner.rb:23:in `run'
|
160
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/runner/example_group_runner.rb:22:in `each'
|
161
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/runner/example_group_runner.rb:22:in `run'
|
162
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/runner/options.rb:117:in `run_examples'
|
163
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/lib/spec/runner/command_line.rb:9:in `run'
|
164
|
+
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.2/bin/spec:4:
|
165
|
+
/usr/bin/spec:19:in `load'
|
166
|
+
/usr/bin/spec:19:
|
167
|
+
=end
|
168
|
+
|
169
|
+
app = lambda {|env| [200, {}, Rack::File.new(__FILE__)] }
|
170
|
+
File.file?("cache/foo.html").should be_false
|
171
|
+
RackBox.request app, "/foo.html"
|
172
|
+
File.file?("cache/foo.html").should be_false # shouldn't be cached!
|
173
|
+
|
174
|
+
# just double check ...
|
175
|
+
app = lambda {|env| [200, {}, ["cache me!"]] }
|
176
|
+
File.file?("cache/foo.html").should be_false
|
177
|
+
RackBox.request app, "/foo.html"
|
178
|
+
File.file?("cache/foo.html").should be_true # normal #each should be cached
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should not cache responses with certain HTTP Status Codes' do
|
182
|
+
Rack::Staticifier::STATUS_CODES_NOT_TO_CACHE.each do |code|
|
183
|
+
app = lambda {|env| [code, {}, ["not cached"]] }
|
184
|
+
File.file?("foo.html").should be_false
|
185
|
+
RackBox.request app, "/foo.html"
|
186
|
+
File.file?("foo.html").should be_false # shouldn't be cached!
|
187
|
+
end
|
188
|
+
|
189
|
+
# this assumes that 304 will always be in STATUS_CODES_NOT_TO_CACHE ... want to double check!
|
190
|
+
app = lambda {|env| [304, {}, ["not cached"]] }
|
191
|
+
File.file?("foo.html").should be_false
|
192
|
+
RackBox.request app, "/foo.html"
|
193
|
+
File.file?("foo.html").should be_false # shouldn't be cached!
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'should be able to customize the name of the cached file (?)'
|
133
197
|
|
134
198
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remi-rack-staticifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- remi
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-05-
|
12
|
+
date: 2009-05-07 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,7 +29,16 @@ files:
|
|
29
29
|
- lib/rack
|
30
30
|
- lib/rack/staticifier.rb
|
31
31
|
- spec/rack-staticifier_spec.rb
|
32
|
-
-
|
32
|
+
- bin/staticify
|
33
|
+
- examples/sinatra-blog-with-built-in-caching
|
34
|
+
- examples/sinatra-blog-with-built-in-caching/my-sinatra-blog.rb
|
35
|
+
- examples/blog-to-staticify
|
36
|
+
- examples/blog-to-staticify/posts
|
37
|
+
- examples/blog-to-staticify/posts/first.mkd
|
38
|
+
- examples/blog-to-staticify/posts/second.mkd
|
39
|
+
- examples/blog-to-staticify/my-blog.rb
|
40
|
+
- examples/blog-to-staticify/config.ru
|
41
|
+
- examples/blog-to-staticify/paths-to-cache
|
33
42
|
has_rdoc: true
|
34
43
|
homepage: http://github.com/remi/rack-staticifier
|
35
44
|
post_install_message:
|
data/examples/my-sinatra-blog.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
%w( rubygems sinatra rack/staticifier ).each {|lib| require lib }
|
3
|
-
|
4
|
-
# sinatra serves out of the public directory by default
|
5
|
-
use Rack::Staticifier, :root => 'public' do |env, response|
|
6
|
-
response.first == 200 # only staticly cache 200 responses, meaning /non-existent-page-name should render OK
|
7
|
-
end
|
8
|
-
|
9
|
-
$posts = {
|
10
|
-
'hello-world' => 'Hello World!',
|
11
|
-
'hi-there' => 'Hi from my blog post text'
|
12
|
-
}
|
13
|
-
|
14
|
-
get '/' do
|
15
|
-
"Home Page rendered at #{ Time.now }"
|
16
|
-
end
|
17
|
-
|
18
|
-
get '/:post.html' do
|
19
|
-
name = params['post']
|
20
|
-
|
21
|
-
if $posts.keys.include?(name)
|
22
|
-
$posts[name]
|
23
|
-
|
24
|
-
else
|
25
|
-
status 404
|
26
|
-
"Cannot find page: #{ name }"
|
27
|
-
end
|
28
|
-
end
|