heel 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,52 @@
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
4
+ #++
5
+
6
+ require 'tasks/config'
7
+
8
+ #-------------------------------------------------------------------------------
9
+ # Distribution and Packaging
10
+ #-------------------------------------------------------------------------------
11
+ if pkg_config = Configuration.for_if_exist?("packaging") then
12
+
13
+ require 'gemspec'
14
+ require 'rake/gempackagetask'
15
+ require 'rake/contrib/sshpublisher'
16
+
17
+ namespace :dist do
18
+
19
+ Rake::GemPackageTask.new(Heel::GEM_SPEC) do |pkg|
20
+ pkg.need_tar = pkg_config.formats.tgz
21
+ pkg.need_zip = pkg_config.formats.zip
22
+ end
23
+
24
+ desc "Install as a gem"
25
+ task :install => [:clobber, :package] do
26
+ sh "sudo gem install -y pkg/#{Heel::GEM_SPEC.full_name}.gem"
27
+ end
28
+
29
+ desc "Uninstall gem"
30
+ task :uninstall do
31
+ sh "sudo gem uninstall -i #{Heel::GEM_SPEC.name} -x"
32
+ end
33
+
34
+ desc "dump gemspec"
35
+ task :gemspec do
36
+ puts Heel::GEM_SPEC.to_ruby
37
+ end
38
+
39
+ desc "reinstall gem"
40
+ task :reinstall => [:uninstall, :repackage, :install]
41
+
42
+ desc "distribute copiously"
43
+ task :copious => [:package] do
44
+ Rake::SshFilePublisher.new('jeremy@copiousfreetime.org',
45
+ '/var/www/vhosts/www.copiousfreetime.org/htdocs/gems/gems',
46
+ 'pkg',"#{Heel::GEM_SPEC.full_name}.gem").upload
47
+ sh "ssh jeremy@copiousfreetime.org rake -f /var/www/vhosts/www.copiousfreetime.org/htdocs/gems/Rakefile"
48
+ end
49
+
50
+
51
+ end
52
+ end
@@ -0,0 +1,35 @@
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
4
+ #++
5
+
6
+ require 'tasks/config'
7
+
8
+ #-----------------------------------------------------------------------
9
+ # Documentation
10
+ #-----------------------------------------------------------------------
11
+
12
+ if rdoc_config = Configuration.for_if_exist?('rdoc') then
13
+
14
+ namespace :doc do
15
+
16
+ require 'rake/rdoctask'
17
+
18
+ # generating documentation locally
19
+ Rake::RDocTask.new do |rdoc|
20
+ rdoc.rdoc_dir = rdoc_config.output_dir
21
+ rdoc.options = rdoc_config.options
22
+ rdoc.rdoc_files = rdoc_config.files
23
+ rdoc.title = rdoc_config.title
24
+ rdoc.main = rdoc_config.main
25
+ end
26
+
27
+ if rubyforge_config = Configuration.for_if_exist?('rubyforge') then
28
+ desc "Deploy the RDoc documentation to #{rubyforge_config.rdoc_location}"
29
+ task :deploy => :rerdoc do
30
+ sh "rsync -zav --delete #{rdoc_config.output_dir}/ #{rubyforge_config.rdoc_location}"
31
+ end
32
+ end
33
+
34
+ end
35
+ end
data/tasks/rspec.rb ADDED
@@ -0,0 +1,33 @@
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
4
+ #++
5
+
6
+ require 'tasks/config'
7
+
8
+ #-------------------------------------------------------------------------------
9
+ # configuration for running rspec. This shows up as the test:default task
10
+ #-------------------------------------------------------------------------------
11
+
12
+ if spec_config = Configuration.for_if_exist?('test') then
13
+
14
+ namespace :test do
15
+
16
+ task :default => :spec
17
+
18
+ require 'spec/rake/spectask'
19
+ Spec::Rake::SpecTask.new do |r|
20
+ r.rcov = spec_config.ruby_opts
21
+ r.libs = [ Heel::Configuration.lib_path,
22
+ Heel::Configuration.root_dir ]
23
+ r.spec_files = spec_config.files
24
+ r.spec_opts = spec_config.options
25
+
26
+ if rcov_config = Configuration.for_if_exist?('rcov') then
27
+ r.rcov = true
28
+ r.rcov_dir = rcov_config.output_dir
29
+ r.rcov_opts = rcov_config.rcov_opts
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
4
+ #++
5
+
6
+ require 'tasks/config'
7
+
8
+ #-----------------------------------------------------------------------
9
+ # Rubyforge additions to the task library
10
+ #-----------------------------------------------------------------------
11
+ if rf_conf = Configuration.for_if_exist?('rubyforge') then
12
+ require 'rubyforge'
13
+
14
+ proj_conf = Configuration.for('project')
15
+
16
+ namespace :dist do
17
+ desc "Release files to rubyforge"
18
+ task :rubyforge => [:clean, :package] do
19
+
20
+ rubyforge = ::RubyForge.new
21
+
22
+ # make sure this release doesn't already exist
23
+ releases = rubyforge.autoconfig['release_ids']
24
+ if releases.has_key?(proj_conf.name) and releases[proj_conf.name][Heel::VERSION] then
25
+ abort("Release #{Heel::VERSION} already exists! Unable to release.")
26
+ end
27
+
28
+ config = rubyforge.userconfig
29
+ config["release_notes"] = proj_conf.description
30
+ config["release_changes"] = Utils.release_notes_from(proj_conf.history)[Heel::VERSION]
31
+ config["Prefomatted"] = true
32
+
33
+ puts "Uploading to rubyforge..."
34
+ files = FileList[File.join("pkg","#{proj_conf.name}-#{Heel::VERSION}*.*")].to_a
35
+ rubyforge.login
36
+ rubyforge.add_release(rf_conf.project, proj_conf.name, Heel::VERSION, *files)
37
+ puts "done."
38
+ end
39
+ end
40
+
41
+ namespace :announce do
42
+ desc "Post news of #{proj_conf.name} to #{rf_conf.project} on rubyforge"
43
+ task :rubyforge do
44
+ subject, title, body, urls = announcement
45
+ rubyforge = RubyForge.new
46
+ rubyforge.login
47
+ rubyforge.post_news(rf_conf.project, subject, "#{title}\n\n#{urls}\n\n#{body}")
48
+ puts "Posted to rubyforge"
49
+ end
50
+
51
+ end
52
+ end
data/tasks/utils.rb ADDED
@@ -0,0 +1,85 @@
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
4
+ #++
5
+
6
+ require 'heel/version'
7
+
8
+ #-------------------------------------------------------------------------------
9
+ # Additions to the Configuration class that are useful
10
+ #-------------------------------------------------------------------------------
11
+ class Configuration
12
+ class << self
13
+ def exist?( name )
14
+ Configuration::Table.has_key?( name )
15
+ end
16
+
17
+ def for_if_exist?( name )
18
+ if self.exist?( name ) then
19
+ self.for( name )
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ #-------------------------------------------------------------------------------
26
+ # some useful utilitiy methods for the tasks
27
+ #-------------------------------------------------------------------------------
28
+ module Utils
29
+ class << self
30
+
31
+ # Try to load the given _library_ using the built-in require, but do not
32
+ # raise a LoadError if unsuccessful. Returns +true+ if the _library_ was
33
+ # successfully loaded; returns +false+ otherwise.
34
+ #
35
+ def try_require( lib )
36
+ require lib
37
+ true
38
+ rescue LoadError
39
+ false
40
+ end
41
+
42
+ # partition an rdoc file into sections, and return the text of the section
43
+ # given.
44
+ def section_of(file, section_name)
45
+ File.read(file).split(/^(?==)/).each do |section|
46
+ lines = section.split("\n")
47
+ return lines[1..-1].join("\n").strip if lines.first =~ /#{section_name}/i
48
+ end
49
+ nil
50
+ end
51
+
52
+ # Get an array of all the changes in the application for a particular
53
+ # release. This is done by looking in the history file and grabbing the
54
+ # information for the most recent release. The history file is assumed to
55
+ # be in RDoc format and version release are 2nd tier sections separated by
56
+ # '== Version X.Y.Z'
57
+ #
58
+ # returns:: A hash of notes keyed by version number
59
+ #
60
+ def release_notes_from(history_file)
61
+ releases = {}
62
+ File.read(history_file).split(/^(?==)/).each do |section|
63
+ lines = section.split("\n")
64
+ md = %r{Version ((\w+\.)+\w+)}.match(lines.first)
65
+ next unless md
66
+ releases[md[1]] = lines[1..-1].join("\n").strip
67
+ end
68
+ return releases
69
+ end
70
+
71
+ # return a hash of useful information for the latest release
72
+ # urls, subject, title, description and latest release notes
73
+ #
74
+ def announcement
75
+ cfg = Configuration.for("project")
76
+ {
77
+ :subject => "#{cfg.name} #{Heel::VERSION} Released",
78
+ :title => "#{cfg.name} version #{Heel::VERSION} has been released.",
79
+ :urls => "#{cfg.homepage}",
80
+ :description => "#{cfg.description.rstrip}",
81
+ :release_notes => Utils.release_notes_from(cfg.history)[Heel::VERSION].rstrip
82
+ }
83
+ end
84
+ end
85
+ end # << self
metadata CHANGED
@@ -1,34 +1,25 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
5
- platform: ""
4
+ version: 1.0.0
5
+ platform: ruby
6
6
  authors:
