heel 0.6.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{CHANGES → HISTORY} +3 -3
- data/LICENSE +1 -1
- data/README +28 -26
- data/bin/heel +5 -1
- data/data/error.rhtml +1 -1
- data/data/listing.rhtml +2 -2
- data/gemspec.rb +42 -0
- data/lib/heel.rb +18 -13
- data/lib/heel/configuration.rb +64 -0
- data/lib/heel/directory_indexer.rb +114 -0
- data/lib/heel/error_response.rb +43 -0
- data/lib/heel/logger.rb +42 -0
- data/lib/heel/mime_map.rb +87 -0
- data/lib/heel/rackapp.rb +142 -0
- data/lib/heel/request.rb +66 -0
- data/lib/heel/server.rb +253 -219
- data/lib/heel/version.rb +21 -16
- data/spec/configuration_spec.rb +20 -0
- data/spec/directory_indexer_spec.rb +34 -0
- data/spec/rackapp_spec.rb +43 -0
- data/spec/server_spec.rb +107 -108
- data/tasks/announce.rake +42 -0
- data/tasks/config.rb +103 -0
- data/tasks/distribution.rake +52 -0
- data/tasks/documentation.rake +35 -0
- data/tasks/rspec.rb +33 -0
- data/tasks/rubyforge.rb +52 -0
- data/tasks/utils.rb +85 -0
- metadata +52 -44
- data/lib/heel/dir_handler.rb +0 -310
- data/lib/heel/error_handler.rb +0 -30
- data/lib/heel/gemspec.rb +0 -56
- data/lib/heel/specification.rb +0 -128
- data/spec/dir_handler_spec.rb +0 -128
- data/spec/error_handler_spec.rb +0 -29
data/lib/heel/error_handler.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'heel'
|
2
|
-
require 'erb'
|
3
|
-
|
4
|
-
module Heel
|
5
|
-
|
6
|
-
class ErrorHandler < ::Mongrel::HttpHandler
|
7
|
-
|
8
|
-
attr_reader :template
|
9
|
-
attr_accessor :listener
|
10
|
-
attr_reader :request_notify
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(options = {})
|
14
|
-
@template = ::ERB.new File.read(File.join(APP_DATA_DIR,"error.rhtml"))
|
15
|
-
end
|
16
|
-
|
17
|
-
def process(request,response)
|
18
|
-
status = response.status
|
19
|
-
if status != 200 then
|
20
|
-
message = ::Mongrel::HTTP_STATUS_CODES[status]
|
21
|
-
base_uri = ::Mongrel::HttpRequest.unescape(request.params[Mongrel::Const::REQUEST_URI])
|
22
|
-
|
23
|
-
response.start(status) do |head,out|
|
24
|
-
head['Content-Type'] = 'text/html'
|
25
|
-
out.write(template.result(binding))
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
data/lib/heel/gemspec.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'heel/specification'
|
3
|
-
require 'heel/version'
|
4
|
-
require 'rake'
|
5
|
-
|
6
|
-
module Heel
|
7
|
-
SPEC = Heel::Specification.new do |spec|
|
8
|
-
spec.name = "heel"
|
9
|
-
spec.version = Heel::VERSION
|
10
|
-
spec.rubyforge_project = "copiousfreetime"
|
11
|
-
spec.author = "Jeremy Hinegardner"
|
12
|
-
spec.email = "jeremy@hinegardner.org"
|
13
|
-
spec.homepage = "http://copiousfreetime.rubyforge.org/heel/"
|
14
|
-
|
15
|
-
spec.summary = "A mongrel based static file webserver."
|
16
|
-
spec.description = <<-DESC
|
17
|
-
Heel is a mongrel based web server to quickly and easily serve up the
|
18
|
-
contents of a directory as webpages. Beyond just serving up webpages
|
19
|
-
heel uses an ERB template and famfamfam icons to create useful index
|
20
|
-
pages.
|
21
|
-
|
22
|
-
And to make things even easier it launches your browser for you so no
|
23
|
-
cut and paste necessary.
|
24
|
-
DESC
|
25
|
-
|
26
|
-
spec.extra_rdoc_files = FileList["CHANGES", "LICENSE", "README"]
|
27
|
-
spec.has_rdoc = true
|
28
|
-
spec.rdoc_main = "README"
|
29
|
-
spec.rdoc_options = [ "--line-numbers" , "--inline-source" ]
|
30
|
-
|
31
|
-
spec.test_files = FileList["spec/**/*.rb"]
|
32
|
-
spec.executable = spec.name
|
33
|
-
spec.files = spec.test_files + spec.extra_rdoc_files +
|
34
|
-
FileList["lib/**/*.rb", "data/**/*"]
|
35
|
-
|
36
|
-
spec.add_dependency("mongrel", ">= 1.0.1")
|
37
|
-
spec.add_dependency("launchy", ">= 0.3.0")
|
38
|
-
spec.add_dependency("mime-types", ">= 1.15")
|
39
|
-
spec.add_dependency("coderay", ">= 0.7.4.215")
|
40
|
-
spec.add_dependency("rake", ">= 0.7.3")
|
41
|
-
|
42
|
-
spec.required_ruby_version = ">= 1.8.5"
|
43
|
-
|
44
|
-
spec.platform = Gem::Platform::RUBY
|
45
|
-
|
46
|
-
spec.remote_user = "jjh"
|
47
|
-
spec.local_rdoc_dir = "doc/rdoc"
|
48
|
-
spec.remote_rdoc_dir = ""
|
49
|
-
spec.local_coverage_dir = "doc/coverage"
|
50
|
-
|
51
|
-
spec.remote_site_dir = "#{spec.name}/"
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
|
data/lib/heel/specification.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rubygems/specification'
|
3
|
-
require 'rake'
|
4
|
-
|
5
|
-
module Heel
|
6
|
-
# Add some additional items to Gem::Specification
|
7
|
-
# A Heel::Specification adds additional pieces of information the
|
8
|
-
# typical gem specification
|
9
|
-
class Specification
|
10
|
-
|
11
|
-
RUBYFORGE_ROOT = "/var/www/gforge-projects/"
|
12
|
-
|
13
|
-
# user that accesses remote site
|
14
|
-
attr_accessor :remote_user
|
15
|
-
|
16
|
-
# remote host, default 'rubyforge.org'
|
17
|
-
attr_accessor :remote_host
|
18
|
-
|
19
|
-
# name the rdoc main
|
20
|
-
attr_accessor :rdoc_main
|
21
|
-
|
22
|
-
# local directory in development holding the generated rdoc
|
23
|
-
# default 'doc'
|
24
|
-
attr_accessor :local_rdoc_dir
|
25
|
-
|
26
|
-
# remote directory for storing rdoc, default 'doc'
|
27
|
-
attr_accessor :remote_rdoc_dir
|
28
|
-
|
29
|
-
# local directory for coverage report
|
30
|
-
attr_accessor :local_coverage_dir
|
31
|
-
|
32
|
-
# remote directory for storing coverage reports
|
33
|
-
# This defaults to 'coverage'
|
34
|
-
attr_accessor :remote_coverage_dir
|
35
|
-
|
36
|
-
# local directory for generated website, default +site/public+
|
37
|
-
attr_accessor :local_site_dir
|
38
|
-
|
39
|
-
# remote directory relative to +remote_root+ for the website.
|
40
|
-
# website.
|
41
|
-
attr_accessor :remote_site_dir
|
42
|
-
|
43
|
-
# is a .tgz to be created?, default 'true'
|
44
|
-
attr_accessor :need_tar
|
45
|
-
|
46
|
-
# is a .zip to be created, default 'true'
|
47
|
-
attr_accessor :need_zip
|
48
|
-
|
49
|
-
|
50
|
-
def initialize
|
51
|
-
@remote_user = nil
|
52
|
-
@remote_host = "rubyforge.org"
|
53
|
-
|
54
|
-
@rdoc_main = "README"
|
55
|
-
@local_rdoc_dir = "doc"
|
56
|
-
@remote_rdoc_dir = "doc"
|
57
|
-
@local_coverage_dir = "coverage"
|
58
|
-
@remote_coverage_dir = "coverage"
|
59
|
-
@local_site_dir = "site/public"
|
60
|
-
@remote_site_dir = "."
|
61
|
-
|
62
|
-
@need_tar = true
|
63
|
-
@need_zip = true
|
64
|
-
|
65
|
-
@spec = Gem::Specification.new
|
66
|
-
|
67
|
-
yield self if block_given?
|
68
|
-
|
69
|
-
# update rdoc options to take care of the rdoc_main if it is
|
70
|
-
# there, and add a default title if one is not given
|
71
|
-
if not @spec.rdoc_options.include?("--main") then
|
72
|
-
@spec.rdoc_options.concat(["--main", rdoc_main])
|
73
|
-
end
|
74
|
-
|
75
|
-
if not @spec.rdoc_options.include?("--title") then
|
76
|
-
@spec.rdoc_options.concat(["--title","'#{name} -- #{summary}'"])
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# if this gets set then it overwrites what would be the
|
81
|
-
# rubyforge default. If rubyforge project is not set then use
|
82
|
-
# name. If rubyforge project and name are set, but they are
|
83
|
-
# different then assume that name is a subproject of the
|
84
|
-
# rubyforge project
|
85
|
-
def remote_root
|
86
|
-
if rubyforge_project.nil? or
|
87
|
-
rubyforge_project == name then
|
88
|
-
return RUBYFORGE_ROOT + "#{name}/"
|
89
|
-
else
|
90
|
-
return RUBYFORGE_ROOT + "#{rubyforge_project}/#{name}/"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
# rdoc files is the same as what would be generated during gem
|
95
|
-
# installation. That is, everything in the require paths plus
|
96
|
-
# the extra_rdoc_files
|
97
|
-
#
|
98
|
-
def rdoc_files
|
99
|
-
flist = extra_rdoc_files.dup
|
100
|
-
@spec.require_paths.each do |rp|
|
101
|
-
flist << FileList["#{rp}/**/*.rb"]
|
102
|
-
end
|
103
|
-
flist.flatten.uniq
|
104
|
-
end
|
105
|
-
|
106
|
-
# calculate the remote directories
|
107
|
-
def remote_root_location
|
108
|
-
"#{remote_user}@#{remote_host}:#{remote_root}"
|
109
|
-
end
|
110
|
-
|
111
|
-
def remote_rdoc_location
|
112
|
-
remote_root_location + @remote_rdoc_dir
|
113
|
-
end
|
114
|
-
|
115
|
-
def remote_coverage_location
|
116
|
-
remote_root_loation + @remote_coverage_dir
|
117
|
-
end
|
118
|
-
|
119
|
-
def remote_site_location
|
120
|
-
remote_root_location + @remote_site_dir
|
121
|
-
end
|
122
|
-
|
123
|
-
# we delegate any other calls to spec
|
124
|
-
def method_missing(method_id,*params,&block)
|
125
|
-
@spec.send method_id, *params, &block
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
data/spec/dir_handler_spec.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
|
2
|
-
|
3
|
-
require 'stringio'
|
4
|
-
|
5
|
-
describe Heel::DirHandler do
|
6
|
-
before(:each) do
|
7
|
-
@handler = Heel::DirHandler.new({:highlighting => true})
|
8
|
-
@classifier = Mongrel::URIClassifier.new
|
9
|
-
@classifier.register("/",1)
|
10
|
-
@socket = StringIO.new
|
11
|
-
@params = Mongrel::HttpParams.new
|
12
|
-
@params.http_body = ""
|
13
|
-
@params[Mongrel::Const::REQUEST_METHOD] = Mongrel::Const::GET
|
14
|
-
@response = Mongrel::HttpResponse.new(@socket)
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should return the index page" do
|
19
|
-
@params[Mongrel::Const::REQUEST_URI] = "/"
|
20
|
-
junk1,path_info,junk2 = @classifier.resolve(@params[Mongrel::Const::REQUEST_URI])
|
21
|
-
|
22
|
-
@params[Mongrel::Const::PATH_INFO] = path_info
|
23
|
-
@request = Mongrel::HttpRequest.new(@params,@socket,nil)
|
24
|
-
|
25
|
-
@handler.process(@request,@response)
|
26
|
-
@response.finished
|
27
|
-
|
28
|
-
@response.status.should == 200
|
29
|
-
@socket.string.should =~ /Index of/m
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should return an existing directory index page if it exists" do
|
33
|
-
File.open("index.html", "w") { |f| f.write('delete me') }
|
34
|
-
@params[Mongrel::Const::REQUEST_URI] = "/"
|
35
|
-
junk1,path_info,junk2 = @classifier.resolve(@params[Mongrel::Const::REQUEST_URI])
|
36
|
-
|
37
|
-
@params[Mongrel::Const::PATH_INFO] = path_info
|
38
|
-
@request = Mongrel::HttpRequest.new(@params,@socket,nil)
|
39
|
-
|
40
|
-
@handler.process(@request,@response)
|
41
|
-
@response.finished
|
42
|
-
File.unlink("index.html")
|
43
|
-
|
44
|
-
@response.status.should == 200
|
45
|
-
@socket.string.should =~ /delete me/m
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should return a 403 if a request for an ignorable file is made" do
|
49
|
-
File.open(".htaccess", "w") { |f| f.write('delete me') }
|
50
|
-
@params[Mongrel::Const::REQUEST_URI] = "/.htaccess"
|
51
|
-
junk1,path_info,junk2 = @classifier.resolve(@params[Mongrel::Const::REQUEST_URI])
|
52
|
-
|
53
|
-
@params[Mongrel::Const::PATH_INFO] = path_info
|
54
|
-
@request = Mongrel::HttpRequest.new(@params,@socket,nil)
|
55
|
-
|
56
|
-
@handler.process(@request,@response)
|
57
|
-
@response.finished
|
58
|
-
|
59
|
-
File.unlink(".htaccess")
|
60
|
-
@response.status.should == 403
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
it "should return a 403 if an invalid request method is used" do
|
65
|
-
@params[Mongrel::Const::REQUEST_METHOD] = "PUT"
|
66
|
-
@params[Mongrel::Const::REQUEST_URI] = "/"
|
67
|
-
junk1,path_info,junk2 = @classifier.resolve(@params[Mongrel::Const::REQUEST_URI])
|
68
|
-
|
69
|
-
@params[Mongrel::Const::PATH_INFO] = path_info
|
70
|
-
@request = Mongrel::HttpRequest.new(@params,@socket,nil)
|
71
|
-
|
72
|
-
@handler.process(@request,@response)
|
73
|
-
@response.finished
|
74
|
-
|
75
|
-
@response.status.should == 403
|
76
|
-
@socket.string.should =~ /Only HEAD and GET requests are honored./m
|
77
|
-
end
|
78
|
-
|
79
|
-
it "should format a ruby file and return it as a content-type text/html" do
|
80
|
-
@params[Mongrel::Const::REQUEST_URI] = "/spec/" + File.basename(__FILE__)
|
81
|
-
junk1,path_info,junk2 = @classifier.resolve(@params[Mongrel::Const::REQUEST_URI])
|
82
|
-
|
83
|
-
@params[Mongrel::Const::PATH_INFO] = path_info
|
84
|
-
@request = Mongrel::HttpRequest.new(@params,@socket,nil)
|
85
|
-
@handler.process(@request,@response)
|
86
|
-
@response.finished
|
87
|
-
@response.status.should == 200
|
88
|
-
@socket.string.should =~ /Content-Type: text\/html/m
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
it "should parse the highlighting cgi parameter and return non-highlighted text if highlighting=off" do
|
93
|
-
@params[Mongrel::Const::REQUEST_URI] = "/spec/" + File.basename(__FILE__)
|
94
|
-
@params['QUERY_STRING'] = "highlighting=off"
|
95
|
-
junk1,path_info,junk2 = @classifier.resolve(@params[Mongrel::Const::REQUEST_URI])
|
96
|
-
|
97
|
-
@params[Mongrel::Const::PATH_INFO] = path_info
|
98
|
-
@request = Mongrel::HttpRequest.new(@params,@socket,nil)
|
99
|
-
@handler.process(@request,@response)
|
100
|
-
@response.finished
|
101
|
-
@response.status.should == 200
|
102
|
-
@socket.string.should =~ /Content-Type: text\/plain/m
|
103
|
-
end
|
104
|
-
|
105
|
-
it "should return icons appropriately for unknown mime_type" do
|
106
|
-
@handler.icon_for(MIME::Types.of("stuff.svg").first).should == "page_white.png"
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should test if templates need to be reloaded" do
|
110
|
-
@handler.reload_template_changes?.should == false
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should return 403 if we access something that exists but is not a readable file" do
|
114
|
-
File.open("deleteme.html", "w") { |f| f.write('delete me') }
|
115
|
-
File.chmod(0111, "deleteme.html")
|
116
|
-
@params[Mongrel::Const::REQUEST_URI] = "/deleteme.html"
|
117
|
-
junk1,path_info,junk2 = @classifier.resolve(@params[Mongrel::Const::REQUEST_URI])
|
118
|
-
|
119
|
-
@params[Mongrel::Const::PATH_INFO] = path_info
|
120
|
-
@request = Mongrel::HttpRequest.new(@params,@socket,nil)
|
121
|
-
|
122
|
-
@handler.process(@request,@response)
|
123
|
-
@response.finished
|
124
|
-
File.unlink("deleteme.html")
|
125
|
-
|
126
|
-
@response.status.should == 403
|
127
|
-
end
|
128
|
-
end
|
data/spec/error_handler_spec.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
|
2
|
-
|
3
|
-
describe Heel::ErrorHandler do
|
4
|
-
before(:each) do
|
5
|
-
@handler = Heel::DirHandler.new
|
6
|
-
@classifier = Mongrel::URIClassifier.new
|
7
|
-
@classifier.register("/",1)
|
8
|
-
@socket = StringIO.new
|
9
|
-
@params = Mongrel::HttpParams.new
|
10
|
-
@params.http_body = ""
|
11
|
-
@params[Mongrel::Const::REQUEST_METHOD] = Mongrel::Const::GET
|
12
|
-
@response = Mongrel::HttpResponse.new(@socket)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should return the error page" do
|
16
|
-
@params[Mongrel::Const::REQUEST_URI] = "/does-not-exist"
|
17
|
-
junk1,path_info,junk2 = @classifier.resolve(@params[Mongrel::Const::REQUEST_URI])
|
18
|
-
|
19
|
-
@params[Mongrel::Const::PATH_INFO] = path_info
|
20
|
-
@request = Mongrel::HttpRequest.new(@params,@socket,nil)
|
21
|
-
|
22
|
-
@handler.process(@request,@response)
|
23
|
-
@response.finished
|
24
|
-
|
25
|
-
@response.status.should == 404
|
26
|
-
@socket.string.should =~ /Not Found/m
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|