7
7
  - Jeremy Hinegardner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2007-11-21 00:00:00 -07:00
13
- default_executable: heel
12
+ date: 2008-04-21 00:00:00 -06:00
13
+ default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: mongrel
16
+ name: thin
17
17
  version_requirement:
18
18
  version_requirements: !ruby/object:Gem::Requirement
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.0.1
23
- version:
24
- - !ruby/object:Gem::Dependency
25
- name: launchy
26
- version_requirement:
27
- version_requirements: !ruby/object:Gem::Requirement
28
- requirements:
29
- - - ">="
30
- - !ruby/object:Gem::Version
31
- version: 0.3.0
22
+ version: 0.7.0
32
23
  version:
33
24
  - !ruby/object:Gem::Dependency
34
25
  name: mime-types
@@ -40,48 +31,60 @@ dependencies:
40
31
  version: "1.15"
41
32
  version:
42
33
  - !ruby/object:Gem::Dependency
43
- name: coderay
34
+ name: launchy
44
35
  version_requirement:
45
36
  version_requirements: !ruby/object:Gem::Requirement
46
37
  requirements:
47
38
  - - ">="
48
39
  - !ruby/object:Gem::Version
49
- version: 0.7.4.215
40
+ version: 0.3.1
50
41
  version:
51
42
  - !ruby/object:Gem::Dependency
52
- name: rake
43
+ name: coderay
53
44
  version_requirement:
54
45
  version_requirements: !ruby/object:Gem::Requirement
55
46
  requirements:
56
47
  - - ">="
57
48
  - !ruby/object:Gem::Version
58
- version: 0.7.3
49
+ version: 0.7.4.215
59
50
  version:
60
- description: Heel is a mongrel based web server to quickly and easily serve up the contents of a directory as webpages. Beyond just serving up webpages heel uses an ERB template and famfamfam icons to create useful index pages. And to make things even easier it launches your browser for you so no cut and paste necessary.
61
- email: jeremy@hinegardner.org
51
+ description: Heel is a small static web server for use when you need a quick web server for a directory. Once the server is running, heel will use {launchy}[http://copiousfreetime.rubyforge.org/launchy/] to open your browser at the URL of your document root. Heel is built using {Rack}[http://rack.rubyforge.org] and {Thin}[http://code.macournoyer.com/thin/] % heel >> Thin web server (v0.8.1 codename Rebel Porpoise) >> Threaded mode OFF >> Maximum connections set to 1024 >> Listening on 0.0.0.0:4331, CTRL+C to stop Launching your browser... Or run it in the background % heel --daemonize Created /Users/jeremy/.heel heel's PID (/Users/jeremy/.heel/heel.pid) and log file (/Users/jeremy/.heel/heel.log) are stored here Launching your browser at http://0.0.0.0:4331/ % heel --kill Sending TERM to process 3304 Done.
52
+ email: jeremy at hinegardner dot org
62
53
  executables:
63
54
  - heel
64
55
  extensions: []
65
56
 
66
57
  extra_rdoc_files:
67
- - CHANGES
68
- - LICENSE
69
58
  - README
70
- files:
71
- - spec/dir_handler_spec.rb
72
- - spec/error_handler_spec.rb
73
- - spec/server_spec.rb
74
- - spec/spec_helper.rb
75
- - CHANGES
59
+ - HISTORY
76
60
  - LICENSE
77
- - README
78
- - lib/heel/dir_handler.rb
79
- - lib/heel/error_handler.rb
80
- - lib/heel/gemspec.rb
61
+ - lib/heel/configuration.rb
62
+ - lib/heel/directory_indexer.rb
63
+ - lib/heel/error_response.rb
64
+ - lib/heel/logger.rb
65
+ - lib/heel/mime_map.rb
66
+ - lib/heel/rackapp.rb
67
+ - lib/heel/request.rb
68
+ - lib/heel/server.rb
69
+ - lib/heel/version.rb
70
+ - lib/heel.rb
71
+ files:
72
+ - bin/heel
73
+ - lib/heel/configuration.rb
74
+ - lib/heel/directory_indexer.rb
75
+ - lib/heel/error_response.rb
76
+ - lib/heel/logger.rb
77
+ - lib/heel/mime_map.rb
78
+ - lib/heel/rackapp.rb
79
+ - lib/heel/request.rb
81
80
  - lib/heel/server.rb
82
- - lib/heel/specification.rb
83
81
  - lib/heel/version.rb
84
82
  - lib/heel.rb
83
+ - spec/configuration_spec.rb
84
+ - spec/directory_indexer_spec.rb
85
+ - spec/rackapp_spec.rb
86
+ - spec/server_spec.rb
87
+ - spec/spec_helper.rb
85
88
  - data/css
86
89
  - data/css/coderay-cycnus.css
87
90
  - data/css/coderay-murphy.css
@@ -106,7 +109,17 @@ files:
106
109
  - data/famfamfam/readme.html
107
110
  - data/famfamfam/readme.txt
108
111
  - data/listing.rhtml
109
- - bin/heel
112
+ - README
113
+ - HISTORY
114
+ - LICENSE
115
+ - tasks/announce.rake
116
+ - tasks/distribution.rake
117
+ - tasks/documentation.rake
118
+ - tasks/config.rb
119
+ - tasks/rspec.rb
120
+ - tasks/rubyforge.rb
121
+ - tasks/utils.rb
122
+ - gemspec.rb
110
123
  has_rdoc: true
111
124
  homepage: http://copiousfreetime.rubyforge.org/heel/
112
125
  post_install_message:
@@ -115,15 +128,13 @@ rdoc_options:
115
128
  - --inline-source
116
129
  - --main
117
130
  - README
118
- - --title
119
- - "'heel -- A mongrel based static file webserver.'"
120
131
  require_paths:
121
132
  - lib
122
133
  required_ruby_version: !ruby/object:Gem::Requirement
123
134
  requirements:
124
135
  - - ">="
125
136
  - !ruby/object:Gem::Version
126
- version: 1.8.5
137
+ version: "0"
127
138
  version:
128
139
  required_rubygems_version: !ruby/object:Gem::Requirement
129
140
  requirements:
@@ -137,9 +148,6 @@ rubyforge_project: copiousfreetime
137
148
  rubygems_version: 0.9.5
138
149
  signing_key:
139
150
  specification_version: 2
140
- summary: A mongrel based static file webserver.
141
- test_files:
142
- - spec/dir_handler_spec.rb
143
- - spec/error_handler_spec.rb
144
- - spec/server_spec.rb
145
- - spec/spec_helper.rb
151
+ summary: Heel is a small static web server for use when you need a quick web server for a directory
152
+ test_files: []
153
+
@@ -1,310 +0,0 @@
1
- require 'heel'
2
- require 'mime/types'
3
- require 'erb'
4
- require 'coderay'
5
- require 'coderay/helpers/file_type'
6
-
7
- module Heel
8
-
9
- # A refactored version of Mongrel::DirHandler using the mime-types
10
- # gem and a prettier directory listing.
11
- class DirHandler < ::Mongrel::HttpHandler
12
- attr_reader :document_root
13
- attr_reader :directory_index_html
14
- attr_reader :icon_url
15
- attr_reader :default_mime_type
16
- attr_reader :highlighting
17
- attr_reader :ignore_globs
18
- attr_reader :reload_template_changes
19
- attr_reader :template
20
- attr_reader :template_mtime
21
- attr_accessor :listener
22
- attr_reader :request_notify
23
-
24
- # if any other mime types are needed, add them directly via the
25
- # mime-types calls.
26
- ADDITIONAL_MIME_TYPES = [
27
- # [ content-type , [ array, of, filename, extentions] ]
28
- ["images/svg+xml", ["svg"]],
29
- ["video/x-flv", ["flv"]],
30
- ["application/x-shockwave-flash", ["swf"]],
31
- ["text/plain", ["rb", "rhtml"]],
32
- ]
33
-
34
- ICONS_BY_MIME_TYPE = {
35
- "text/plain" => "page_white_text.png",
36
- "image" => "picture.png",
37
- "pdf" => "page_white_acrobat.png",
38
- "xml" => "page_white_code.png",
39
- "compress" => "compress.png",
40
- "gzip" => "compress.png",
41
- "zip" => "compress.png",
42
- "application/xhtml+xml" => "xhtml.png",
43
- "application/word" => "page_word.png",
44
- "application/excel" => "page_excel.png",
45
- "application/powerpoint" => "page_white_powerpoint.png",
46
- "text/html" => "html.png",
47
- "application" => "application.png",
48
- "text" => "page_white_text.png",
49
- :directory => "folder.png",
50
- :default => "page_white.png",
51
- }
52
-
53
- def initialize(options = {})
54
- @ignore_globs = options[:ignore_globs] || %w( *~ .htaccess . )
55
- @document_root = options[:document_root] || Dir.pwd
56
- @directory_listing_allowed = options[:directory_listing_allowed] || true
57
- @directory_index_html = options[:directory_index_html] || "index.html"
58
- @using_icons = options[:using_icons] || true
59
- @icon_url = options[:icon_url] || "/heel_icons"
60
- @reload_template_changes = options[:reload_template_changes] || false
61
- @highlighting = options[:highlighting] || false
62
- reload_template
63
-
64
- ADDITIONAL_MIME_TYPES.each do |mt|
65
- if MIME::Types[mt.first].size == 0 then
66
- type = MIME::Type.from_array(mt)
67
- MIME::Types.add(type)
68
- else
69
- type = MIME::Types[mt.first].first
70
- mt[1].each do |ext|
71
- type.extensions << ext unless type.extensions.include?(ext)
72
- end
73
- # have to reindex if new extensions added
74
- MIME::Types.index_extensions(type)
75
- end
76
- end
77
-
78
- @default_mime_type = MIME::Types["application/octet-stream"].first
79
- end
80
-
81
- def directory_listing_allowed?
82
- return !!@directory_listing_allowed
83
- end
84
-
85
- def using_icons?
86
- return !!@using_icons
87
- end
88
-
89
- def icon_for(mime_type)
90
- icon = nil
91
- [:content_type, :sub_type, :media_type].each do |t|
92
- icon = ICONS_BY_MIME_TYPE[mime_type.send(t)]
93
- return icon if icon
94
- end
95
- icon = ICONS_BY_MIME_TYPE[:default]
96
- end
97
-
98
- def reload_template_changes?
99
- return @reload_template_changes
100
- end
101
-
102
- def reload_template
103
- fname = File.join(APP_DATA_DIR,"listing.rhtml")
104
- fstat = File.stat(fname)
105
- @template_mtime ||= fstat.mtime
106
- if @template.nil? or fstat.mtime > @template_mtime then
107
- @template = ::ERB.new(File.read(fname))
108
- end
109
- end
110
-
111
- # determine how to respond to the request, it will either be a
112
- # directory listing, a file return, or an error return.
113
- def how_to_respond(req_path,query_params = {})
114
- return 403 unless req_path.index(document_root) == 0
115
- begin
116
- stat = File.stat(req_path)
117
-
118
- # if it is a directory, we either return the
119
- # directory index file, or a directory listing
120
- if stat.directory? then
121
- dir_index = File.join(req_path,directory_index_html)
122
- if File.exists?(dir_index) then
123
- return dir_index
124
- elsif directory_listing_allowed?
125
- return :directory_listing
126
- end
127
-
128
- # if it is a file and readable, make sure that the
129
- # path is a legal path
130
- elsif stat.file? and stat.readable? then
131
- if should_ignore?(File.basename(req_path)) then
132
- return 403
133
- elsif highlighting and (stat.size > 0) and not %w(false off).include? query_params['highlighting'].to_s.downcase
134
- ft = ::FileType[req_path,true]
135
- return :highlighted_file if ft and ft != :html
136
- end
137
- return req_path
138
- else
139
- log "ERROR: #{req_path} is not a directory or a readable file"
140
- return 403
141
- end
142
-
143
- rescue => error
144
- if error.kind_of?(Errno::ENOENT) then
145
- return 404
146
- end
147
- log "ERROR: Unknown, check out the backtrace"
148
- log error.backtrace.join("\n")
149
- return 500
150
- end
151
- end
152
-
153
- def should_ignore?(fname)
154
- ignore_globs.each do |glob|
155
- return true if File.fnmatch(glob,fname)
156
- end
157
- false
158
- end
159
-
160
- # send a directory listing back to the client
161
- def respond_with_directory_listing(req_path,request,response)
162
- base_uri = ::Mongrel::HttpRequest.unescape(request.params[Mongrel::Const::REQUEST_URI])
163
- entries = []
164
- Dir.entries(req_path).each do |entry|
165
- next if should_ignore?(entry)
166
- next if req_path == document_root and entry == ".."
167
-
168
- stat = File.stat(File.join(req_path,entry))
169
- entry_data = OpenStruct.new
170
-
171
- entry_data.name = entry == ".." ? "Parent Directory" : entry
172
- entry_data.link = entry
173
- entry_data.size = num_to_bytes(stat.size)
174
- entry_data.last_modified = stat.mtime.strftime("%Y-%m-%d %H:%M:%S")
175
-
176
- if stat.directory? then
177
- entry_data.content_type = "Directory"
178
- entry_data.size = "-"
179
- entry_data.name += "/"
180
- if using_icons? then
181
- entry_data.icon_url = File.join(icon_url, ICONS_BY_MIME_TYPE[:directory])
182
- end
183
- else
184
- entry_data.mime_type = MIME::Types.of(entry).first || default_mime_type
185
- entry_data.content_type = entry_data.mime_type.content_type
186
- if using_icons? then
187
- entry_data.icon_url = File.join(icon_url, icon_for(entry_data.mime_type))
188
- end
189
- end
190
- entries << entry_data
191
- end
192
-
193
- entries = entries.sort_by { |e| e.link }
194
- res_bytes = 0
195
- response.start(200) do |head,out|
196
- head['Content-Type'] = 'text/html'
197
- res_bytes = out.write(template.result(binding))
198
- end
199
- return res_bytes
200
- end
201
-
202
-
203
- # send the file back with the appropriate mimetype
204
- def respond_with_send_file(path,method,request,response)
205
- stat = File.stat(path)
206
- header = response.header
207
-
208
- header[::Mongrel::Const::LAST_MODIFIED] = stat.mtime
209
- header[::Mongrel::Const::CONTENT_TYPE] = (MIME::Types.of(path).first || default_mime_type).to_s
210
-
211
- response.status = 200
212
- response.send_status(stat.size)
213
- response.send_header
214
-
215
- if method == ::Mongrel::Const::GET then
216
- response.send_file(path,stat.size < ::Mongrel::Const::CHUNK_SIZE * 2)
217
- end
218
-
219
- return stat.size
220
- end
221
-
222
- #
223
- # send back the file marked up by code ray
224
- def respond_with_highlighted_file(path,request,response)
225
- res_bytes = 0
226
- response.start(200) do |head,out|
227
- head[::Mongrel::Const::CONTENT_TYPE] = 'text/html'
228
- bytes = CodeRay.scan_file(path,:auto).html
229
- res_bytes = out.write(<<-EOM)
230
- <html>
231
- <head>
232
- <title>#{path}</title>
233
- <!-- CodeRay syntax highlighting CSS -->
234
- <link rel="stylesheet" href="/heel_css/coderay-cycnus.css" type="text/css" />
235
- </head>
236
- <body>
237
- <div class="CodeRay">
238
- <pre>
239
- #{CodeRay.scan_file(path,:auto).html({:line_numbers => :inline})}
240
- </pre>
241
- </div>
242
- </body>
243
- </html>
244
- EOM
245
- end
246
- return res_bytes
247
- end
248
-
249
- # process the request, returning either the file, a directory
250
- # listing (if allowed) or an appropriate error
251
- def process(request, response)
252
- method = request.params[Mongrel::Const::REQUEST_METHOD] || Mongrel::Const::GET
253
- if ( method == Mongrel::Const::GET ) or ( method == Mongrel::Const::HEAD ) then
254
-
255
- reload_template if reload_template_changes
256
-
257
- req_path = File.expand_path(File.join(@document_root,
258
- ::Mongrel::HttpRequest.unescape(request.params[Mongrel::Const::PATH_INFO])),
259
- @document_root)
260
- res_type = how_to_respond(req_path,::Mongrel::HttpRequest.query_parse(request.params['QUERY_STRING']))
261
- res_size = 0
262
- case res_type
263
- when :directory_listing
264
- res_size = respond_with_directory_listing(req_path,request,response)
265
- when :highlighted_file
266
- res_size = respond_with_highlighted_file(req_path,request,response)
267
- when String
268
- res_size = respond_with_send_file(res_type,method,request,response)
269
- when Integer
270
- response.status = res_type
271
- end
272
-
273
-
274
- # invalid method
275
- else
276
- response.start(403) { |head,out| out.write("Only HEAD and GET requests are honored.") }
277
- end
278
- log_line = [ request.params[Mongrel::Const::REMOTE_ADDR], "-", "-", "[#{Time.now.strftime("%d/%b/%Y:%H:%M:%S %Z")}]" ]
279
- log_line << "\"#{method}"
280
- log_line << request.params['REQUEST_URI']
281
- log_line << "#{request.params['HTTP_VERSION']}\""
282
- log_line << response.status
283
- log_line << res_size
284
-
285
- log log_line.join(' ')
286
- end
287
-
288
- # essentially this is strfbytes from facets
289
- def num_to_bytes(num,fmt="%.2f")
290
- case
291
- when num < 1024
292
- "#{num} bytes"
293
- when num < 1024**2
294
- "#{fmt % (num.to_f / 1024)} KB"
295
- when num < 1024**3
296
- "#{fmt % (num.to_f / 1024**2)} MB"
297
- when num < 1024**4
298
- "#{fmt % (num.to_f / 1024**3)} GB"
299
- when num < 1024**5
300
- "#{fmt % (num.to_f / 1024**4)} TB"
301
- else
302
- "#{num} bytes"
303
- end
304
- end
305
-
306
- def log(msg)
307
- STDERR.print msg, "\n"
308
- end
309
- end
310
- end